* [PATCH i-g-t 0/4] revamp big joiner test
@ 2024-03-03 17:22 Kunal Joshi
2024-03-03 17:22 ` [PATCH i-g-t 1/4] lib/igt_kms: move bigjoiner_mode_found to lib Kunal Joshi
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Kunal Joshi @ 2024-03-03 17:22 UTC (permalink / raw)
To: igt-dev; +Cc: Kunal Joshi
big joiner outputs are statically assigned to pipe,
assign dynamically also add support for forcing
joiner, support for forcing joiner was introduced with
below kmd patch
drm/i915: Add bigjoiner force enable option to debugfs
Kunal Joshi (4):
lib/igt_kms: move bigjoiner_mode_found to lib
lib/igt_kms: add helpers to enable/disable force joiner
tests/intel/kms_big_joiner: revamp kms_big_joiner
tests/intel-ci/fast-feedback: HAX PATCH DO NOT MERGE
lib/igt_kms.c | 73 ++++
lib/igt_kms.h | 4 +
tests/intel-ci/fast-feedback.testlist | 5 +
tests/intel/kms_big_joiner.c | 504 ++++++++++++++------------
4 files changed, 351 insertions(+), 235 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH i-g-t 1/4] lib/igt_kms: move bigjoiner_mode_found to lib 2024-03-03 17:22 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi @ 2024-03-03 17:22 ` Kunal Joshi 2024-03-03 17:22 ` [PATCH i-g-t 2/4] lib/igt_kms: add helpers to enable/disable force joiner Kunal Joshi ` (4 subsequent siblings) 5 siblings, 0 replies; 14+ messages in thread From: Kunal Joshi @ 2024-03-03 17:22 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi, Karthik B S, Bhanuprakash Modem move bigjoiner_mode_found to lib Cc: Karthik B S <karthik.b.s@intel.com> Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- lib/igt_kms.c | 25 +++++++++++++++++++++++++ lib/igt_kms.h | 2 ++ tests/intel/kms_big_joiner.c | 14 +------------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 1b4d0d761..89956b9d5 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -6142,6 +6142,31 @@ bool igt_bigjoiner_possible(drmModeModeInfo *mode, int max_dotclock) mode->clock > max_dotclock); } +/** + * bigjoiner_mode_found: + * @connector: libdrm connector + * @sort_method: comparator method + * @mode: libdrm mode + * + * Bigjoiner will come in to the picture when the + * resolution > 5K or clock > max-dot-clock. + * + * Returns: True if big joiner found in connector modes + */ +bool bigjoiner_mode_found(int drm_fd, drmModeConnector *connector, + int max_dotclock) +{ + bool found = false; + + igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc); + found = igt_bigjoiner_possible(&connector->modes[0], max_dotclock); + if (!found) { + igt_sort_connector_modes(connector, sort_drm_modes_by_clk_dsc); + found = igt_bigjoiner_possible(&connector->modes[0], max_dotclock); + } + return found; +} + /** * igt_check_bigjoiner_support: * @display: a pointer to an #igt_display_t structure diff --git a/lib/igt_kms.h b/lib/igt_kms.h index b3882808b..bab8487d3 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -1212,6 +1212,8 @@ bool igt_max_bpc_constraint(igt_display_t *display, enum pipe pipe, igt_output_t *output, int bpc); int igt_get_max_dotclock(int fd); bool igt_bigjoiner_possible(drmModeModeInfo *mode, int max_dotclock); +bool bigjoiner_mode_found(int drm_fd, drmModeConnector *connector, + int max_dotclock); bool igt_check_bigjoiner_support(igt_display_t *display); bool igt_parse_mode_string(const char *mode_string, drmModeModeInfo *mode); bool intel_pipe_output_combo_valid(igt_display_t *display); diff --git a/tests/intel/kms_big_joiner.c b/tests/intel/kms_big_joiner.c index aba2adfbe..28678b958 100644 --- a/tests/intel/kms_big_joiner.c +++ b/tests/intel/kms_big_joiner.c @@ -199,16 +199,6 @@ static void test_dual_display(data_t *data) igt_display_commit2(display, COMMIT_ATOMIC); } -static bool bigjoiner_mode_found(drmModeConnector *connector, - int (*sort_method)(const void *, const void*), - drmModeModeInfo *mode) -{ - igt_sort_connector_modes(connector, sort_method); - *mode = connector->modes[0]; - - return igt_bigjoiner_possible(mode, max_dotclock); -} - igt_main { data_t data; @@ -235,9 +225,7 @@ igt_main * Bigjoiner will come in to the picture when the * resolution > 5K or clock > max-dot-clock. */ - found = (bigjoiner_mode_found(connector, sort_drm_modes_by_res_dsc, &mode) || - bigjoiner_mode_found(connector, sort_drm_modes_by_clk_dsc, &mode)) ? - true : false; + found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock); if (found) { data.output[count].output_id = output->id; -- 2.25.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH i-g-t 2/4] lib/igt_kms: add helpers to enable/disable force joiner 2024-03-03 17:22 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi 2024-03-03 17:22 ` [PATCH i-g-t 1/4] lib/igt_kms: move bigjoiner_mode_found to lib Kunal Joshi @ 2024-03-03 17:22 ` Kunal Joshi 2024-03-05 11:44 ` Modem, Bhanuprakash 2024-03-03 17:22 ` [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner Kunal Joshi ` (3 subsequent siblings) 5 siblings, 1 reply; 14+ messages in thread From: Kunal Joshi @ 2024-03-03 17:22 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi, Karthik B S, Bhanuprakash Modem add helped to enable/disable force joiner and for checking current state enabled/disabled Cc: Karthik B S <karthik.b.s@intel.com> Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- lib/igt_kms.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/igt_kms.h | 2 ++ 2 files changed, 50 insertions(+) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 89956b9d5..e6952f56a 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -6242,6 +6242,54 @@ bool igt_check_bigjoiner_support(igt_display_t *display) return true; } +/** + * Checks if the force big joiner is enabled for a specific connector. + * + * @param drmfd The file descriptor of the DRM device. + * @param connector_name The name of the connector. + * Returns: + * 1 if the force big joiner is enabled, 0 if disabled, and -1 on error. + */ +int igt_check_force_bigjoiner_status(int drmfd, char *connector_name) +{ + char buf[512]; + int debugfs_fd, ret; + + debugfs_fd = igt_debugfs_connector_dir(drmfd, connector_name, O_RDONLY); + ret = igt_debugfs_simple_read(debugfs_fd, "i915_bigjoiner_force_enable", + buf, sizeof(buf)); + if (ret < 0) { + igt_info("Could not read debugfs %s\n", + strerror(-ret)); + return -1; + } + if (strstr(buf, "Bigjoiner enable: 1")) + return 1; + else if (strstr(buf, "Bigjoiner enable: 0")) + return 0; + else + return -1; +} + +/** + * Forces the enable/disable state of big joiner for a specific connector. + * + * @param drmfd The file descriptor of the DRM device. + * @param connector_name The name of the connector. + * @param enable The desired state of big joiner (true for enable, false for disable). + * Returns: + * >=0 on success, otherwise an error code. + */ +int igt_force_bigjoiner_enable(int drmfd, char *connector_name, bool enable) +{ + int debugfs_fd, ret; + + debugfs_fd = igt_debugfs_connector_dir(drmfd, connector_name, O_DIRECTORY); + ret = igt_sysfs_write(debugfs_fd, "i915_bigjoiner_force_enable", enable ? "1" : "0", 1); + close(debugfs_fd); + return ret; +} + /** * igt_parse_mode_string: * @mode_string: modeline string diff --git a/lib/igt_kms.h b/lib/igt_kms.h index bab8487d3..b28022db4 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -1215,6 +1215,8 @@ bool igt_bigjoiner_possible(drmModeModeInfo *mode, int max_dotclock); bool bigjoiner_mode_found(int drm_fd, drmModeConnector *connector, int max_dotclock); bool igt_check_bigjoiner_support(igt_display_t *display); +int igt_check_force_bigjoiner_status(int drmfd, char *connector_name); +int igt_force_bigjoiner_enable(int drmfd, char *connector_name, bool enable); bool igt_parse_mode_string(const char *mode_string, drmModeModeInfo *mode); bool intel_pipe_output_combo_valid(igt_display_t *display); bool igt_check_output_is_dp_mst(igt_output_t *output); -- 2.25.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH i-g-t 2/4] lib/igt_kms: add helpers to enable/disable force joiner 2024-03-03 17:22 ` [PATCH i-g-t 2/4] lib/igt_kms: add helpers to enable/disable force joiner Kunal Joshi @ 2024-03-05 11:44 ` Modem, Bhanuprakash 2024-03-05 12:50 ` Joshi, Kunal1 0 siblings, 1 reply; 14+ messages in thread From: Modem, Bhanuprakash @ 2024-03-05 11:44 UTC (permalink / raw) To: Kunal Joshi, igt-dev; +Cc: Karthik B S Hi Kunal, On 03-03-2024 10:52 pm, Kunal Joshi wrote: > add helped to enable/disable force joiner and for > checking current state enabled/disabled > > Cc: Karthik B S <karthik.b.s@intel.com> > Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> > Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> > --- > lib/igt_kms.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ > lib/igt_kms.h | 2 ++ > 2 files changed, 50 insertions(+) > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c > index 89956b9d5..e6952f56a 100644 > --- a/lib/igt_kms.c > +++ b/lib/igt_kms.c > @@ -6242,6 +6242,54 @@ bool igt_check_bigjoiner_support(igt_display_t *display) > return true; > } > > +/** > + * Checks if the force big joiner is enabled for a specific connector. > + * > + * @param drmfd The file descriptor of the DRM device. > + * @param connector_name The name of the connector. > + * Returns: > + * 1 if the force big joiner is enabled, 0 if disabled, and -1 on error. > + */ > +int igt_check_force_bigjoiner_status(int drmfd, char *connector_name) > +{ > + char buf[512]; > + int debugfs_fd, ret; > + > + debugfs_fd = igt_debugfs_connector_dir(drmfd, connector_name, O_RDONLY); We must guard "debugfs_fd" with igt_assert() or igt_require(). > + ret = igt_debugfs_simple_read(debugfs_fd, "i915_bigjoiner_force_enable", > + buf, sizeof(buf)); > + if (ret < 0) { > + igt_info("Could not read debugfs %s\n", > + strerror(-ret)); > + return -1; > + } > + if (strstr(buf, "Bigjoiner enable: 1")) > + return 1; > + else if (strstr(buf, "Bigjoiner enable: 0")) > + return 0; > + else > + return -1; > +} > + > +/** > + * Forces the enable/disable state of big joiner for a specific connector. > + * > + * @param drmfd The file descriptor of the DRM device. > + * @param connector_name The name of the connector. > + * @param enable The desired state of big joiner (true for enable, false for disable). > + * Returns: > + * >=0 on success, otherwise an error code. IMHO, let's make return value as bool. Return True if write success else False. > + */ > +int igt_force_bigjoiner_enable(int drmfd, char *connector_name, bool enable) > +{ > + int debugfs_fd, ret; > + > + debugfs_fd = igt_debugfs_connector_dir(drmfd, connector_name, O_DIRECTORY); ----------------------------------------------------------------------^ This could be O_RDWR or O_WRONLY? - Bhanu > + ret = igt_sysfs_write(debugfs_fd, "i915_bigjoiner_force_enable", enable ? "1" : "0", 1); > + close(debugfs_fd); > + return ret; > +} > + > /** > * igt_parse_mode_string: > * @mode_string: modeline string > diff --git a/lib/igt_kms.h b/lib/igt_kms.h > index bab8487d3..b28022db4 100644 > --- a/lib/igt_kms.h > +++ b/lib/igt_kms.h > @@ -1215,6 +1215,8 @@ bool igt_bigjoiner_possible(drmModeModeInfo *mode, int max_dotclock); > bool bigjoiner_mode_found(int drm_fd, drmModeConnector *connector, > int max_dotclock); > bool igt_check_bigjoiner_support(igt_display_t *display); > +int igt_check_force_bigjoiner_status(int drmfd, char *connector_name); > +int igt_force_bigjoiner_enable(int drmfd, char *connector_name, bool enable); > bool igt_parse_mode_string(const char *mode_string, drmModeModeInfo *mode); > bool intel_pipe_output_combo_valid(igt_display_t *display); > bool igt_check_output_is_dp_mst(igt_output_t *output); ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH i-g-t 2/4] lib/igt_kms: add helpers to enable/disable force joiner 2024-03-05 11:44 ` Modem, Bhanuprakash @ 2024-03-05 12:50 ` Joshi, Kunal1 0 siblings, 0 replies; 14+ messages in thread From: Joshi, Kunal1 @ 2024-03-05 12:50 UTC (permalink / raw) To: Modem, Bhanuprakash, igt-dev; +Cc: Karthik B S Hello Bhanu, Thanks for taking a look. On 3/5/2024 5:14 PM, Modem, Bhanuprakash wrote: > Hi Kunal, > > On 03-03-2024 10:52 pm, Kunal Joshi wrote: >> add helped to enable/disable force joiner and for >> checking current state enabled/disabled >> >> Cc: Karthik B S <karthik.b.s@intel.com> >> Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> >> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> >> --- >> lib/igt_kms.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ >> lib/igt_kms.h | 2 ++ >> 2 files changed, 50 insertions(+) >> >> diff --git a/lib/igt_kms.c b/lib/igt_kms.c >> index 89956b9d5..e6952f56a 100644 >> --- a/lib/igt_kms.c >> +++ b/lib/igt_kms.c >> @@ -6242,6 +6242,54 @@ bool igt_check_bigjoiner_support(igt_display_t >> *display) >> return true; >> } >> +/** >> + * Checks if the force big joiner is enabled for a specific connector. >> + * >> + * @param drmfd The file descriptor of the DRM device. >> + * @param connector_name The name of the connector. >> + * Returns: >> + * 1 if the force big joiner is enabled, 0 if disabled, and -1 on >> error. >> + */ >> +int igt_check_force_bigjoiner_status(int drmfd, char *connector_name) >> +{ >> + char buf[512]; >> + int debugfs_fd, ret; >> + >> + debugfs_fd = igt_debugfs_connector_dir(drmfd, connector_name, >> O_RDONLY); > > We must guard "debugfs_fd" with igt_assert() or igt_require(). Will address in next revision. > >> + ret = igt_debugfs_simple_read(debugfs_fd, >> "i915_bigjoiner_force_enable", >> + buf, sizeof(buf)); >> + if (ret < 0) { >> + igt_info("Could not read debugfs %s\n", >> + strerror(-ret)); >> + return -1; >> + } >> + if (strstr(buf, "Bigjoiner enable: 1")) >> + return 1; >> + else if (strstr(buf, "Bigjoiner enable: 0")) >> + return 0; >> + else >> + return -1; >> +} >> + >> +/** >> + * Forces the enable/disable state of big joiner for a specific >> connector. >> + * >> + * @param drmfd The file descriptor of the DRM device. >> + * @param connector_name The name of the connector. >> + * @param enable The desired state of big joiner (true for enable, >> false for disable). >> + * Returns: >> + * >=0 on success, otherwise an error code. > > IMHO, let's make return value as bool. Return True if write success > else False. Yes we can do like that way too, will address in next revision > >> + */ >> +int igt_force_bigjoiner_enable(int drmfd, char *connector_name, bool >> enable) >> +{ >> + int debugfs_fd, ret; >> + >> + debugfs_fd = igt_debugfs_connector_dir(drmfd, connector_name, >> O_DIRECTORY); > ----------------------------------------------------------------------^ > This could be O_RDWR or O_WRONLY? No O_RDWR and O_WRONLY are for files not for directories. > > - Bhanu > >> + ret = igt_sysfs_write(debugfs_fd, "i915_bigjoiner_force_enable", >> enable ? "1" : "0", 1); >> + close(debugfs_fd); >> + return ret; >> +} >> + >> /** >> * igt_parse_mode_string: >> * @mode_string: modeline string >> diff --git a/lib/igt_kms.h b/lib/igt_kms.h >> index bab8487d3..b28022db4 100644 >> --- a/lib/igt_kms.h >> +++ b/lib/igt_kms.h >> @@ -1215,6 +1215,8 @@ bool igt_bigjoiner_possible(drmModeModeInfo >> *mode, int max_dotclock); >> bool bigjoiner_mode_found(int drm_fd, drmModeConnector *connector, >> int max_dotclock); >> bool igt_check_bigjoiner_support(igt_display_t *display); >> +int igt_check_force_bigjoiner_status(int drmfd, char *connector_name); >> +int igt_force_bigjoiner_enable(int drmfd, char *connector_name, bool >> enable); >> bool igt_parse_mode_string(const char *mode_string, drmModeModeInfo >> *mode); >> bool intel_pipe_output_combo_valid(igt_display_t *display); >> bool igt_check_output_is_dp_mst(igt_output_t *output); Thanks and Regards Kunal Joshi ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner 2024-03-03 17:22 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi 2024-03-03 17:22 ` [PATCH i-g-t 1/4] lib/igt_kms: move bigjoiner_mode_found to lib Kunal Joshi 2024-03-03 17:22 ` [PATCH i-g-t 2/4] lib/igt_kms: add helpers to enable/disable force joiner Kunal Joshi @ 2024-03-03 17:22 ` Kunal Joshi 2024-03-05 11:44 ` Modem, Bhanuprakash 2024-03-03 17:22 ` [PATCH i-g-t 4/4] tests/intel-ci/fast-feedback: HAX PATCH DO NOT MERGE Kunal Joshi ` (2 subsequent siblings) 5 siblings, 1 reply; 14+ messages in thread From: Kunal Joshi @ 2024-03-03 17:22 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi, Karthik B S, Bhanuprakash Modem big joiner outputs are statically assigned to pipe, assign dynamically also add support for forcing joiner, support for forcing joiner was introduced with below kmd patch drm/i915: Add bigjoiner force enable option to debugfs Cc: Karthik B S <karthik.b.s@intel.com> Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- tests/intel/kms_big_joiner.c | 494 +++++++++++++++++++---------------- 1 file changed, 270 insertions(+), 224 deletions(-) diff --git a/tests/intel/kms_big_joiner.c b/tests/intel/kms_big_joiner.c index 28678b958..a4f6b8782 100644 --- a/tests/intel/kms_big_joiner.c +++ b/tests/intel/kms_big_joiner.c @@ -1,27 +1,6 @@ +/* SPDX-License-Identifier: MIT */ /* - * Copyright © 2020 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Author: - * Karthik B S <karthik.b.s@intel.com> + * Copyright © 2024 Intel Corporation */ /** @@ -37,22 +16,36 @@ #include "igt.h" /** - * SUBTEST: invalid-modeset - * Description: Verify if the modeset on the adjoining pipe is rejected when - * the pipe is active with a big joiner modeset - * * SUBTEST: basic * Description: Verify the basic modeset on big joiner mode on all pipes * - * SUBTEST: 2x-modeset - * Description: Verify simultaneous modeset on 2 big joiner outputs + * SUBTEST: force-joiner-basic + * Description: Verify the basic modeset on force joiner mode on all pipes + * + * SUBTEST: invalid-modeset + * Description: Verify the invalid modeset on big joiner mode on all pipes + * + * SUBTEST: force-joiner-invalid-modeset + * Description: Verify the invalid modeset on force joiner mode on all pipes */ +IGT_TEST_DESCRIPTION("Test big joiner / force joiner"); -IGT_TEST_DESCRIPTION("Test big joiner"); +#define MAX_OUTPUTS 256 +#define MAX_COMBINATIONS 1000 +#define INVALID_TEST_OUTPUT 2 +typedef struct { + int combination[MAX_OUTPUTS]; +} Combination; -struct bigjoiner_output { - uint32_t output_id; - drmModeModeInfo mode; +enum tests { + BASIC, + INVALID_MODESET, + INVALID, +}; + +enum joiner_type { + BIG_JOINER = 1 << 1, + INVALID_JOINER = -1, }; typedef struct { @@ -60,273 +53,326 @@ typedef struct { igt_display_t display; struct igt_fb fb; int n_pipes; - enum pipe pipe1; - enum pipe pipe2; - struct bigjoiner_output output[2]; + uint64_t big_joiner_outputs[IGT_MAX_PIPES]; + uint64_t non_big_joiner_outputs[IGT_MAX_PIPES]; + uint64_t combined_outputs[IGT_MAX_PIPES]; + int big_joiner_output_count; + int non_big_joiner_output_count; + int combined_output_count; + int output_count; + enum pipe pipe_seq[IGT_MAX_PIPES]; } data_t; static int max_dotclock; -static void test_invalid_modeset(data_t *data) +static bool output_supports_force_joiner(igt_output_t *output) { - igt_output_t *output; - igt_display_t *display = &data->display; - int ret; + return output->config.connector->connector_type == + DRM_MODE_CONNECTOR_DisplayPort || + output->config.connector->connector_type == + DRM_MODE_CONNECTOR_eDP; +} - igt_info("Bigjoiner test on "); - for_each_connected_output(display, output){ - enum pipe p = output->pending_pipe; - drmModeModeInfo *mode; - igt_pipe_t *pipe; - igt_plane_t *plane; +static void generate_combinations(int output_count, int pipe_count, + int pipes_per_output, + Combination combinations[MAX_COMBINATIONS], + uint64_t *num_combinations) +{ + int i, index; + int current_combination[MAX_OUTPUTS]; - if (p == PIPE_NONE) - continue; + for (i = 0; i < output_count; ++i) + current_combination[i] = i * pipes_per_output; - mode = igt_output_get_mode(output); - igt_info("pipe:%s, output:%s, mode:", kmstest_pipe_name(p), igt_output_name(output)); - kmstest_dump_mode(mode); + while (current_combination[0] <= pipe_count - output_count * pipes_per_output) { + for (i = 0; i < output_count; ++i) + combinations[*num_combinations].combination[i] = current_combination[i]; - pipe = &display->pipes[p]; - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); + (*num_combinations)++; - igt_plane_set_fb(plane, &data->fb); - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); - } + index = output_count - 1; + while (index >= 0 && current_combination[index] == pipe_count - (output_count - index) * pipes_per_output) + index--; - igt_assert(!igt_check_bigjoiner_support(display)); + if (index < 0) + break; - /* This commit is expectd to fail as this pipe is being used for big joiner */ - ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | - DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + current_combination[index]++; + for (i = index + 1; i < output_count; ++i) + current_combination[i] = current_combination[i - 1] + pipes_per_output; + } +} - igt_display_reset(&data->display); - igt_display_commit2(display, COMMIT_ATOMIC); +static igt_output_t *get_output_by_id(data_t *data, uint64_t output_id) +{ + igt_output_t *output; - igt_assert_lt(ret, 0); + for_each_connected_output(&data->display, output) { + if (output->id == output_id) + return output; + } + igt_assert("Output not found\n"); + return NULL; } -static void test_basic_modeset(data_t *data) +static void test_invalid_modeset_two_joiner(data_t *data, bool force_joiner, + bool combined) { + int i, j, ret; + igt_output_t *output; + uint64_t *outputs; + igt_plane_t *primary[INVALID_TEST_OUTPUT]; + igt_fb_t fb[INVALID_TEST_OUTPUT]; drmModeModeInfo *mode; - igt_output_t *output, *bigjoiner_output = NULL; - igt_display_t *display = &data->display; - igt_pipe_t *pipe; - igt_plane_t *plane; - - igt_display_reset(display); - for_each_connected_output(display, output) { - if (data->output[0].output_id == output->id) { - bigjoiner_output = output; - break; + outputs = force_joiner ? data->non_big_joiner_outputs : + combined ? data->combined_outputs : data->big_joiner_outputs; + + for (i = 0; i < data->n_pipes-1; i++) { + igt_display_reset(&data->display); + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { + output = get_output_by_id(data, outputs[j]); + igt_assert(output); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); + } + igt_output_set_pipe(output, data->pipe_seq[i + j]); + mode = igt_output_get_mode(output); + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d%s", + kmstest_pipe_name(data->pipe_seq[i + j]), + igt_output_name(output), mode->hdisplay, + mode->vdisplay, mode->vrefresh, + j == INVALID_TEST_OUTPUT - 1 ? "\n" : ", "); + primary[j] = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb[j]); + igt_plane_set_fb(primary[j], &fb[j]); + } + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); + if (force_joiner) { + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { + output = get_output_by_id(data, outputs[j]); + igt_assert(output); + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 0); + } } } - - igt_output_set_pipe(bigjoiner_output, data->pipe1); - - mode = &data->output[0].mode; - igt_output_override_mode(bigjoiner_output, mode); - - pipe = &display->pipes[data->pipe1]; - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane, &data->fb); - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); - - igt_display_commit2(display, COMMIT_ATOMIC); - - igt_output_set_pipe(bigjoiner_output, PIPE_NONE); - igt_plane_set_fb(plane, NULL); - igt_display_commit2(display, COMMIT_ATOMIC); } -static void test_dual_display(data_t *data) +static void tets_big_joiner_on_last_pipe(data_t *data, bool force_joiner) { + int i, len, ret; + uint64_t *outputs; + igt_output_t *output; + igt_plane_t *primary; + igt_fb_t fb; drmModeModeInfo *mode; - igt_output_t *output, *bigjoiner_output[2]; - igt_display_t *display = &data->display; - igt_pipe_t *pipe; - igt_plane_t *plane1, *plane2; - int count = 0; - igt_display_reset(display); + len = force_joiner ? data->non_big_joiner_output_count : data->big_joiner_output_count; + outputs = force_joiner ? data->non_big_joiner_outputs : data->big_joiner_outputs; - for_each_connected_output(display, output) { - if (data->output[count].output_id == output->id) { - bigjoiner_output[count] = output; - count++; + for (i = 0; i < len; i++) { + igt_display_reset(&data->display); + output = get_output_by_id(data, outputs[i]); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); } - - if (count > 1) - break; + igt_output_set_pipe(output, data->pipe_seq[data->n_pipes - 1]); + mode = igt_output_get_mode(output); + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d\n", + kmstest_pipe_name(data->pipe_seq[data->n_pipes - 1]), + igt_output_name(output), mode->hdisplay, + mode->vdisplay, mode->vrefresh); + primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb); + igt_plane_set_fb(primary, &fb); + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); } + if (force_joiner) { + for (i = 0; i < len; i++) { + output = get_output_by_id(data, outputs[i]); + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); + } + } +} - igt_output_set_pipe(bigjoiner_output[0], data->pipe1); - igt_output_set_pipe(bigjoiner_output[1], data->pipe2); - - /* Set up first big joiner output on Pipe A*/ - mode = &data->output[0].mode; - igt_output_override_mode(bigjoiner_output[0], mode); - - pipe = &display->pipes[data->pipe1]; - plane1 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane1, &data->fb); - igt_fb_set_size(&data->fb, plane1, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane1, mode->hdisplay, mode->vdisplay); - - /* Set up second big joiner output on Pipe C*/ - mode = &data->output[1].mode; - igt_output_override_mode(bigjoiner_output[1], mode); - - pipe = &display->pipes[data->pipe2]; - plane2 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane2, &data->fb); - igt_fb_set_size(&data->fb, plane2, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane2, mode->hdisplay, mode->vdisplay); - - igt_display_commit2(display, COMMIT_ATOMIC); +static void test_basic_modeset(data_t *data, int num_outputs, + Combination combinations[MAX_COMBINATIONS], + uint64_t num_combinations, bool force_joiner) +{ + int i, j, ret; + igt_display_t *display = &data->display; + igt_output_t *output[num_outputs]; + igt_plane_t *primary[num_outputs]; + igt_fb_t fb[num_outputs]; + drmModeModeInfo *mode; - /* Clean up */ - igt_output_set_pipe(bigjoiner_output[0], PIPE_NONE); - igt_output_set_pipe(bigjoiner_output[1], PIPE_NONE); - igt_plane_set_fb(plane1, NULL); - igt_plane_set_fb(plane2, NULL); - igt_display_commit2(display, COMMIT_ATOMIC); + for (i = 0; i < num_combinations; i++) { + igt_display_reset(display); + for (j = 0; j < num_outputs; j++) { + output[j] = get_output_by_id(data, + force_joiner ? + data->non_big_joiner_outputs[j] : + data->big_joiner_outputs[j]); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, + output[j]->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, + output[j]->name) == 1); + } + igt_info("Assigning pipe %d to %s%s", + data->pipe_seq[combinations[i].combination[j]], + output[j]->name, j == num_outputs - 1 ? "\n" : ", "); + igt_output_set_pipe(output[j], data->pipe_seq[combinations[i].combination[j]]); + primary[j] = igt_output_get_plane_type(output[j], DRM_PLANE_TYPE_PRIMARY); + mode = igt_output_get_mode(output[j]); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb[j]); + igt_plane_set_fb(primary[j], &fb[j]); + } + ret = igt_display_try_commit2(display, COMMIT_ATOMIC); + if (ret == 0) + igt_display_commit2(display, COMMIT_ATOMIC); + else + igt_assert_f(ret == 0, "Commit failed\n"); + + if (force_joiner) { + for (j = 0; j < num_outputs; j++) { + igt_force_bigjoiner_enable(data->drm_fd, output[j]->name, false); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output[j]->name) == 0); + } + } + } } igt_main { + int i, j; data_t data; igt_output_t *output; - drmModeModeInfo mode; - int valid_output = 0, i, count = 0, j = 0; - uint16_t width = 0, height = 0; - enum pipe pipe_seq[IGT_MAX_PIPES]; + i = j = 0; igt_fixture { data.drm_fd = drm_open_driver_master(DRIVER_INTEL | DRIVER_XE); kmstest_set_vt_graphics_mode(); - igt_display_require(&data.display, data.drm_fd); igt_require(data.display.is_atomic); - max_dotclock = igt_get_max_dotclock(data.drm_fd); + data.big_joiner_output_count = 0; + data.non_big_joiner_output_count = 0; + data.combined_output_count = 0; + data.output_count = 0; for_each_connected_output(&data.display, output) { bool found = false; drmModeConnector *connector = output->config.connector; - - /* - * Bigjoiner will come in to the picture when the - * resolution > 5K or clock > max-dot-clock. - */ found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock); - if (found) { - data.output[count].output_id = output->id; - memcpy(&data.output[count].mode, &mode, sizeof(drmModeModeInfo)); - count++; - - width = max(width, mode.hdisplay); - height = max(height, mode.vdisplay); + data.big_joiner_outputs[data.big_joiner_output_count++] = output->id; + igt_output_override_mode(output, &connector->modes[0]); + } else { + if (output_supports_force_joiner(output)) { + data.non_big_joiner_outputs[data.non_big_joiner_output_count++] = output->id; + igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc); + igt_output_override_mode(output, &connector->modes[0]); + } } - valid_output++; + data.output_count++; } data.n_pipes = 0; for_each_pipe(&data.display, i) { data.n_pipes++; - pipe_seq[j] = i; + data.pipe_seq[j] = i; j++; } - - igt_require_f(count > 0, "No output with 5k+ mode (or) clock > max-dot-clock found\n"); - - igt_create_pattern_fb(data.drm_fd, width, height, DRM_FORMAT_XRGB8888, - DRM_FORMAT_MOD_LINEAR, &data.fb); } igt_describe("Verify the basic modeset on big joiner mode on all pipes"); igt_subtest_with_dynamic("basic") { - for (i = 0; i < data.n_pipes - 1; i++) { - data.pipe1 = pipe_seq[i]; - igt_dynamic_f("pipe-%s", kmstest_pipe_name(pipe_seq[i])) - test_basic_modeset(&data); + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + for (i = 0; i < data.big_joiner_output_count; i++) { + uint64_t num_combinations = 0; + Combination combinations[MAX_COMBINATIONS]; + + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", + i+1, data.n_pipes, num_combinations); + + if (num_combinations > 0) + igt_dynamic_f("%dx-big-joiner", i+1) + test_basic_modeset(&data, i+1, combinations, num_combinations, false); + else + break; } } - igt_describe("Verify if the modeset on the adjoining pipe is rejected " - "when the pipe is active with a big joiner modeset"); - igt_subtest_with_dynamic("invalid-modeset") { - data.pipe1 = pipe_seq[j - 1]; - - igt_display_reset(&data.display); - for_each_connected_output(&data.display, output) { - if (data.output[0].output_id != output->id) - continue; - - mode = data.output[0].mode; - igt_output_set_pipe(output, data.pipe1); - igt_output_override_mode(output, &mode); - - igt_dynamic_f("pipe-%s-%s", - kmstest_pipe_name(data.pipe1), - igt_output_name(output)) - test_invalid_modeset(&data); + igt_describe("Verify the basic modeset on big joiner mode on all pipes"); + igt_subtest_with_dynamic("force-joiner-basic") { + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >= 11, + "force joiner not supported on this platform\n"); + igt_require_f(data.non_big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + for (i = 0; i < data.non_big_joiner_output_count; i++) { + uint64_t num_combinations = 0; + Combination combinations[MAX_COMBINATIONS]; + + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", + i+1, data.n_pipes, num_combinations); + + if (num_combinations > 0) + igt_dynamic_f("%dx-joiner", i+1) + test_basic_modeset(&data, i+1, combinations, num_combinations, true); + else + break; } + } - if(valid_output > 1) { - for (i = 0; i < data.n_pipes - 1; i++) { - igt_output_t *first_output = NULL, *second_output = NULL; - - data.pipe1 = pipe_seq[i]; - data.pipe2 = pipe_seq[i + 1]; - - igt_display_reset(&data.display); - for_each_connected_output(&data.display, output) { - if (data.output[0].output_id == output->id) { - first_output = output; - mode = data.output[0].mode; + igt_subtest_with_dynamic("invalid-modeset") { + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); - igt_output_set_pipe(output, data.pipe1); - igt_output_override_mode(output, &mode); - } else if (second_output == NULL) { - second_output = output; - igt_output_set_pipe(output, data.pipe2); + if (data.big_joiner_output_count >= 1) + igt_dynamic_f("big_joiner_on_last_pipe") + tets_big_joiner_on_last_pipe(&data, false); - break; - } - } + if (data.big_joiner_output_count > 1) + igt_dynamic_f("invalid_combinations") + test_invalid_modeset_two_joiner(&data, false, false); - igt_dynamic_f("pipe-%s-%s-pipe-%s-%s", - kmstest_pipe_name(data.pipe1), - igt_output_name(first_output), - kmstest_pipe_name(data.pipe2), - igt_output_name(second_output)) - test_invalid_modeset(&data); - } + if (data.big_joiner_output_count == 1 && data.non_big_joiner_output_count > 0) { + data.combined_outputs[data.combined_output_count++] = data.big_joiner_outputs[0]; + data.combined_outputs[data.combined_output_count++] = data.non_big_joiner_outputs[0]; + test_invalid_modeset_two_joiner(&data, false, true); } } - igt_describe("Verify simultaneous modeset on 2 big joiner outputs"); - igt_subtest_with_dynamic("2x-modeset") { - igt_require_f(count > 1, "2 outputs with big joiner modes are required\n"); - igt_require_f(data.n_pipes > 3, "Minumum of 4 pipes are required\n"); - for (i = 0; (i + 2) < data.n_pipes - 1; i++) { - data.pipe1 = pipe_seq[i]; - data.pipe2 = pipe_seq[i + 2]; - igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe_seq[i]), kmstest_pipe_name(pipe_seq[i + 2])) - test_dual_display(&data); - } + igt_subtest_with_dynamic("force-joiner-invalid-modeset") { + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >= 11, + "force joiner not supported on this platform\n"); + igt_require_f(data.non_big_joiner_output_count > 0, "Non big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + if (data.non_big_joiner_output_count >= 1) + igt_dynamic_f("big_joiner_on_last_pipe") + tets_big_joiner_on_last_pipe(&data, true); + + if (data.non_big_joiner_output_count > 1) + igt_dynamic_f("invalid_combinations") + test_invalid_modeset_two_joiner(&data, true, false); } igt_fixture { - igt_remove_fb(data.drm_fd, &data.fb); igt_display_fini(&data.display); drm_close_driver(data.drm_fd); } -- 2.25.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner 2024-03-03 17:22 ` [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner Kunal Joshi @ 2024-03-05 11:44 ` Modem, Bhanuprakash 2024-03-05 13:14 ` Joshi, Kunal1 2024-03-05 17:34 ` Kamil Konieczny 0 siblings, 2 replies; 14+ messages in thread From: Modem, Bhanuprakash @ 2024-03-05 11:44 UTC (permalink / raw) To: Kunal Joshi, igt-dev, Kamil Konieczny; +Cc: Karthik B S Hi Kunal, On 03-03-2024 10:52 pm, Kunal Joshi wrote: > big joiner outputs are statically assigned to pipe, > assign dynamically also add support for forcing > joiner, support for forcing joiner was introduced with > below kmd patch > > drm/i915: Add bigjoiner force enable option to debugfs > > Cc: Karthik B S <karthik.b.s@intel.com> > Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> > Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> > --- > tests/intel/kms_big_joiner.c | 494 +++++++++++++++++++---------------- > 1 file changed, 270 insertions(+), 224 deletions(-) > > diff --git a/tests/intel/kms_big_joiner.c b/tests/intel/kms_big_joiner.c > index 28678b958..a4f6b8782 100644 > --- a/tests/intel/kms_big_joiner.c > +++ b/tests/intel/kms_big_joiner.c > @@ -1,27 +1,6 @@ > +/* SPDX-License-Identifier: MIT */ > /* > - * Copyright © 2020 Intel Corporation > - * > - * Permission is hereby granted, free of charge, to any person obtaining a > - * copy of this software and associated documentation files (the "Software"), > - * to deal in the Software without restriction, including without limitation > - * the rights to use, copy, modify, merge, publish, distribute, sublicense, > - * and/or sell copies of the Software, and to permit persons to whom the > - * Software is furnished to do so, subject to the following conditions: > - * > - * The above copyright notice and this permission notice (including the next > - * paragraph) shall be included in all copies or substantial portions of the > - * Software. > - * > - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS > - * IN THE SOFTWARE. > - * > - * Author: > - * Karthik B S <karthik.b.s@intel.com> > + * Copyright © 2024 Intel Corporation I think, we don't need to touch the license part. @kmail JFYI > */ > > /** > @@ -37,22 +16,36 @@ > #include "igt.h" > > /** > - * SUBTEST: invalid-modeset > - * Description: Verify if the modeset on the adjoining pipe is rejected when > - * the pipe is active with a big joiner modeset > - * > * SUBTEST: basic > * Description: Verify the basic modeset on big joiner mode on all pipes > * > - * SUBTEST: 2x-modeset > - * Description: Verify simultaneous modeset on 2 big joiner outputs > + * SUBTEST: force-joiner-basic > + * Description: Verify the basic modeset on force joiner mode on all pipes > + * > + * SUBTEST: invalid-modeset > + * Description: Verify the invalid modeset on big joiner mode on all pipes > + * > + * SUBTEST: force-joiner-invalid-modeset > + * Description: Verify the invalid modeset on force joiner mode on all pipes > */ > +IGT_TEST_DESCRIPTION("Test big joiner / force joiner"); > > -IGT_TEST_DESCRIPTION("Test big joiner"); > +#define MAX_OUTPUTS 256 > +#define MAX_COMBINATIONS 1000 > +#define INVALID_TEST_OUTPUT 2 > +typedef struct { > + int combination[MAX_OUTPUTS]; > +} Combination; > > -struct bigjoiner_output { > - uint32_t output_id; > - drmModeModeInfo mode; > +enum tests { > + BASIC, > + INVALID_MODESET, > + INVALID, > +}; > + > +enum joiner_type { > + BIG_JOINER = 1 << 1, > + INVALID_JOINER = -1, > }; > > typedef struct { > @@ -60,273 +53,326 @@ typedef struct { > igt_display_t display; > struct igt_fb fb; > int n_pipes; > - enum pipe pipe1; > - enum pipe pipe2; > - struct bigjoiner_output output[2]; > + uint64_t big_joiner_outputs[IGT_MAX_PIPES]; > + uint64_t non_big_joiner_outputs[IGT_MAX_PIPES]; > + uint64_t combined_outputs[IGT_MAX_PIPES]; > + int big_joiner_output_count; > + int non_big_joiner_output_count; > + int combined_output_count; > + int output_count; > + enum pipe pipe_seq[IGT_MAX_PIPES]; > } data_t; > > static int max_dotclock; > > -static void test_invalid_modeset(data_t *data) > +static bool output_supports_force_joiner(igt_output_t *output) > { > - igt_output_t *output; > - igt_display_t *display = &data->display; > - int ret; > + return output->config.connector->connector_type == > + DRM_MODE_CONNECTOR_DisplayPort || > + output->config.connector->connector_type == > + DRM_MODE_CONNECTOR_eDP; > +} I think, this is not a source of truth. Perhaps, you can just check if debugfs is present or not. > > - igt_info("Bigjoiner test on "); > - for_each_connected_output(display, output){ > - enum pipe p = output->pending_pipe; > - drmModeModeInfo *mode; > - igt_pipe_t *pipe; > - igt_plane_t *plane; > +static void generate_combinations(int output_count, int pipe_count, > + int pipes_per_output, > + Combination combinations[MAX_COMBINATIONS], > + uint64_t *num_combinations) If possible, can you please add some documentation? I am not able to understand this logic. > +{ > + int i, index; > + int current_combination[MAX_OUTPUTS]; > > - if (p == PIPE_NONE) > - continue; > + for (i = 0; i < output_count; ++i) > + current_combination[i] = i * pipes_per_output; > > - mode = igt_output_get_mode(output); > - igt_info("pipe:%s, output:%s, mode:", kmstest_pipe_name(p), igt_output_name(output)); > - kmstest_dump_mode(mode); > + while (current_combination[0] <= pipe_count - output_count * pipes_per_output) { > + for (i = 0; i < output_count; ++i) > + combinations[*num_combinations].combination[i] = current_combination[i]; > > - pipe = &display->pipes[p]; > - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); > + (*num_combinations)++; > > - igt_plane_set_fb(plane, &data->fb); > - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); > - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); > - } > + index = output_count - 1; > + while (index >= 0 && current_combination[index] == pipe_count - (output_count - index) * pipes_per_output) > + index--; > > - igt_assert(!igt_check_bigjoiner_support(display)); > + if (index < 0) > + break; > > - /* This commit is expectd to fail as this pipe is being used for big joiner */ > - ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | > - DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); > + current_combination[index]++; > + for (i = index + 1; i < output_count; ++i) > + current_combination[i] = current_combination[i - 1] + pipes_per_output; > + } > +} > > - igt_display_reset(&data->display); > - igt_display_commit2(display, COMMIT_ATOMIC); > +static igt_output_t *get_output_by_id(data_t *data, uint64_t output_id) > +{ > + igt_output_t *output; > > - igt_assert_lt(ret, 0); > + for_each_connected_output(&data->display, output) { > + if (output->id == output_id) > + return output; > + } > + igt_assert("Output not found\n"); igt_assert without condition? > + return NULL; > } > > -static void test_basic_modeset(data_t *data) > +static void test_invalid_modeset_two_joiner(data_t *data, bool force_joiner, > + bool combined) > { > + int i, j, ret; > + igt_output_t *output; > + uint64_t *outputs; > + igt_plane_t *primary[INVALID_TEST_OUTPUT]; > + igt_fb_t fb[INVALID_TEST_OUTPUT]; > drmModeModeInfo *mode; > - igt_output_t *output, *bigjoiner_output = NULL; > - igt_display_t *display = &data->display; > - igt_pipe_t *pipe; > - igt_plane_t *plane; > - > - igt_display_reset(display); > > - for_each_connected_output(display, output) { > - if (data->output[0].output_id == output->id) { > - bigjoiner_output = output; > - break; > + outputs = force_joiner ? data->non_big_joiner_outputs : > + combined ? data->combined_outputs : data->big_joiner_outputs; > + > + for (i = 0; i < data->n_pipes-1; i++) { > + igt_display_reset(&data->display); > + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { > + output = get_output_by_id(data, outputs[j]); > + igt_assert(output); > + if (force_joiner) { > + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); > + } > + igt_output_set_pipe(output, data->pipe_seq[i + j]); > + mode = igt_output_get_mode(output); > + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d%s", > + kmstest_pipe_name(data->pipe_seq[i + j]), > + igt_output_name(output), mode->hdisplay, > + mode->vdisplay, mode->vrefresh, > + j == INVALID_TEST_OUTPUT - 1 ? "\n" : ", "); > + primary[j] = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); > + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, > + DRM_FORMAT_MOD_LINEAR, &fb[j]); > + igt_plane_set_fb(primary[j], &fb[j]); > + } > + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); > + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); > + if (force_joiner) { > + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { > + output = get_output_by_id(data, outputs[j]); > + igt_assert(output); > + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 0); > + } > } > } > - > - igt_output_set_pipe(bigjoiner_output, data->pipe1); > - > - mode = &data->output[0].mode; > - igt_output_override_mode(bigjoiner_output, mode); > - > - pipe = &display->pipes[data->pipe1]; > - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); > - > - igt_plane_set_fb(plane, &data->fb); > - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); > - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); > - > - igt_display_commit2(display, COMMIT_ATOMIC); > - > - igt_output_set_pipe(bigjoiner_output, PIPE_NONE); > - igt_plane_set_fb(plane, NULL); > - igt_display_commit2(display, COMMIT_ATOMIC); > } > > -static void test_dual_display(data_t *data) > +static void tets_big_joiner_on_last_pipe(data_t *data, bool force_joiner) > { > + int i, len, ret; > + uint64_t *outputs; > + igt_output_t *output; > + igt_plane_t *primary; > + igt_fb_t fb; > drmModeModeInfo *mode; > - igt_output_t *output, *bigjoiner_output[2]; > - igt_display_t *display = &data->display; > - igt_pipe_t *pipe; > - igt_plane_t *plane1, *plane2; > - int count = 0; > > - igt_display_reset(display); > + len = force_joiner ? data->non_big_joiner_output_count : data->big_joiner_output_count; > + outputs = force_joiner ? data->non_big_joiner_outputs : data->big_joiner_outputs; > > - for_each_connected_output(display, output) { > - if (data->output[count].output_id == output->id) { > - bigjoiner_output[count] = output; > - count++; > + for (i = 0; i < len; i++) { > + igt_display_reset(&data->display); > + output = get_output_by_id(data, outputs[i]); > + if (force_joiner) { > + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); > } > - > - if (count > 1) > - break; > + igt_output_set_pipe(output, data->pipe_seq[data->n_pipes - 1]); > + mode = igt_output_get_mode(output); > + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d\n", > + kmstest_pipe_name(data->pipe_seq[data->n_pipes - 1]), > + igt_output_name(output), mode->hdisplay, > + mode->vdisplay, mode->vrefresh); > + primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); > + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, > + DRM_FORMAT_MOD_LINEAR, &fb); > + igt_plane_set_fb(primary, &fb); > + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); > + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); > } > + if (force_joiner) { > + for (i = 0; i < len; i++) { > + output = get_output_by_id(data, outputs[i]); > + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); > + } > + } > +} > > - igt_output_set_pipe(bigjoiner_output[0], data->pipe1); > - igt_output_set_pipe(bigjoiner_output[1], data->pipe2); > - > - /* Set up first big joiner output on Pipe A*/ > - mode = &data->output[0].mode; > - igt_output_override_mode(bigjoiner_output[0], mode); > - > - pipe = &display->pipes[data->pipe1]; > - plane1 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); > - > - igt_plane_set_fb(plane1, &data->fb); > - igt_fb_set_size(&data->fb, plane1, mode->hdisplay, mode->vdisplay); > - igt_plane_set_size(plane1, mode->hdisplay, mode->vdisplay); > - > - /* Set up second big joiner output on Pipe C*/ > - mode = &data->output[1].mode; > - igt_output_override_mode(bigjoiner_output[1], mode); > - > - pipe = &display->pipes[data->pipe2]; > - plane2 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); > - > - igt_plane_set_fb(plane2, &data->fb); > - igt_fb_set_size(&data->fb, plane2, mode->hdisplay, mode->vdisplay); > - igt_plane_set_size(plane2, mode->hdisplay, mode->vdisplay); > - > - igt_display_commit2(display, COMMIT_ATOMIC); > +static void test_basic_modeset(data_t *data, int num_outputs, > + Combination combinations[MAX_COMBINATIONS], > + uint64_t num_combinations, bool force_joiner) > +{ > + int i, j, ret; > + igt_display_t *display = &data->display; > + igt_output_t *output[num_outputs]; > + igt_plane_t *primary[num_outputs]; > + igt_fb_t fb[num_outputs]; > + drmModeModeInfo *mode; > > - /* Clean up */ > - igt_output_set_pipe(bigjoiner_output[0], PIPE_NONE); > - igt_output_set_pipe(bigjoiner_output[1], PIPE_NONE); > - igt_plane_set_fb(plane1, NULL); > - igt_plane_set_fb(plane2, NULL); > - igt_display_commit2(display, COMMIT_ATOMIC); > + for (i = 0; i < num_combinations; i++) { > + igt_display_reset(display); > + for (j = 0; j < num_outputs; j++) { > + output[j] = get_output_by_id(data, > + force_joiner ? > + data->non_big_joiner_outputs[j] : > + data->big_joiner_outputs[j]); > + if (force_joiner) { > + igt_force_bigjoiner_enable(data->drm_fd, > + output[j]->name, true); Do we need to check the sysfs write status? since this helper has the return type as non-void. > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, > + output[j]->name) == 1); > + } > + igt_info("Assigning pipe %d to %s%s", > + data->pipe_seq[combinations[i].combination[j]], Let's print the pipe name which is more redable than index. > + output[j]->name, j == num_outputs - 1 ? "\n" : ", "); > + igt_output_set_pipe(output[j], data->pipe_seq[combinations[i].combination[j]]); > + primary[j] = igt_output_get_plane_type(output[j], DRM_PLANE_TYPE_PRIMARY); > + mode = igt_output_get_mode(output[j]); > + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, > + DRM_FORMAT_MOD_LINEAR, &fb[j]); > + igt_plane_set_fb(primary[j], &fb[j]); > + } > + ret = igt_display_try_commit2(display, COMMIT_ATOMIC); > + if (ret == 0) > + igt_display_commit2(display, COMMIT_ATOMIC); This commit is not required. > + else > + igt_assert_f(ret == 0, "Commit failed\n"); > + > + if (force_joiner) { > + for (j = 0; j < num_outputs; j++) { > + igt_force_bigjoiner_enable(data->drm_fd, output[j]->name, false); > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output[j]->name) == 0); > + } > + } > + } > } > > igt_main > { > + int i, j; > data_t data; > igt_output_t *output; > - drmModeModeInfo mode; > - int valid_output = 0, i, count = 0, j = 0; > - uint16_t width = 0, height = 0; > - enum pipe pipe_seq[IGT_MAX_PIPES]; > > + i = j = 0; > igt_fixture { > data.drm_fd = drm_open_driver_master(DRIVER_INTEL | DRIVER_XE); > kmstest_set_vt_graphics_mode(); > - > igt_display_require(&data.display, data.drm_fd); > igt_require(data.display.is_atomic); > - > max_dotclock = igt_get_max_dotclock(data.drm_fd); > + data.big_joiner_output_count = 0; > + data.non_big_joiner_output_count = 0; > + data.combined_output_count = 0; > + data.output_count = 0; > > for_each_connected_output(&data.display, output) { > bool found = false; > drmModeConnector *connector = output->config.connector; > - > - /* > - * Bigjoiner will come in to the picture when the > - * resolution > 5K or clock > max-dot-clock. > - */ > found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock); > - > if (found) { > - data.output[count].output_id = output->id; > - memcpy(&data.output[count].mode, &mode, sizeof(drmModeModeInfo)); > - count++; > - > - width = max(width, mode.hdisplay); > - height = max(height, mode.vdisplay); > + data.big_joiner_outputs[data.big_joiner_output_count++] = output->id; > + igt_output_override_mode(output, &connector->modes[0]); > + } else { > + if (output_supports_force_joiner(output)) { > + data.non_big_joiner_outputs[data.non_big_joiner_output_count++] = output->id; > + igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc); Do we really need to sort the connector modes? > + igt_output_override_mode(output, &connector->modes[0]); > + } > } > - valid_output++; > + data.output_count++; > } > > data.n_pipes = 0; > for_each_pipe(&data.display, i) { > data.n_pipes++; > - pipe_seq[j] = i; > + data.pipe_seq[j] = i; > j++; > } > - > - igt_require_f(count > 0, "No output with 5k+ mode (or) clock > max-dot-clock found\n"); > - > - igt_create_pattern_fb(data.drm_fd, width, height, DRM_FORMAT_XRGB8888, > - DRM_FORMAT_MOD_LINEAR, &data.fb); > } > > igt_describe("Verify the basic modeset on big joiner mode on all pipes"); > igt_subtest_with_dynamic("basic") { > - for (i = 0; i < data.n_pipes - 1; i++) { > - data.pipe1 = pipe_seq[i]; > - igt_dynamic_f("pipe-%s", kmstest_pipe_name(pipe_seq[i])) > - test_basic_modeset(&data); > + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); > + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); > + > + for (i = 0; i < data.big_joiner_output_count; i++) { > + uint64_t num_combinations = 0; > + Combination combinations[MAX_COMBINATIONS]; > + > + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); > + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", > + i+1, data.n_pipes, num_combinations); > + > + if (num_combinations > 0) > + igt_dynamic_f("%dx-big-joiner", i+1) > + test_basic_modeset(&data, i+1, combinations, num_combinations, false); > + else > + break; IMHO, we need to split this patch into 2: 1- Rewamp existing subtests 2- Add new subtests for forcejoiner > } > } > > - igt_describe("Verify if the modeset on the adjoining pipe is rejected " > - "when the pipe is active with a big joiner modeset"); > - igt_subtest_with_dynamic("invalid-modeset") { > - data.pipe1 = pipe_seq[j - 1]; > - > - igt_display_reset(&data.display); > - for_each_connected_output(&data.display, output) { > - if (data.output[0].output_id != output->id) > - continue; > - > - mode = data.output[0].mode; > - igt_output_set_pipe(output, data.pipe1); > - igt_output_override_mode(output, &mode); > - > - igt_dynamic_f("pipe-%s-%s", > - kmstest_pipe_name(data.pipe1), > - igt_output_name(output)) > - test_invalid_modeset(&data); > + igt_describe("Verify the basic modeset on big joiner mode on all pipes"); > + igt_subtest_with_dynamic("force-joiner-basic") { > + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >= 11, > + "force joiner not supported on this platform\n"); > + igt_require_f(data.non_big_joiner_output_count > 0, "Big joiner output not found\n"); > + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); > + > + for (i = 0; i < data.non_big_joiner_output_count; i++) { > + uint64_t num_combinations = 0; > + Combination combinations[MAX_COMBINATIONS]; > + > + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); > + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", > + i+1, data.n_pipes, num_combinations); > + > + if (num_combinations > 0) > + igt_dynamic_f("%dx-joiner", i+1) > + test_basic_modeset(&data, i+1, combinations, num_combinations, true); > + else > + break; > } > + } > > - if(valid_output > 1) { > - for (i = 0; i < data.n_pipes - 1; i++) { > - igt_output_t *first_output = NULL, *second_output = NULL; > - > - data.pipe1 = pipe_seq[i]; > - data.pipe2 = pipe_seq[i + 1]; > - > - igt_display_reset(&data.display); > - for_each_connected_output(&data.display, output) { > - if (data.output[0].output_id == output->id) { > - first_output = output; > - mode = data.output[0].mode; > + igt_subtest_with_dynamic("invalid-modeset") { > + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); > + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); > > - igt_output_set_pipe(output, data.pipe1); > - igt_output_override_mode(output, &mode); > - } else if (second_output == NULL) { > - second_output = output; > - igt_output_set_pipe(output, data.pipe2); > + if (data.big_joiner_output_count >= 1) > + igt_dynamic_f("big_joiner_on_last_pipe") > + tets_big_joiner_on_last_pipe(&data, false); > > - break; > - } > - } > + if (data.big_joiner_output_count > 1) > + igt_dynamic_f("invalid_combinations") > + test_invalid_modeset_two_joiner(&data, false, false); > > - igt_dynamic_f("pipe-%s-%s-pipe-%s-%s", > - kmstest_pipe_name(data.pipe1), > - igt_output_name(first_output), > - kmstest_pipe_name(data.pipe2), > - igt_output_name(second_output)) > - test_invalid_modeset(&data); > - } > + if (data.big_joiner_output_count == 1 && data.non_big_joiner_output_count > 0) { > + data.combined_outputs[data.combined_output_count++] = data.big_joiner_outputs[0]; > + data.combined_outputs[data.combined_output_count++] = data.non_big_joiner_outputs[0]; Probably, move this logic to igt_fixture & use as: if (data.combined_output_count) > + test_invalid_modeset_two_joiner(&data, false, true); igt_dynamic() is missing. - Bhanu > } > } > > - igt_describe("Verify simultaneous modeset on 2 big joiner outputs"); > - igt_subtest_with_dynamic("2x-modeset") { > - igt_require_f(count > 1, "2 outputs with big joiner modes are required\n"); > - igt_require_f(data.n_pipes > 3, "Minumum of 4 pipes are required\n"); > - for (i = 0; (i + 2) < data.n_pipes - 1; i++) { > - data.pipe1 = pipe_seq[i]; > - data.pipe2 = pipe_seq[i + 2]; > - igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe_seq[i]), kmstest_pipe_name(pipe_seq[i + 2])) > - test_dual_display(&data); > - } > + igt_subtest_with_dynamic("force-joiner-invalid-modeset") { > + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >= 11, > + "force joiner not supported on this platform\n"); > + igt_require_f(data.non_big_joiner_output_count > 0, "Non big joiner output not found\n"); > + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); > + > + if (data.non_big_joiner_output_count >= 1) > + igt_dynamic_f("big_joiner_on_last_pipe") > + tets_big_joiner_on_last_pipe(&data, true); > + > + if (data.non_big_joiner_output_count > 1) > + igt_dynamic_f("invalid_combinations") > + test_invalid_modeset_two_joiner(&data, true, false); > } > > igt_fixture { > - igt_remove_fb(data.drm_fd, &data.fb); > igt_display_fini(&data.display); > drm_close_driver(data.drm_fd); > } ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner 2024-03-05 11:44 ` Modem, Bhanuprakash @ 2024-03-05 13:14 ` Joshi, Kunal1 2024-03-05 17:34 ` Kamil Konieczny 1 sibling, 0 replies; 14+ messages in thread From: Joshi, Kunal1 @ 2024-03-05 13:14 UTC (permalink / raw) To: Modem, Bhanuprakash, igt-dev, Kamil Konieczny; +Cc: Karthik B S Hello Bhanu, On 3/5/2024 5:14 PM, Modem, Bhanuprakash wrote: > Hi Kunal, > > On 03-03-2024 10:52 pm, Kunal Joshi wrote: >> big joiner outputs are statically assigned to pipe, >> assign dynamically also add support for forcing >> joiner, support for forcing joiner was introduced with >> below kmd patch >> >> drm/i915: Add bigjoiner force enable option to debugfs >> >> Cc: Karthik B S <karthik.b.s@intel.com> >> Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> >> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> >> --- >> tests/intel/kms_big_joiner.c | 494 +++++++++++++++++++---------------- >> 1 file changed, 270 insertions(+), 224 deletions(-) >> >> diff --git a/tests/intel/kms_big_joiner.c b/tests/intel/kms_big_joiner.c >> index 28678b958..a4f6b8782 100644 >> --- a/tests/intel/kms_big_joiner.c >> +++ b/tests/intel/kms_big_joiner.c >> @@ -1,27 +1,6 @@ >> +/* SPDX-License-Identifier: MIT */ >> /* >> - * Copyright © 2020 Intel Corporation >> - * >> - * Permission is hereby granted, free of charge, to any person >> obtaining a >> - * copy of this software and associated documentation files (the >> "Software"), >> - * to deal in the Software without restriction, including without >> limitation >> - * the rights to use, copy, modify, merge, publish, distribute, >> sublicense, >> - * and/or sell copies of the Software, and to permit persons to whom >> the >> - * Software is furnished to do so, subject to the following conditions: >> - * >> - * The above copyright notice and this permission notice (including >> the next >> - * paragraph) shall be included in all copies or substantial >> portions of the >> - * Software. >> - * >> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >> EXPRESS OR >> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >> MERCHANTABILITY, >> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO >> EVENT SHALL >> - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES >> OR OTHER >> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, >> ARISING >> - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR >> OTHER DEALINGS >> - * IN THE SOFTWARE. >> - * >> - * Author: >> - * Karthik B S <karthik.b.s@intel.com> >> + * Copyright © 2024 Intel Corporation > > I think, we don't need to touch the license part. > > @kmail JFYI @kmail please let me know if this needs to be updated or not will remove in the next revision for now > >> */ >> /** >> @@ -37,22 +16,36 @@ >> #include "igt.h" >> /** >> - * SUBTEST: invalid-modeset >> - * Description: Verify if the modeset on the adjoining pipe is >> rejected when >> - * the pipe is active with a big joiner modeset >> - * >> * SUBTEST: basic >> * Description: Verify the basic modeset on big joiner mode on all >> pipes >> * >> - * SUBTEST: 2x-modeset >> - * Description: Verify simultaneous modeset on 2 big joiner outputs >> + * SUBTEST: force-joiner-basic >> + * Description: Verify the basic modeset on force joiner mode on all >> pipes >> + * >> + * SUBTEST: invalid-modeset >> + * Description: Verify the invalid modeset on big joiner mode on all >> pipes >> + * >> + * SUBTEST: force-joiner-invalid-modeset >> + * Description: Verify the invalid modeset on force joiner mode on >> all pipes >> */ >> +IGT_TEST_DESCRIPTION("Test big joiner / force joiner"); >> -IGT_TEST_DESCRIPTION("Test big joiner"); >> +#define MAX_OUTPUTS 256 >> +#define MAX_COMBINATIONS 1000 >> +#define INVALID_TEST_OUTPUT 2 >> +typedef struct { >> + int combination[MAX_OUTPUTS]; >> +} Combination; >> -struct bigjoiner_output { >> - uint32_t output_id; >> - drmModeModeInfo mode; >> +enum tests { >> + BASIC, >> + INVALID_MODESET, >> + INVALID, >> +}; >> + >> +enum joiner_type { >> + BIG_JOINER = 1 << 1, >> + INVALID_JOINER = -1, >> }; >> typedef struct { >> @@ -60,273 +53,326 @@ typedef struct { >> igt_display_t display; >> struct igt_fb fb; >> int n_pipes; >> - enum pipe pipe1; >> - enum pipe pipe2; >> - struct bigjoiner_output output[2]; >> + uint64_t big_joiner_outputs[IGT_MAX_PIPES]; >> + uint64_t non_big_joiner_outputs[IGT_MAX_PIPES]; >> + uint64_t combined_outputs[IGT_MAX_PIPES]; >> + int big_joiner_output_count; >> + int non_big_joiner_output_count; >> + int combined_output_count; >> + int output_count; >> + enum pipe pipe_seq[IGT_MAX_PIPES]; >> } data_t; >> static int max_dotclock; >> -static void test_invalid_modeset(data_t *data) >> +static bool output_supports_force_joiner(igt_output_t *output) >> { >> - igt_output_t *output; >> - igt_display_t *display = &data->display; >> - int ret; >> + return output->config.connector->connector_type == >> + DRM_MODE_CONNECTOR_DisplayPort || >> + output->config.connector->connector_type == >> + DRM_MODE_CONNECTOR_eDP; >> +} > > I think, this is not a source of truth. Perhaps, you can just check if > debugfs is present or not. Will address in next revision. > >> - igt_info("Bigjoiner test on "); >> - for_each_connected_output(display, output){ >> - enum pipe p = output->pending_pipe; >> - drmModeModeInfo *mode; >> - igt_pipe_t *pipe; >> - igt_plane_t *plane; >> +static void generate_combinations(int output_count, int pipe_count, >> + int pipes_per_output, >> + Combination combinations[MAX_COMBINATIONS], >> + uint64_t *num_combinations) > > If possible, can you please add some documentation? I am not able to > understand this logic. Sure will add. > > >> +{ >> + int i, index; >> + int current_combination[MAX_OUTPUTS]; >> - if (p == PIPE_NONE) >> - continue; >> + for (i = 0; i < output_count; ++i) >> + current_combination[i] = i * pipes_per_output; >> - mode = igt_output_get_mode(output); >> - igt_info("pipe:%s, output:%s, mode:", kmstest_pipe_name(p), >> igt_output_name(output)); >> - kmstest_dump_mode(mode); >> + while (current_combination[0] <= pipe_count - output_count * >> pipes_per_output) { >> + for (i = 0; i < output_count; ++i) >> + combinations[*num_combinations].combination[i] = >> current_combination[i]; >> - pipe = &display->pipes[p]; >> - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); >> + (*num_combinations)++; >> - igt_plane_set_fb(plane, &data->fb); >> - igt_fb_set_size(&data->fb, plane, mode->hdisplay, >> mode->vdisplay); >> - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); >> - } >> + index = output_count - 1; >> + while (index >= 0 && current_combination[index] == >> pipe_count - (output_count - index) * pipes_per_output) >> + index--; >> - igt_assert(!igt_check_bigjoiner_support(display)); >> + if (index < 0) >> + break; >> - /* This commit is expectd to fail as this pipe is being used >> for big joiner */ >> - ret = igt_display_try_commit_atomic(display, >> DRM_MODE_ATOMIC_TEST_ONLY | >> - DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); >> + current_combination[index]++; >> + for (i = index + 1; i < output_count; ++i) >> + current_combination[i] = current_combination[i - 1] + >> pipes_per_output; >> + } >> +} >> - igt_display_reset(&data->display); >> - igt_display_commit2(display, COMMIT_ATOMIC); >> +static igt_output_t *get_output_by_id(data_t *data, uint64_t output_id) >> +{ >> + igt_output_t *output; >> - igt_assert_lt(ret, 0); >> + for_each_connected_output(&data->display, output) { >> + if (output->id == output_id) >> + return output; >> + } >> + igt_assert("Output not found\n"); > > igt_assert without condition? Expectation is to always find output with given id, if not assert Probably will change the name of the function get_output_by_id_or_assert() > >> + return NULL; >> } >> -static void test_basic_modeset(data_t *data) >> +static void test_invalid_modeset_two_joiner(data_t *data, bool >> force_joiner, >> + bool combined) >> { >> + int i, j, ret; >> + igt_output_t *output; >> + uint64_t *outputs; >> + igt_plane_t *primary[INVALID_TEST_OUTPUT]; >> + igt_fb_t fb[INVALID_TEST_OUTPUT]; >> drmModeModeInfo *mode; >> - igt_output_t *output, *bigjoiner_output = NULL; >> - igt_display_t *display = &data->display; >> - igt_pipe_t *pipe; >> - igt_plane_t *plane; >> - >> - igt_display_reset(display); >> - for_each_connected_output(display, output) { >> - if (data->output[0].output_id == output->id) { >> - bigjoiner_output = output; >> - break; >> + outputs = force_joiner ? data->non_big_joiner_outputs : >> + combined ? data->combined_outputs : data->big_joiner_outputs; >> + >> + for (i = 0; i < data->n_pipes-1; i++) { >> + igt_display_reset(&data->display); >> + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { >> + output = get_output_by_id(data, outputs[j]); >> + igt_assert(output); >> + if (force_joiner) { >> + igt_force_bigjoiner_enable(data->drm_fd, >> output->name, true); >> + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, >> output->name) == 1); >> + } >> + igt_output_set_pipe(output, data->pipe_seq[i + j]); >> + mode = igt_output_get_mode(output); >> + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d%s", >> + kmstest_pipe_name(data->pipe_seq[i + j]), >> + igt_output_name(output), mode->hdisplay, >> + mode->vdisplay, mode->vrefresh, >> + j == INVALID_TEST_OUTPUT - 1 ? "\n" : ", "); >> + primary[j] = igt_output_get_plane_type(output, >> DRM_PLANE_TYPE_PRIMARY); >> + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, >> mode->vdisplay, DRM_FORMAT_XRGB8888, >> + DRM_FORMAT_MOD_LINEAR, &fb[j]); >> + igt_plane_set_fb(primary[j], &fb[j]); >> + } >> + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); >> + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); >> + if (force_joiner) { >> + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { >> + output = get_output_by_id(data, outputs[j]); >> + igt_assert(output); >> + igt_force_bigjoiner_enable(data->drm_fd, >> output->name, false); >> + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, >> output->name) == 0); >> + } >> } >> } >> - >> - igt_output_set_pipe(bigjoiner_output, data->pipe1); >> - >> - mode = &data->output[0].mode; >> - igt_output_override_mode(bigjoiner_output, mode); >> - >> - pipe = &display->pipes[data->pipe1]; >> - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); >> - >> - igt_plane_set_fb(plane, &data->fb); >> - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); >> - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); >> - >> - igt_display_commit2(display, COMMIT_ATOMIC); >> - >> - igt_output_set_pipe(bigjoiner_output, PIPE_NONE); >> - igt_plane_set_fb(plane, NULL); >> - igt_display_commit2(display, COMMIT_ATOMIC); >> } >> -static void test_dual_display(data_t *data) >> +static void tets_big_joiner_on_last_pipe(data_t *data, bool >> force_joiner) >> { >> + int i, len, ret; >> + uint64_t *outputs; >> + igt_output_t *output; >> + igt_plane_t *primary; >> + igt_fb_t fb; >> drmModeModeInfo *mode; >> - igt_output_t *output, *bigjoiner_output[2]; >> - igt_display_t *display = &data->display; >> - igt_pipe_t *pipe; >> - igt_plane_t *plane1, *plane2; >> - int count = 0; >> - igt_display_reset(display); >> + len = force_joiner ? data->non_big_joiner_output_count : >> data->big_joiner_output_count; >> + outputs = force_joiner ? data->non_big_joiner_outputs : >> data->big_joiner_outputs; >> - for_each_connected_output(display, output) { >> - if (data->output[count].output_id == output->id) { >> - bigjoiner_output[count] = output; >> - count++; >> + for (i = 0; i < len; i++) { >> + igt_display_reset(&data->display); >> + output = get_output_by_id(data, outputs[i]); >> + if (force_joiner) { >> + igt_force_bigjoiner_enable(data->drm_fd, output->name, >> true); >> + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, >> output->name) == 1); >> } >> - >> - if (count > 1) >> - break; >> + igt_output_set_pipe(output, data->pipe_seq[data->n_pipes - 1]); >> + mode = igt_output_get_mode(output); >> + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d\n", >> + kmstest_pipe_name(data->pipe_seq[data->n_pipes - 1]), >> + igt_output_name(output), mode->hdisplay, >> + mode->vdisplay, mode->vrefresh); >> + primary = igt_output_get_plane_type(output, >> DRM_PLANE_TYPE_PRIMARY); >> + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, >> mode->vdisplay, DRM_FORMAT_XRGB8888, >> + DRM_FORMAT_MOD_LINEAR, &fb); >> + igt_plane_set_fb(primary, &fb); >> + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); >> + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); >> } >> + if (force_joiner) { >> + for (i = 0; i < len; i++) { >> + output = get_output_by_id(data, outputs[i]); >> + igt_force_bigjoiner_enable(data->drm_fd, output->name, >> false); >> + } >> + } >> +} >> - igt_output_set_pipe(bigjoiner_output[0], data->pipe1); >> - igt_output_set_pipe(bigjoiner_output[1], data->pipe2); >> - >> - /* Set up first big joiner output on Pipe A*/ >> - mode = &data->output[0].mode; >> - igt_output_override_mode(bigjoiner_output[0], mode); >> - >> - pipe = &display->pipes[data->pipe1]; >> - plane1 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); >> - >> - igt_plane_set_fb(plane1, &data->fb); >> - igt_fb_set_size(&data->fb, plane1, mode->hdisplay, mode->vdisplay); >> - igt_plane_set_size(plane1, mode->hdisplay, mode->vdisplay); >> - >> - /* Set up second big joiner output on Pipe C*/ >> - mode = &data->output[1].mode; >> - igt_output_override_mode(bigjoiner_output[1], mode); >> - >> - pipe = &display->pipes[data->pipe2]; >> - plane2 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); >> - >> - igt_plane_set_fb(plane2, &data->fb); >> - igt_fb_set_size(&data->fb, plane2, mode->hdisplay, mode->vdisplay); >> - igt_plane_set_size(plane2, mode->hdisplay, mode->vdisplay); >> - >> - igt_display_commit2(display, COMMIT_ATOMIC); >> +static void test_basic_modeset(data_t *data, int num_outputs, >> + Combination combinations[MAX_COMBINATIONS], >> + uint64_t num_combinations, bool force_joiner) >> +{ >> + int i, j, ret; >> + igt_display_t *display = &data->display; >> + igt_output_t *output[num_outputs]; >> + igt_plane_t *primary[num_outputs]; >> + igt_fb_t fb[num_outputs]; >> + drmModeModeInfo *mode; >> - /* Clean up */ >> - igt_output_set_pipe(bigjoiner_output[0], PIPE_NONE); >> - igt_output_set_pipe(bigjoiner_output[1], PIPE_NONE); >> - igt_plane_set_fb(plane1, NULL); >> - igt_plane_set_fb(plane2, NULL); >> - igt_display_commit2(display, COMMIT_ATOMIC); >> + for (i = 0; i < num_combinations; i++) { >> + igt_display_reset(display); >> + for (j = 0; j < num_outputs; j++) { >> + output[j] = get_output_by_id(data, >> + force_joiner ? >> + data->non_big_joiner_outputs[j] : >> + data->big_joiner_outputs[j]); >> + if (force_joiner) { >> + igt_force_bigjoiner_enable(data->drm_fd, >> + output[j]->name, true); > > Do we need to check the sysfs write status? since this helper has the > return type as non-void. Yes we can check but here we are checking the status to see whether write was successful, Maybe i can combine both igt_force_bigjoiner_enable and igt_check_force_bigjoiner_status > >> + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, >> + output[j]->name) == 1); >> + } >> + igt_info("Assigning pipe %d to %s%s", >> + data->pipe_seq[combinations[i].combination[j]], > > Let's print the pipe name which is more redable than index. Yes this was a miss, have done it in rest of the places, Will fix it in next revision > >> + output[j]->name, j == num_outputs - 1 ? "\n" : ", "); >> + igt_output_set_pipe(output[j], >> data->pipe_seq[combinations[i].combination[j]]); >> + primary[j] = igt_output_get_plane_type(output[j], >> DRM_PLANE_TYPE_PRIMARY); >> + mode = igt_output_get_mode(output[j]); >> + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, >> mode->vdisplay, DRM_FORMAT_XRGB8888, >> + DRM_FORMAT_MOD_LINEAR, &fb[j]); >> + igt_plane_set_fb(primary[j], &fb[j]); >> + } >> + ret = igt_display_try_commit2(display, COMMIT_ATOMIC); >> + if (ret == 0) >> + igt_display_commit2(display, COMMIT_ATOMIC); > > This commit is not required. Ok will remove this. > > >> + else >> + igt_assert_f(ret == 0, "Commit failed\n"); >> + >> + if (force_joiner) { >> + for (j = 0; j < num_outputs; j++) { >> + igt_force_bigjoiner_enable(data->drm_fd, >> output[j]->name, false); >> + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, >> output[j]->name) == 0); >> + } >> + } >> + } >> } >> igt_main >> { >> + int i, j; >> data_t data; >> igt_output_t *output; >> - drmModeModeInfo mode; >> - int valid_output = 0, i, count = 0, j = 0; >> - uint16_t width = 0, height = 0; >> - enum pipe pipe_seq[IGT_MAX_PIPES]; >> + i = j = 0; >> igt_fixture { >> data.drm_fd = drm_open_driver_master(DRIVER_INTEL | >> DRIVER_XE); >> kmstest_set_vt_graphics_mode(); >> - >> igt_display_require(&data.display, data.drm_fd); >> igt_require(data.display.is_atomic); >> - >> max_dotclock = igt_get_max_dotclock(data.drm_fd); >> + data.big_joiner_output_count = 0; >> + data.non_big_joiner_output_count = 0; >> + data.combined_output_count = 0; >> + data.output_count = 0; >> for_each_connected_output(&data.display, output) { >> bool found = false; >> drmModeConnector *connector = output->config.connector; >> - >> - /* >> - * Bigjoiner will come in to the picture when the >> - * resolution > 5K or clock > max-dot-clock. >> - */ >> found = bigjoiner_mode_found(data.drm_fd, connector, >> max_dotclock); >> - >> if (found) { >> - data.output[count].output_id = output->id; >> - memcpy(&data.output[count].mode, &mode, >> sizeof(drmModeModeInfo)); >> - count++; >> - >> - width = max(width, mode.hdisplay); >> - height = max(height, mode.vdisplay); >> + data.big_joiner_outputs[data.big_joiner_output_count++] = output->id; >> + igt_output_override_mode(output, &connector->modes[0]); >> + } else { >> + if (output_supports_force_joiner(output)) { >> + data.non_big_joiner_outputs[data.non_big_joiner_output_count++] = >> output->id; >> + igt_sort_connector_modes(connector, >> sort_drm_modes_by_res_dsc); > > Do we really need to sort the connector modes? Yes bigjoiner_mode_found will sort the mode first by res then by clock If this is non big joiner output then it will be currently sorted by clock Maybe i can check if there is connector reset which sets how it was default. > >> + igt_output_override_mode(output, &connector->modes[0]); >> + } >> } >> - valid_output++; >> + data.output_count++; >> } >> data.n_pipes = 0; >> for_each_pipe(&data.display, i) { >> data.n_pipes++; >> - pipe_seq[j] = i; >> + data.pipe_seq[j] = i; >> j++; >> } >> - >> - igt_require_f(count > 0, "No output with 5k+ mode (or) clock >> > max-dot-clock found\n"); >> - >> - igt_create_pattern_fb(data.drm_fd, width, height, >> DRM_FORMAT_XRGB8888, >> - DRM_FORMAT_MOD_LINEAR, &data.fb); >> } >> igt_describe("Verify the basic modeset on big joiner mode on >> all pipes"); >> igt_subtest_with_dynamic("basic") { >> - for (i = 0; i < data.n_pipes - 1; i++) { >> - data.pipe1 = pipe_seq[i]; >> - igt_dynamic_f("pipe-%s", kmstest_pipe_name(pipe_seq[i])) >> - test_basic_modeset(&data); >> + igt_require_f(data.big_joiner_output_count > 0, "Big joiner >> output not found\n"); >> + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are >> required\n"); >> + >> + for (i = 0; i < data.big_joiner_output_count; i++) { >> + uint64_t num_combinations = 0; >> + Combination combinations[MAX_COMBINATIONS]; >> + >> + generate_combinations(i+1, data.n_pipes, BIG_JOINER, >> combinations, &num_combinations); >> + igt_info("Number of combinations for %d outputs and %d >> pipes are %ld\n", >> + i+1, data.n_pipes, num_combinations); >> + >> + if (num_combinations > 0) >> + igt_dynamic_f("%dx-big-joiner", i+1) >> + test_basic_modeset(&data, i+1, combinations, >> num_combinations, false); >> + else >> + break; > > IMHO, we need to split this patch into 2: > 1- Rewamp existing subtests > 2- Add new subtests for forcejoiner > Ok will split. > >> } >> } >> - igt_describe("Verify if the modeset on the adjoining pipe is >> rejected " >> - "when the pipe is active with a big joiner modeset"); >> - igt_subtest_with_dynamic("invalid-modeset") { >> - data.pipe1 = pipe_seq[j - 1]; >> - >> - igt_display_reset(&data.display); >> - for_each_connected_output(&data.display, output) { >> - if (data.output[0].output_id != output->id) >> - continue; >> - >> - mode = data.output[0].mode; >> - igt_output_set_pipe(output, data.pipe1); >> - igt_output_override_mode(output, &mode); >> - >> - igt_dynamic_f("pipe-%s-%s", >> - kmstest_pipe_name(data.pipe1), >> - igt_output_name(output)) >> - test_invalid_modeset(&data); >> + igt_describe("Verify the basic modeset on big joiner mode on all >> pipes"); >> + igt_subtest_with_dynamic("force-joiner-basic") { >> + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >> >= 11, >> + "force joiner not supported on this >> platform\n"); >> + igt_require_f(data.non_big_joiner_output_count > 0, "Big >> joiner output not found\n"); >> + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are >> required\n"); >> + >> + for (i = 0; i < data.non_big_joiner_output_count; i++) { >> + uint64_t num_combinations = 0; >> + Combination combinations[MAX_COMBINATIONS]; >> + >> + generate_combinations(i+1, data.n_pipes, BIG_JOINER, >> combinations, &num_combinations); >> + igt_info("Number of combinations for %d outputs and %d >> pipes are %ld\n", >> + i+1, data.n_pipes, num_combinations); >> + >> + if (num_combinations > 0) >> + igt_dynamic_f("%dx-joiner", i+1) >> + test_basic_modeset(&data, i+1, combinations, >> num_combinations, true); >> + else >> + break; >> } >> + } >> - if(valid_output > 1) { >> - for (i = 0; i < data.n_pipes - 1; i++) { >> - igt_output_t *first_output = NULL, *second_output = >> NULL; >> - >> - data.pipe1 = pipe_seq[i]; >> - data.pipe2 = pipe_seq[i + 1]; >> - >> - igt_display_reset(&data.display); >> - for_each_connected_output(&data.display, output) { >> - if (data.output[0].output_id == output->id) { >> - first_output = output; >> - mode = data.output[0].mode; >> + igt_subtest_with_dynamic("invalid-modeset") { >> + igt_require_f(data.big_joiner_output_count > 0, "Big joiner >> output not found\n"); >> + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are >> required\n"); >> - igt_output_set_pipe(output, data.pipe1); >> - igt_output_override_mode(output, &mode); >> - } else if (second_output == NULL) { >> - second_output = output; >> - igt_output_set_pipe(output, data.pipe2); >> + if (data.big_joiner_output_count >= 1) >> + igt_dynamic_f("big_joiner_on_last_pipe") >> + tets_big_joiner_on_last_pipe(&data, false); >> - break; >> - } >> - } >> + if (data.big_joiner_output_count > 1) >> + igt_dynamic_f("invalid_combinations") >> + test_invalid_modeset_two_joiner(&data, false, false); >> - igt_dynamic_f("pipe-%s-%s-pipe-%s-%s", >> - kmstest_pipe_name(data.pipe1), >> - igt_output_name(first_output), >> - kmstest_pipe_name(data.pipe2), >> - igt_output_name(second_output)) >> - test_invalid_modeset(&data); >> - } >> + if (data.big_joiner_output_count == 1 && >> data.non_big_joiner_output_count > 0) { >> + data.combined_outputs[data.combined_output_count++] = >> data.big_joiner_outputs[0]; >> + data.combined_outputs[data.combined_output_count++] = >> data.non_big_joiner_outputs[0]; > > Probably, move this logic to igt_fixture & use as: > if (data.combined_output_count) Sure > >> + test_invalid_modeset_two_joiner(&data, false, true); > > igt_dynamic() is missing. Ahh, thanks for the catch. > > - Bhanu > >> } >> } >> - igt_describe("Verify simultaneous modeset on 2 big joiner >> outputs"); >> - igt_subtest_with_dynamic("2x-modeset") { >> - igt_require_f(count > 1, "2 outputs with big joiner modes >> are required\n"); >> - igt_require_f(data.n_pipes > 3, "Minumum of 4 pipes are >> required\n"); >> - for (i = 0; (i + 2) < data.n_pipes - 1; i++) { >> - data.pipe1 = pipe_seq[i]; >> - data.pipe2 = pipe_seq[i + 2]; >> - igt_dynamic_f("pipe-%s-%s", >> kmstest_pipe_name(pipe_seq[i]), kmstest_pipe_name(pipe_seq[i + 2])) >> - test_dual_display(&data); >> - } >> + igt_subtest_with_dynamic("force-joiner-invalid-modeset") { >> + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >> >= 11, >> + "force joiner not supported on this >> platform\n"); >> + igt_require_f(data.non_big_joiner_output_count > 0, "Non big >> joiner output not found\n"); >> + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are >> required\n"); >> + >> + if (data.non_big_joiner_output_count >= 1) >> + igt_dynamic_f("big_joiner_on_last_pipe") >> + tets_big_joiner_on_last_pipe(&data, true); >> + >> + if (data.non_big_joiner_output_count > 1) >> + igt_dynamic_f("invalid_combinations") >> + test_invalid_modeset_two_joiner(&data, true, false); >> } >> igt_fixture { >> - igt_remove_fb(data.drm_fd, &data.fb); >> igt_display_fini(&data.display); >> drm_close_driver(data.drm_fd); >> } Thanks and Regards Kunal Joshi ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner 2024-03-05 11:44 ` Modem, Bhanuprakash 2024-03-05 13:14 ` Joshi, Kunal1 @ 2024-03-05 17:34 ` Kamil Konieczny 1 sibling, 0 replies; 14+ messages in thread From: Kamil Konieczny @ 2024-03-05 17:34 UTC (permalink / raw) To: igt-dev; +Cc: Modem, Bhanuprakash, Kunal Joshi, Karthik B S Hi Modem,, On 2024-03-05 at 17:14:27 +0530, Modem, Bhanuprakash wrote: > Hi Kunal, > > On 03-03-2024 10:52 pm, Kunal Joshi wrote: > > big joiner outputs are statically assigned to pipe, > > assign dynamically also add support for forcing > > joiner, support for forcing joiner was introduced with > > below kmd patch > > > > drm/i915: Add bigjoiner force enable option to debugfs > > > > Cc: Karthik B S <karthik.b.s@intel.com> > > Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> > > Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> > > --- > > tests/intel/kms_big_joiner.c | 494 +++++++++++++++++++---------------- > > 1 file changed, 270 insertions(+), 224 deletions(-) > > > > diff --git a/tests/intel/kms_big_joiner.c b/tests/intel/kms_big_joiner.c > > index 28678b958..a4f6b8782 100644 > > --- a/tests/intel/kms_big_joiner.c > > +++ b/tests/intel/kms_big_joiner.c > > @@ -1,27 +1,6 @@ > > +/* SPDX-License-Identifier: MIT */ > > /* > > - * Copyright © 2020 Intel Corporation > > - * > > - * Permission is hereby granted, free of charge, to any person obtaining a > > - * copy of this software and associated documentation files (the "Software"), > > - * to deal in the Software without restriction, including without limitation > > - * the rights to use, copy, modify, merge, publish, distribute, sublicense, > > - * and/or sell copies of the Software, and to permit persons to whom the > > - * Software is furnished to do so, subject to the following conditions: > > - * > > - * The above copyright notice and this permission notice (including the next > > - * paragraph) shall be included in all copies or substantial portions of the > > - * Software. > > - * > > - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > > - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > > - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS > > - * IN THE SOFTWARE. > > - * > > - * Author: > > - * Karthik B S <karthik.b.s@intel.com> > > + * Copyright © 2024 Intel Corporation > > I think, we don't need to touch the license part. > > @kmail JFYI > We useally do not touch existing licence, you could consider adding 2024 year to it if you make much changes. Regards, Kamil > > */ > > /** > > @@ -37,22 +16,36 @@ > > #include "igt.h" > > /** > > - * SUBTEST: invalid-modeset > > - * Description: Verify if the modeset on the adjoining pipe is rejected when > > - * the pipe is active with a big joiner modeset > > - * > > * SUBTEST: basic > > * Description: Verify the basic modeset on big joiner mode on all pipes > > * > > - * SUBTEST: 2x-modeset > > - * Description: Verify simultaneous modeset on 2 big joiner outputs > > + * SUBTEST: force-joiner-basic > > + * Description: Verify the basic modeset on force joiner mode on all pipes > > + * > > + * SUBTEST: invalid-modeset > > + * Description: Verify the invalid modeset on big joiner mode on all pipes > > + * > > + * SUBTEST: force-joiner-invalid-modeset > > + * Description: Verify the invalid modeset on force joiner mode on all pipes > > */ > > +IGT_TEST_DESCRIPTION("Test big joiner / force joiner"); > > -IGT_TEST_DESCRIPTION("Test big joiner"); > > +#define MAX_OUTPUTS 256 > > +#define MAX_COMBINATIONS 1000 > > +#define INVALID_TEST_OUTPUT 2 > > +typedef struct { > > + int combination[MAX_OUTPUTS]; > > +} Combination; > > -struct bigjoiner_output { > > - uint32_t output_id; > > - drmModeModeInfo mode; > > +enum tests { > > + BASIC, > > + INVALID_MODESET, > > + INVALID, > > +}; > > + > > +enum joiner_type { > > + BIG_JOINER = 1 << 1, > > + INVALID_JOINER = -1, > > }; > > typedef struct { > > @@ -60,273 +53,326 @@ typedef struct { > > igt_display_t display; > > struct igt_fb fb; > > int n_pipes; > > - enum pipe pipe1; > > - enum pipe pipe2; > > - struct bigjoiner_output output[2]; > > + uint64_t big_joiner_outputs[IGT_MAX_PIPES]; > > + uint64_t non_big_joiner_outputs[IGT_MAX_PIPES]; > > + uint64_t combined_outputs[IGT_MAX_PIPES]; > > + int big_joiner_output_count; > > + int non_big_joiner_output_count; > > + int combined_output_count; > > + int output_count; > > + enum pipe pipe_seq[IGT_MAX_PIPES]; > > } data_t; > > static int max_dotclock; > > -static void test_invalid_modeset(data_t *data) > > +static bool output_supports_force_joiner(igt_output_t *output) > > { > > - igt_output_t *output; > > - igt_display_t *display = &data->display; > > - int ret; > > + return output->config.connector->connector_type == > > + DRM_MODE_CONNECTOR_DisplayPort || > > + output->config.connector->connector_type == > > + DRM_MODE_CONNECTOR_eDP; > > +} > > I think, this is not a source of truth. Perhaps, you can just check if > debugfs is present or not. > > > - igt_info("Bigjoiner test on "); > > - for_each_connected_output(display, output){ > > - enum pipe p = output->pending_pipe; > > - drmModeModeInfo *mode; > > - igt_pipe_t *pipe; > > - igt_plane_t *plane; > > +static void generate_combinations(int output_count, int pipe_count, > > + int pipes_per_output, > > + Combination combinations[MAX_COMBINATIONS], > > + uint64_t *num_combinations) > > If possible, can you please add some documentation? I am not able to > understand this logic. > > > +{ > > + int i, index; > > + int current_combination[MAX_OUTPUTS]; > > - if (p == PIPE_NONE) > > - continue; > > + for (i = 0; i < output_count; ++i) > > + current_combination[i] = i * pipes_per_output; > > - mode = igt_output_get_mode(output); > > - igt_info("pipe:%s, output:%s, mode:", kmstest_pipe_name(p), igt_output_name(output)); > > - kmstest_dump_mode(mode); > > + while (current_combination[0] <= pipe_count - output_count * pipes_per_output) { > > + for (i = 0; i < output_count; ++i) > > + combinations[*num_combinations].combination[i] = current_combination[i]; > > - pipe = &display->pipes[p]; > > - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); > > + (*num_combinations)++; > > - igt_plane_set_fb(plane, &data->fb); > > - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); > > - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); > > - } > > + index = output_count - 1; > > + while (index >= 0 && current_combination[index] == pipe_count - (output_count - index) * pipes_per_output) > > + index--; > > - igt_assert(!igt_check_bigjoiner_support(display)); > > + if (index < 0) > > + break; > > - /* This commit is expectd to fail as this pipe is being used for big joiner */ > > - ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | > > - DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); > > + current_combination[index]++; > > + for (i = index + 1; i < output_count; ++i) > > + current_combination[i] = current_combination[i - 1] + pipes_per_output; > > + } > > +} > > - igt_display_reset(&data->display); > > - igt_display_commit2(display, COMMIT_ATOMIC); > > +static igt_output_t *get_output_by_id(data_t *data, uint64_t output_id) > > +{ > > + igt_output_t *output; > > - igt_assert_lt(ret, 0); > > + for_each_connected_output(&data->display, output) { > > + if (output->id == output_id) > > + return output; > > + } > > + igt_assert("Output not found\n"); > > igt_assert without condition? > > > + return NULL; > > } > > -static void test_basic_modeset(data_t *data) > > +static void test_invalid_modeset_two_joiner(data_t *data, bool force_joiner, > > + bool combined) > > { > > + int i, j, ret; > > + igt_output_t *output; > > + uint64_t *outputs; > > + igt_plane_t *primary[INVALID_TEST_OUTPUT]; > > + igt_fb_t fb[INVALID_TEST_OUTPUT]; > > drmModeModeInfo *mode; > > - igt_output_t *output, *bigjoiner_output = NULL; > > - igt_display_t *display = &data->display; > > - igt_pipe_t *pipe; > > - igt_plane_t *plane; > > - > > - igt_display_reset(display); > > - for_each_connected_output(display, output) { > > - if (data->output[0].output_id == output->id) { > > - bigjoiner_output = output; > > - break; > > + outputs = force_joiner ? data->non_big_joiner_outputs : > > + combined ? data->combined_outputs : data->big_joiner_outputs; > > + > > + for (i = 0; i < data->n_pipes-1; i++) { > > + igt_display_reset(&data->display); > > + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { > > + output = get_output_by_id(data, outputs[j]); > > + igt_assert(output); > > + if (force_joiner) { > > + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); > > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); > > + } > > + igt_output_set_pipe(output, data->pipe_seq[i + j]); > > + mode = igt_output_get_mode(output); > > + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d%s", > > + kmstest_pipe_name(data->pipe_seq[i + j]), > > + igt_output_name(output), mode->hdisplay, > > + mode->vdisplay, mode->vrefresh, > > + j == INVALID_TEST_OUTPUT - 1 ? "\n" : ", "); > > + primary[j] = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); > > + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, > > + DRM_FORMAT_MOD_LINEAR, &fb[j]); > > + igt_plane_set_fb(primary[j], &fb[j]); > > + } > > + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); > > + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); > > + if (force_joiner) { > > + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { > > + output = get_output_by_id(data, outputs[j]); > > + igt_assert(output); > > + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); > > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 0); > > + } > > } > > } > > - > > - igt_output_set_pipe(bigjoiner_output, data->pipe1); > > - > > - mode = &data->output[0].mode; > > - igt_output_override_mode(bigjoiner_output, mode); > > - > > - pipe = &display->pipes[data->pipe1]; > > - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); > > - > > - igt_plane_set_fb(plane, &data->fb); > > - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); > > - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); > > - > > - igt_display_commit2(display, COMMIT_ATOMIC); > > - > > - igt_output_set_pipe(bigjoiner_output, PIPE_NONE); > > - igt_plane_set_fb(plane, NULL); > > - igt_display_commit2(display, COMMIT_ATOMIC); > > } > > -static void test_dual_display(data_t *data) > > +static void tets_big_joiner_on_last_pipe(data_t *data, bool force_joiner) > > { > > + int i, len, ret; > > + uint64_t *outputs; > > + igt_output_t *output; > > + igt_plane_t *primary; > > + igt_fb_t fb; > > drmModeModeInfo *mode; > > - igt_output_t *output, *bigjoiner_output[2]; > > - igt_display_t *display = &data->display; > > - igt_pipe_t *pipe; > > - igt_plane_t *plane1, *plane2; > > - int count = 0; > > - igt_display_reset(display); > > + len = force_joiner ? data->non_big_joiner_output_count : data->big_joiner_output_count; > > + outputs = force_joiner ? data->non_big_joiner_outputs : data->big_joiner_outputs; > > - for_each_connected_output(display, output) { > > - if (data->output[count].output_id == output->id) { > > - bigjoiner_output[count] = output; > > - count++; > > + for (i = 0; i < len; i++) { > > + igt_display_reset(&data->display); > > + output = get_output_by_id(data, outputs[i]); > > + if (force_joiner) { > > + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); > > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); > > } > > - > > - if (count > 1) > > - break; > > + igt_output_set_pipe(output, data->pipe_seq[data->n_pipes - 1]); > > + mode = igt_output_get_mode(output); > > + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d\n", > > + kmstest_pipe_name(data->pipe_seq[data->n_pipes - 1]), > > + igt_output_name(output), mode->hdisplay, > > + mode->vdisplay, mode->vrefresh); > > + primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); > > + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, > > + DRM_FORMAT_MOD_LINEAR, &fb); > > + igt_plane_set_fb(primary, &fb); > > + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); > > + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); > > } > > + if (force_joiner) { > > + for (i = 0; i < len; i++) { > > + output = get_output_by_id(data, outputs[i]); > > + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); > > + } > > + } > > +} > > - igt_output_set_pipe(bigjoiner_output[0], data->pipe1); > > - igt_output_set_pipe(bigjoiner_output[1], data->pipe2); > > - > > - /* Set up first big joiner output on Pipe A*/ > > - mode = &data->output[0].mode; > > - igt_output_override_mode(bigjoiner_output[0], mode); > > - > > - pipe = &display->pipes[data->pipe1]; > > - plane1 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); > > - > > - igt_plane_set_fb(plane1, &data->fb); > > - igt_fb_set_size(&data->fb, plane1, mode->hdisplay, mode->vdisplay); > > - igt_plane_set_size(plane1, mode->hdisplay, mode->vdisplay); > > - > > - /* Set up second big joiner output on Pipe C*/ > > - mode = &data->output[1].mode; > > - igt_output_override_mode(bigjoiner_output[1], mode); > > - > > - pipe = &display->pipes[data->pipe2]; > > - plane2 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); > > - > > - igt_plane_set_fb(plane2, &data->fb); > > - igt_fb_set_size(&data->fb, plane2, mode->hdisplay, mode->vdisplay); > > - igt_plane_set_size(plane2, mode->hdisplay, mode->vdisplay); > > - > > - igt_display_commit2(display, COMMIT_ATOMIC); > > +static void test_basic_modeset(data_t *data, int num_outputs, > > + Combination combinations[MAX_COMBINATIONS], > > + uint64_t num_combinations, bool force_joiner) > > +{ > > + int i, j, ret; > > + igt_display_t *display = &data->display; > > + igt_output_t *output[num_outputs]; > > + igt_plane_t *primary[num_outputs]; > > + igt_fb_t fb[num_outputs]; > > + drmModeModeInfo *mode; > > - /* Clean up */ > > - igt_output_set_pipe(bigjoiner_output[0], PIPE_NONE); > > - igt_output_set_pipe(bigjoiner_output[1], PIPE_NONE); > > - igt_plane_set_fb(plane1, NULL); > > - igt_plane_set_fb(plane2, NULL); > > - igt_display_commit2(display, COMMIT_ATOMIC); > > + for (i = 0; i < num_combinations; i++) { > > + igt_display_reset(display); > > + for (j = 0; j < num_outputs; j++) { > > + output[j] = get_output_by_id(data, > > + force_joiner ? > > + data->non_big_joiner_outputs[j] : > > + data->big_joiner_outputs[j]); > > + if (force_joiner) { > > + igt_force_bigjoiner_enable(data->drm_fd, > > + output[j]->name, true); > > Do we need to check the sysfs write status? since this helper has the return > type as non-void. > > > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, > > + output[j]->name) == 1); > > + } > > + igt_info("Assigning pipe %d to %s%s", > > + data->pipe_seq[combinations[i].combination[j]], > > Let's print the pipe name which is more redable than index. > > > + output[j]->name, j == num_outputs - 1 ? "\n" : ", "); > > + igt_output_set_pipe(output[j], data->pipe_seq[combinations[i].combination[j]]); > > + primary[j] = igt_output_get_plane_type(output[j], DRM_PLANE_TYPE_PRIMARY); > > + mode = igt_output_get_mode(output[j]); > > + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, > > + DRM_FORMAT_MOD_LINEAR, &fb[j]); > > + igt_plane_set_fb(primary[j], &fb[j]); > > + } > > + ret = igt_display_try_commit2(display, COMMIT_ATOMIC); > > + if (ret == 0) > > + igt_display_commit2(display, COMMIT_ATOMIC); > > This commit is not required. > > > + else > > + igt_assert_f(ret == 0, "Commit failed\n"); > > + > > + if (force_joiner) { > > + for (j = 0; j < num_outputs; j++) { > > + igt_force_bigjoiner_enable(data->drm_fd, output[j]->name, false); > > + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output[j]->name) == 0); > > + } > > + } > > + } > > } > > igt_main > > { > > + int i, j; > > data_t data; > > igt_output_t *output; > > - drmModeModeInfo mode; > > - int valid_output = 0, i, count = 0, j = 0; > > - uint16_t width = 0, height = 0; > > - enum pipe pipe_seq[IGT_MAX_PIPES]; > > + i = j = 0; > > igt_fixture { > > data.drm_fd = drm_open_driver_master(DRIVER_INTEL | DRIVER_XE); > > kmstest_set_vt_graphics_mode(); > > - > > igt_display_require(&data.display, data.drm_fd); > > igt_require(data.display.is_atomic); > > - > > max_dotclock = igt_get_max_dotclock(data.drm_fd); > > + data.big_joiner_output_count = 0; > > + data.non_big_joiner_output_count = 0; > > + data.combined_output_count = 0; > > + data.output_count = 0; > > for_each_connected_output(&data.display, output) { > > bool found = false; > > drmModeConnector *connector = output->config.connector; > > - > > - /* > > - * Bigjoiner will come in to the picture when the > > - * resolution > 5K or clock > max-dot-clock. > > - */ > > found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock); > > - > > if (found) { > > - data.output[count].output_id = output->id; > > - memcpy(&data.output[count].mode, &mode, sizeof(drmModeModeInfo)); > > - count++; > > - > > - width = max(width, mode.hdisplay); > > - height = max(height, mode.vdisplay); > > + data.big_joiner_outputs[data.big_joiner_output_count++] = output->id; > > + igt_output_override_mode(output, &connector->modes[0]); > > + } else { > > + if (output_supports_force_joiner(output)) { > > + data.non_big_joiner_outputs[data.non_big_joiner_output_count++] = output->id; > > + igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc); > > Do we really need to sort the connector modes? > > > + igt_output_override_mode(output, &connector->modes[0]); > > + } > > } > > - valid_output++; > > + data.output_count++; > > } > > data.n_pipes = 0; > > for_each_pipe(&data.display, i) { > > data.n_pipes++; > > - pipe_seq[j] = i; > > + data.pipe_seq[j] = i; > > j++; > > } > > - > > - igt_require_f(count > 0, "No output with 5k+ mode (or) clock > max-dot-clock found\n"); > > - > > - igt_create_pattern_fb(data.drm_fd, width, height, DRM_FORMAT_XRGB8888, > > - DRM_FORMAT_MOD_LINEAR, &data.fb); > > } > > igt_describe("Verify the basic modeset on big joiner mode on all pipes"); > > igt_subtest_with_dynamic("basic") { > > - for (i = 0; i < data.n_pipes - 1; i++) { > > - data.pipe1 = pipe_seq[i]; > > - igt_dynamic_f("pipe-%s", kmstest_pipe_name(pipe_seq[i])) > > - test_basic_modeset(&data); > > + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); > > + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); > > + > > + for (i = 0; i < data.big_joiner_output_count; i++) { > > + uint64_t num_combinations = 0; > > + Combination combinations[MAX_COMBINATIONS]; > > + > > + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); > > + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", > > + i+1, data.n_pipes, num_combinations); > > + > > + if (num_combinations > 0) > > + igt_dynamic_f("%dx-big-joiner", i+1) > > + test_basic_modeset(&data, i+1, combinations, num_combinations, false); > > + else > > + break; > > IMHO, we need to split this patch into 2: > 1- Rewamp existing subtests > 2- Add new subtests for forcejoiner > > > } > > } > > - igt_describe("Verify if the modeset on the adjoining pipe is rejected " > > - "when the pipe is active with a big joiner modeset"); > > - igt_subtest_with_dynamic("invalid-modeset") { > > - data.pipe1 = pipe_seq[j - 1]; > > - > > - igt_display_reset(&data.display); > > - for_each_connected_output(&data.display, output) { > > - if (data.output[0].output_id != output->id) > > - continue; > > - > > - mode = data.output[0].mode; > > - igt_output_set_pipe(output, data.pipe1); > > - igt_output_override_mode(output, &mode); > > - > > - igt_dynamic_f("pipe-%s-%s", > > - kmstest_pipe_name(data.pipe1), > > - igt_output_name(output)) > > - test_invalid_modeset(&data); > > + igt_describe("Verify the basic modeset on big joiner mode on all pipes"); > > + igt_subtest_with_dynamic("force-joiner-basic") { > > + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >= 11, > > + "force joiner not supported on this platform\n"); > > + igt_require_f(data.non_big_joiner_output_count > 0, "Big joiner output not found\n"); > > + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); > > + > > + for (i = 0; i < data.non_big_joiner_output_count; i++) { > > + uint64_t num_combinations = 0; > > + Combination combinations[MAX_COMBINATIONS]; > > + > > + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); > > + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", > > + i+1, data.n_pipes, num_combinations); > > + > > + if (num_combinations > 0) > > + igt_dynamic_f("%dx-joiner", i+1) > > + test_basic_modeset(&data, i+1, combinations, num_combinations, true); > > + else > > + break; > > } > > + } > > - if(valid_output > 1) { > > - for (i = 0; i < data.n_pipes - 1; i++) { > > - igt_output_t *first_output = NULL, *second_output = NULL; > > - > > - data.pipe1 = pipe_seq[i]; > > - data.pipe2 = pipe_seq[i + 1]; > > - > > - igt_display_reset(&data.display); > > - for_each_connected_output(&data.display, output) { > > - if (data.output[0].output_id == output->id) { > > - first_output = output; > > - mode = data.output[0].mode; > > + igt_subtest_with_dynamic("invalid-modeset") { > > + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); > > + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); > > - igt_output_set_pipe(output, data.pipe1); > > - igt_output_override_mode(output, &mode); > > - } else if (second_output == NULL) { > > - second_output = output; > > - igt_output_set_pipe(output, data.pipe2); > > + if (data.big_joiner_output_count >= 1) > > + igt_dynamic_f("big_joiner_on_last_pipe") > > + tets_big_joiner_on_last_pipe(&data, false); > > - break; > > - } > > - } > > + if (data.big_joiner_output_count > 1) > > + igt_dynamic_f("invalid_combinations") > > + test_invalid_modeset_two_joiner(&data, false, false); > > - igt_dynamic_f("pipe-%s-%s-pipe-%s-%s", > > - kmstest_pipe_name(data.pipe1), > > - igt_output_name(first_output), > > - kmstest_pipe_name(data.pipe2), > > - igt_output_name(second_output)) > > - test_invalid_modeset(&data); > > - } > > + if (data.big_joiner_output_count == 1 && data.non_big_joiner_output_count > 0) { > > + data.combined_outputs[data.combined_output_count++] = data.big_joiner_outputs[0]; > > + data.combined_outputs[data.combined_output_count++] = data.non_big_joiner_outputs[0]; > > Probably, move this logic to igt_fixture & use as: > if (data.combined_output_count) > > > + test_invalid_modeset_two_joiner(&data, false, true); > > igt_dynamic() is missing. > > - Bhanu > > > } > > } > > - igt_describe("Verify simultaneous modeset on 2 big joiner outputs"); > > - igt_subtest_with_dynamic("2x-modeset") { > > - igt_require_f(count > 1, "2 outputs with big joiner modes are required\n"); > > - igt_require_f(data.n_pipes > 3, "Minumum of 4 pipes are required\n"); > > - for (i = 0; (i + 2) < data.n_pipes - 1; i++) { > > - data.pipe1 = pipe_seq[i]; > > - data.pipe2 = pipe_seq[i + 2]; > > - igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe_seq[i]), kmstest_pipe_name(pipe_seq[i + 2])) > > - test_dual_display(&data); > > - } > > + igt_subtest_with_dynamic("force-joiner-invalid-modeset") { > > + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >= 11, > > + "force joiner not supported on this platform\n"); > > + igt_require_f(data.non_big_joiner_output_count > 0, "Non big joiner output not found\n"); > > + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); > > + > > + if (data.non_big_joiner_output_count >= 1) > > + igt_dynamic_f("big_joiner_on_last_pipe") > > + tets_big_joiner_on_last_pipe(&data, true); > > + > > + if (data.non_big_joiner_output_count > 1) > > + igt_dynamic_f("invalid_combinations") > > + test_invalid_modeset_two_joiner(&data, true, false); > > } > > igt_fixture { > > - igt_remove_fb(data.drm_fd, &data.fb); > > igt_display_fini(&data.display); > > drm_close_driver(data.drm_fd); > > } ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH i-g-t 4/4] tests/intel-ci/fast-feedback: HAX PATCH DO NOT MERGE 2024-03-03 17:22 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi ` (2 preceding siblings ...) 2024-03-03 17:22 ` [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner Kunal Joshi @ 2024-03-03 17:22 ` Kunal Joshi 2024-03-03 17:46 ` ✓ CI.xeBAT: success for revamp big joiner test (rev3) Patchwork 2024-03-03 18:07 ` ✗ Fi.CI.BAT: failure " Patchwork 5 siblings, 0 replies; 14+ messages in thread From: Kunal Joshi @ 2024-03-03 17:22 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi Just for testing Do not merge Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- tests/intel-ci/fast-feedback.testlist | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist index be0965110..06863f1a2 100644 --- a/tests/intel-ci/fast-feedback.testlist +++ b/tests/intel-ci/fast-feedback.testlist @@ -1,6 +1,11 @@ # Try to load the driver if it's not available yet. igt@i915_module_load@load +#HAX PATCH DO NOT MERGE +igt@kms_big_joiner@basic +igt@kms_big_joiner@force-joiner-basic +igt@kms_big_joiner@invalid-modeset +igt@kms_big_joiner@force-joiner-invalid-modeset # Keep alphabetically sorted by default igt@core_auth@basic-auth igt@debugfs_test@read_all_entries -- 2.25.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* ✓ CI.xeBAT: success for revamp big joiner test (rev3) 2024-03-03 17:22 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi ` (3 preceding siblings ...) 2024-03-03 17:22 ` [PATCH i-g-t 4/4] tests/intel-ci/fast-feedback: HAX PATCH DO NOT MERGE Kunal Joshi @ 2024-03-03 17:46 ` Patchwork 2024-03-03 18:07 ` ✗ Fi.CI.BAT: failure " Patchwork 5 siblings, 0 replies; 14+ messages in thread From: Patchwork @ 2024-03-03 17:46 UTC (permalink / raw) To: Kunal Joshi; +Cc: igt-dev [-- Attachment #1: Type: text/plain, Size: 5103 bytes --] == Series Details == Series: revamp big joiner test (rev3) URL : https://patchwork.freedesktop.org/series/130572/ State : success == Summary == CI Bug Log - changes from XEIGT_7742_BAT -> XEIGTPW_10766_BAT ==================================================== Summary ------- **SUCCESS** No regressions found. Participating hosts (4 -> 4) ------------------------------ No changes in participating hosts Known issues ------------ Here are the changes found in XEIGTPW_10766_BAT that come from known issues: ### IGT changes ### #### Issues hit #### * igt@kms_addfb_basic@invalid-set-prop-any: - bat-atsm-2: NOTRUN -> [SKIP][1] ([i915#6077]) +30 other tests skip [1]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_addfb_basic@invalid-set-prop-any.html * igt@kms_cursor_legacy@basic-flip-after-cursor-atomic: - bat-atsm-2: NOTRUN -> [SKIP][2] ([Intel XE#1024] / [Intel XE#782]) +5 other tests skip [2]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html * igt@kms_dsc@dsc-basic: - bat-atsm-2: NOTRUN -> [SKIP][3] ([Intel XE#1024] / [Intel XE#784]) [3]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_dsc@dsc-basic.html * igt@kms_flip@basic-flip-vs-modeset: - bat-atsm-2: NOTRUN -> [SKIP][4] ([Intel XE#1024] / [Intel XE#947]) +3 other tests skip [4]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_flip@basic-flip-vs-modeset.html * igt@kms_force_connector_basic@force-connector-state: - bat-atsm-2: NOTRUN -> [SKIP][5] ([Intel XE#540]) +3 other tests skip [5]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_force_connector_basic@force-connector-state.html * igt@kms_frontbuffer_tracking@basic: - bat-atsm-2: NOTRUN -> [SKIP][6] ([Intel XE#1024] / [Intel XE#783]) [6]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_frontbuffer_tracking@basic.html * igt@kms_pipe_crc_basic@nonblocking-crc: - bat-atsm-2: NOTRUN -> [SKIP][7] ([i915#1836]) +6 other tests skip [7]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_pipe_crc_basic@nonblocking-crc.html * igt@kms_prop_blob@basic: - bat-atsm-2: NOTRUN -> [SKIP][8] ([Intel XE#780]) [8]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_prop_blob@basic.html * igt@kms_psr@psr-primary-page-flip: - bat-atsm-2: NOTRUN -> [SKIP][9] ([Intel XE#1024]) +2 other tests skip [9]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@kms_psr@psr-primary-page-flip.html * igt@xe_exec_fault_mode@twice-userptr-rebind-prefetch: - bat-atsm-2: NOTRUN -> [SKIP][10] ([Intel XE#288]) +22 other tests skip [10]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@xe_exec_fault_mode@twice-userptr-rebind-prefetch.html * igt@xe_huc_copy@huc_copy: - bat-atsm-2: NOTRUN -> [SKIP][11] ([Intel XE#255]) [11]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@xe_huc_copy@huc_copy.html * igt@xe_pat@pat-index-xe2: - bat-atsm-2: NOTRUN -> [SKIP][12] ([Intel XE#977]) [12]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@xe_pat@pat-index-xe2.html * igt@xe_pat@pat-index-xehpc: - bat-atsm-2: NOTRUN -> [SKIP][13] ([Intel XE#979]) +1 other test skip [13]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/bat-atsm-2/igt@xe_pat@pat-index-xehpc.html [Intel XE#1024]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1024 [Intel XE#255]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/255 [Intel XE#288]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/288 [Intel XE#540]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/540 [Intel XE#780]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/780 [Intel XE#782]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/782 [Intel XE#783]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/783 [Intel XE#784]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/784 [Intel XE#947]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/947 [Intel XE#977]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/977 [Intel XE#979]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/979 [i915#1836]: https://gitlab.freedesktop.org/drm/intel/issues/1836 [i915#6077]: https://gitlab.freedesktop.org/drm/intel/issues/6077 Build changes ------------- * IGT: IGT_7742 -> IGTPW_10766 * Linux: xe-886-320f2374b2d52629a6a52c6c3059f02efd73c0a5 -> xe-889-511ffdbe886328239e946608243048f8296fa095 IGTPW_10766: 10766 IGT_7742: 7742 xe-886-320f2374b2d52629a6a52c6c3059f02efd73c0a5: 320f2374b2d52629a6a52c6c3059f02efd73c0a5 xe-889-511ffdbe886328239e946608243048f8296fa095: 511ffdbe886328239e946608243048f8296fa095 == Logs == For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_10766/index.html [-- Attachment #2: Type: text/html, Size: 6261 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* ✗ Fi.CI.BAT: failure for revamp big joiner test (rev3) 2024-03-03 17:22 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi ` (4 preceding siblings ...) 2024-03-03 17:46 ` ✓ CI.xeBAT: success for revamp big joiner test (rev3) Patchwork @ 2024-03-03 18:07 ` Patchwork 5 siblings, 0 replies; 14+ messages in thread From: Patchwork @ 2024-03-03 18:07 UTC (permalink / raw) To: Kunal Joshi; +Cc: igt-dev [-- Attachment #1: Type: text/plain, Size: 14677 bytes --] == Series Details == Series: revamp big joiner test (rev3) URL : https://patchwork.freedesktop.org/series/130572/ State : failure == Summary == CI Bug Log - changes from CI_DRM_14379 -> IGTPW_10766 ==================================================== Summary ------- **FAILURE** Serious unknown changes coming with IGTPW_10766 absolutely need to be verified manually. If you think the reported changes have nothing to do with the changes introduced in IGTPW_10766, please notify your bug team (I915-ci-infra@lists.freedesktop.org) to allow them to document this new failure mode, which will reduce false positives in CI. External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/index.html Participating hosts (39 -> 37) ------------------------------ Additional (1): fi-glk-j4005 Missing (3): bat-mtlp-8 bat-arls-2 fi-snb-2520m Possible new issues ------------------- Here are the unknown changes that may have been introduced in IGTPW_10766: ### IGT changes ### #### Possible regressions #### * igt@i915_selftest@live@hugepages: - bat-dg2-9: [PASS][1] -> [ABORT][2] [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14379/bat-dg2-9/igt@i915_selftest@live@hugepages.html [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-dg2-9/igt@i915_selftest@live@hugepages.html * igt@kms_big_joiner@basic: - bat-dg1-7: NOTRUN -> [SKIP][3] +3 other tests skip [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-dg1-7/igt@kms_big_joiner@basic.html - bat-adlp-9: NOTRUN -> [SKIP][4] +1 other test skip [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adlp-9/igt@kms_big_joiner@basic.html - bat-dg2-11: NOTRUN -> [SKIP][5] +3 other tests skip [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-dg2-11/igt@kms_big_joiner@basic.html - bat-dg2-14: NOTRUN -> [SKIP][6] +3 other tests skip [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-dg2-14/igt@kms_big_joiner@basic.html - bat-rplp-1: NOTRUN -> [SKIP][7] +1 other test skip [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-rplp-1/igt@kms_big_joiner@basic.html * {igt@kms_big_joiner@force-joiner-basic} (NEW): - bat-mtlp-6: NOTRUN -> [SKIP][8] +1 other test skip [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-mtlp-6/igt@kms_big_joiner@force-joiner-basic.html * {igt@kms_big_joiner@force-joiner-basic@1x-joiner} (NEW): - {bat-adls-6}: NOTRUN -> [FAIL][9] [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adls-6/igt@kms_big_joiner@force-joiner-basic@1x-joiner.html - bat-adlp-6: NOTRUN -> [DMESG-WARN][10] [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adlp-6/igt@kms_big_joiner@force-joiner-basic@1x-joiner.html - {bat-rpls-3}: NOTRUN -> [FAIL][11] [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-rpls-3/igt@kms_big_joiner@force-joiner-basic@1x-joiner.html - bat-adln-1: NOTRUN -> [DMESG-WARN][12] [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adln-1/igt@kms_big_joiner@force-joiner-basic@1x-joiner.html * {igt@kms_big_joiner@force-joiner-invalid-modeset} (NEW): - fi-rkl-11600: NOTRUN -> [SKIP][13] +3 other tests skip [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-rkl-11600/igt@kms_big_joiner@force-joiner-invalid-modeset.html - {bat-rpls-3}: NOTRUN -> [SKIP][14] [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-rpls-3/igt@kms_big_joiner@force-joiner-invalid-modeset.html - {bat-adls-6}: NOTRUN -> [SKIP][15] [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adls-6/igt@kms_big_joiner@force-joiner-invalid-modeset.html * {igt@kms_big_joiner@force-joiner-invalid-modeset@big_joiner_on_last_pipe} (NEW): - bat-jsl-3: NOTRUN -> [FAIL][16] [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-jsl-3/igt@kms_big_joiner@force-joiner-invalid-modeset@big_joiner_on_last_pipe.html - bat-jsl-1: NOTRUN -> [FAIL][17] [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-jsl-1/igt@kms_big_joiner@force-joiner-invalid-modeset@big_joiner_on_last_pipe.html * igt@kms_big_joiner@invalid-modeset: - bat-jsl-3: NOTRUN -> [SKIP][18] +1 other test skip [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-jsl-3/igt@kms_big_joiner@invalid-modeset.html - bat-dg2-9: NOTRUN -> [SKIP][19] +1 other test skip [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-dg2-9/igt@kms_big_joiner@invalid-modeset.html - bat-adln-1: NOTRUN -> [SKIP][20] +1 other test skip [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adln-1/igt@kms_big_joiner@invalid-modeset.html - bat-dg2-8: NOTRUN -> [SKIP][21] +1 other test skip [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-dg2-8/igt@kms_big_joiner@invalid-modeset.html - bat-adlm-1: NOTRUN -> [SKIP][22] +3 other tests skip [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adlm-1/igt@kms_big_joiner@invalid-modeset.html - bat-jsl-1: NOTRUN -> [SKIP][23] +1 other test skip [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-jsl-1/igt@kms_big_joiner@invalid-modeset.html - fi-tgl-1115g4: NOTRUN -> [SKIP][24] +3 other tests skip [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-tgl-1115g4/igt@kms_big_joiner@invalid-modeset.html - bat-arls-1: NOTRUN -> [SKIP][25] +3 other tests skip [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-arls-1/igt@kms_big_joiner@invalid-modeset.html - bat-adlp-6: NOTRUN -> [SKIP][26] +1 other test skip [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adlp-6/igt@kms_big_joiner@invalid-modeset.html #### Suppressed #### The following results come from untrusted machines, tests, or statuses. They do not affect the overall result. * igt@kms_big_joiner@invalid-modeset: - {bat-arls-4}: NOTRUN -> [SKIP][27] +1 other test skip [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-arls-4/igt@kms_big_joiner@invalid-modeset.html - {bat-adls-6}: NOTRUN -> [SKIP][28] +1 other test skip [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-adls-6/igt@kms_big_joiner@invalid-modeset.html * igt@kms_busy@basic: - {bat-rpls-3}: NOTRUN -> [SKIP][29] +2 other tests skip [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-rpls-3/igt@kms_busy@basic.html * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy: - {bat-rpls-3}: [SKIP][30] ([i915#4103]) -> [SKIP][31] +1 other test skip [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14379/bat-rpls-3/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-rpls-3/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html * igt@kms_cursor_legacy@basic-flip-after-cursor-legacy: - {bat-rpls-3}: [PASS][32] -> [SKIP][33] +5 other tests skip [32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14379/bat-rpls-3/igt@kms_cursor_legacy@basic-flip-after-cursor-legacy.html [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-rpls-3/igt@kms_cursor_legacy@basic-flip-after-cursor-legacy.html * igt@kms_dsc@dsc-basic: - {bat-rpls-3}: [SKIP][34] ([i915#3555] / [i915#3840] / [i915#9886]) -> [SKIP][35] [34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14379/bat-rpls-3/igt@kms_dsc@dsc-basic.html [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-rpls-3/igt@kms_dsc@dsc-basic.html New tests --------- New tests have been introduced between CI_DRM_14379 and IGTPW_10766: ### New IGT tests (4) ### * igt@kms_big_joiner@force-joiner-basic: - Statuses : 25 skip(s) - Exec time: [0.0] s * igt@kms_big_joiner@force-joiner-basic@1x-joiner: - Statuses : 2 dmesg-warn(s) 2 fail(s) 7 pass(s) - Exec time: [0.51, 3.75] s * igt@kms_big_joiner@force-joiner-invalid-modeset: - Statuses : 27 skip(s) - Exec time: [0.0] s * igt@kms_big_joiner@force-joiner-invalid-modeset@big_joiner_on_last_pipe: - Statuses : 2 fail(s) 7 pass(s) - Exec time: [0.03, 1.34] s Known issues ------------ Here are the changes found in IGTPW_10766 that come from known issues: ### IGT changes ### #### Issues hit #### * igt@gem_huc_copy@huc-copy: - fi-glk-j4005: NOTRUN -> [SKIP][36] ([fdo#109271] / [i915#2190]) [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-glk-j4005/igt@gem_huc_copy@huc-copy.html * igt@gem_lmem_swapping@basic: - fi-apl-guc: NOTRUN -> [SKIP][37] ([fdo#109271] / [i915#4613]) +3 other tests skip [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-apl-guc/igt@gem_lmem_swapping@basic.html - fi-glk-j4005: NOTRUN -> [SKIP][38] ([fdo#109271] / [i915#4613]) +3 other tests skip [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-glk-j4005/igt@gem_lmem_swapping@basic.html * igt@kms_big_joiner@basic: - fi-pnv-d510: NOTRUN -> [SKIP][39] ([fdo#109271]) +3 other tests skip [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-pnv-d510/igt@kms_big_joiner@basic.html - fi-skl-guc: NOTRUN -> [SKIP][40] ([fdo#109271]) +3 other tests skip [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-skl-guc/igt@kms_big_joiner@basic.html - fi-kbl-7567u: NOTRUN -> [SKIP][41] ([fdo#109271]) +3 other tests skip [41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-kbl-7567u/igt@kms_big_joiner@basic.html - fi-cfl-8700k: NOTRUN -> [SKIP][42] ([fdo#109271]) +3 other tests skip [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-cfl-8700k/igt@kms_big_joiner@basic.html - fi-bsw-nick: NOTRUN -> [SKIP][43] ([fdo#109271]) +3 other tests skip [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-bsw-nick/igt@kms_big_joiner@basic.html - bat-kbl-2: NOTRUN -> [SKIP][44] ([fdo#109271]) +3 other tests skip [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-kbl-2/igt@kms_big_joiner@basic.html * {igt@kms_big_joiner@force-joiner-invalid-modeset} (NEW): - fi-skl-6600u: NOTRUN -> [SKIP][45] ([fdo#109271]) +3 other tests skip [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-skl-6600u/igt@kms_big_joiner@force-joiner-invalid-modeset.html * igt@kms_big_joiner@invalid-modeset: - fi-cfl-guc: NOTRUN -> [SKIP][46] ([fdo#109271]) +3 other tests skip [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-cfl-guc/igt@kms_big_joiner@invalid-modeset.html - fi-kbl-x1275: NOTRUN -> [SKIP][47] ([fdo#109271]) +3 other tests skip [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-kbl-x1275/igt@kms_big_joiner@invalid-modeset.html - fi-cfl-8109u: NOTRUN -> [SKIP][48] ([fdo#109271]) +3 other tests skip [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-cfl-8109u/igt@kms_big_joiner@invalid-modeset.html - fi-ivb-3770: NOTRUN -> [SKIP][49] ([fdo#109271]) +3 other tests skip [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-ivb-3770/igt@kms_big_joiner@invalid-modeset.html - fi-elk-e7500: NOTRUN -> [SKIP][50] ([fdo#109271]) +3 other tests skip [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-elk-e7500/igt@kms_big_joiner@invalid-modeset.html - fi-kbl-guc: NOTRUN -> [SKIP][51] ([fdo#109271]) +3 other tests skip [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-kbl-guc/igt@kms_big_joiner@invalid-modeset.html - fi-ilk-650: NOTRUN -> [SKIP][52] ([fdo#109271]) +3 other tests skip [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-ilk-650/igt@kms_big_joiner@invalid-modeset.html - fi-blb-e6850: NOTRUN -> [SKIP][53] ([fdo#109271]) +3 other tests skip [53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-blb-e6850/igt@kms_big_joiner@invalid-modeset.html - bat-mtlp-6: NOTRUN -> [SKIP][54] ([i915#9792]) +1 other test skip [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/bat-mtlp-6/igt@kms_big_joiner@invalid-modeset.html * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic: - fi-glk-j4005: NOTRUN -> [SKIP][55] ([fdo#109271]) +14 other tests skip [55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-glk-j4005/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html * igt@kms_hdmi_inject@inject-audio: - fi-apl-guc: NOTRUN -> [SKIP][56] ([fdo#109271]) +21 other tests skip [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/fi-apl-guc/igt@kms_hdmi_inject@inject-audio.html {name}: This element is suppressed. This means it is ignored when computing the status of the difference (SUCCESS, WARNING, or FAILURE). [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271 [fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295 [i915#1849]: https://gitlab.freedesktop.org/drm/intel/issues/1849 [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190 [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555 [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637 [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708 [i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840 [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103 [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613 [i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354 [i915#9792]: https://gitlab.freedesktop.org/drm/intel/issues/9792 [i915#9886]: https://gitlab.freedesktop.org/drm/intel/issues/9886 [i915#9920]: https://gitlab.freedesktop.org/drm/intel/issues/9920 Build changes ------------- * CI: CI-20190529 -> None * IGT: IGT_7742 -> IGTPW_10766 CI-20190529: 20190529 CI_DRM_14379: 511ffdbe886328239e946608243048f8296fa095 @ git://anongit.freedesktop.org/gfx-ci/linux IGTPW_10766: 10766 IGT_7742: 7742 Testlist changes ---------------- +igt@kms_big_joiner@force-joiner-basic +igt@kms_big_joiner@force-joiner-invalid-modeset -igt@kms_atomic@plane-cursor-solid-fill -igt@kms_atomic@plane-primary-solid-fill -igt@kms_big_joiner@2x-modeset == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_10766/index.html [-- Attachment #2: Type: text/html, Size: 17021 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH i-g-t 0/4] revamp big joiner test @ 2024-03-01 8:25 Kunal Joshi 2024-03-01 8:26 ` [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner Kunal Joshi 0 siblings, 1 reply; 14+ messages in thread From: Kunal Joshi @ 2024-03-01 8:25 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi big joiner outputs are statically assigned to pipe, assign dynamically also add support for forcing joiner, support for forcing joiner was introduced with below kmd patch drm/i915: Add bigjoiner force enable option to debugfs Kunal Joshi (3): lib/igt_kms: move bigjoiner_mode_found to lib lib/igt_kms: add helpers to enable/disable force joiner tests/intel/kms_big_joiner: revamp kms_big_joiner tests/intel-ci/fast-feedback: HAX PATCH DO NOT MERGE lib/igt_kms.c | 73 ++++ lib/igt_kms.h | 4 + tests/intel-ci/fast-feedback.testlist | 5 + tests/intel/kms_big_joiner.c | 507 ++++++++++++++------------ 4 files changed, 355 insertions(+), 234 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner 2024-03-01 8:25 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi @ 2024-03-01 8:26 ` Kunal Joshi 0 siblings, 0 replies; 14+ messages in thread From: Kunal Joshi @ 2024-03-01 8:26 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi, Karthik B S, Bhanuprakash Modem big joiner outputs are statically assigned to pipe, assign dynamically also add support for forcing joiner, support for forcing joiner was introduced with below kmd patch drm/i915: Add bigjoiner force enable option to debugfs Cc: Karthik B S <karthik.b.s@intel.com> Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- tests/intel/kms_big_joiner.c | 497 +++++++++++++++++++---------------- 1 file changed, 274 insertions(+), 223 deletions(-) diff --git a/tests/intel/kms_big_joiner.c b/tests/intel/kms_big_joiner.c index 28678b958..4c128141c 100644 --- a/tests/intel/kms_big_joiner.c +++ b/tests/intel/kms_big_joiner.c @@ -1,27 +1,6 @@ +/* SPDX-License-Identifier: MIT */ /* - * Copyright © 2020 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Author: - * Karthik B S <karthik.b.s@intel.com> + * Copyright © 2024 Intel Corporation */ /** @@ -37,22 +16,36 @@ #include "igt.h" /** - * SUBTEST: invalid-modeset - * Description: Verify if the modeset on the adjoining pipe is rejected when - * the pipe is active with a big joiner modeset - * * SUBTEST: basic * Description: Verify the basic modeset on big joiner mode on all pipes * - * SUBTEST: 2x-modeset - * Description: Verify simultaneous modeset on 2 big joiner outputs + * SUBTEST: force-joiner-basic + * Description: Verify the basic modeset on force joiner mode on all pipes + * + * SUBTEST: invalid-modeset + * Description: Verify the invalid modeset on big joiner mode on all pipes + * + * SUBTEST: force-joiner-invalid-modeset + * Description: Verify the invalid modeset on force joiner mode on all pipes */ +IGT_TEST_DESCRIPTION("Test big joiner / force joiner"); -IGT_TEST_DESCRIPTION("Test big joiner"); +#define MAX_OUTPUTS 256 +#define MAX_COMBINATIONS 1000 +#define INVALID_TEST_OUTPUT 2 +typedef struct { + int combination[MAX_OUTPUTS]; +} Combination; -struct bigjoiner_output { - uint32_t output_id; - drmModeModeInfo mode; +enum tests { + BASIC, + INVALID_MODESET, + INVALID, +}; + +enum joiner_type { + BIG_JOINER = 1 << 1, + INVALID_JOINER = -1, }; typedef struct { @@ -60,273 +53,331 @@ typedef struct { igt_display_t display; struct igt_fb fb; int n_pipes; - enum pipe pipe1; - enum pipe pipe2; - struct bigjoiner_output output[2]; + uint64_t big_joiner_outputs[IGT_MAX_PIPES]; + uint64_t non_big_joiner_outputs[IGT_MAX_PIPES]; + uint64_t combined_outputs[IGT_MAX_PIPES]; + int big_joiner_output_count; + int non_big_joiner_output_count; + int combined_output_count; + int output_count; + enum pipe pipe_seq[IGT_MAX_PIPES]; } data_t; static int max_dotclock; -static void test_invalid_modeset(data_t *data) +static bool output_supports_force_joiner(igt_output_t *output) { - igt_output_t *output; - igt_display_t *display = &data->display; - int ret; + return output->config.connector->connector_type == + DRM_MODE_CONNECTOR_DisplayPort || + output->config.connector->connector_type == + DRM_MODE_CONNECTOR_eDP; +} - igt_info("Bigjoiner test on "); - for_each_connected_output(display, output){ - enum pipe p = output->pending_pipe; - drmModeModeInfo *mode; - igt_pipe_t *pipe; - igt_plane_t *plane; +static void generate_combinations(int output_count, int pipe_count, + int pipes_per_output, + Combination combinations[MAX_COMBINATIONS], + uint64_t *num_combinations) +{ + int i, index; + int current_combination[MAX_OUTPUTS]; - if (p == PIPE_NONE) - continue; + for (i = 0; i < output_count; ++i) + current_combination[i] = i * pipes_per_output; - mode = igt_output_get_mode(output); - igt_info("pipe:%s, output:%s, mode:", kmstest_pipe_name(p), igt_output_name(output)); - kmstest_dump_mode(mode); + while (current_combination[0] <= pipe_count - output_count * pipes_per_output) { + for (i = 0; i < output_count; ++i) + combinations[*num_combinations].combination[i] = current_combination[i]; - pipe = &display->pipes[p]; - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); + (*num_combinations)++; - igt_plane_set_fb(plane, &data->fb); - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); - } + index = output_count - 1; + while (index >= 0 && current_combination[index] == pipe_count - (output_count - index) * pipes_per_output) + index--; - igt_assert(!igt_check_bigjoiner_support(display)); + if (index < 0) + break; - /* This commit is expectd to fail as this pipe is being used for big joiner */ - ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | - DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + current_combination[index]++; + for (i = index + 1; i < output_count; ++i) + current_combination[i] = current_combination[i - 1] + pipes_per_output; + } +} - igt_display_reset(&data->display); - igt_display_commit2(display, COMMIT_ATOMIC); +static igt_output_t *get_output_by_id(data_t *data, uint64_t output_id) +{ + igt_output_t *output; - igt_assert_lt(ret, 0); + for_each_connected_output(&data->display, output) { + if (output->id == output_id) + return output; + } + igt_assert("Output not found\n"); + return NULL; } -static void test_basic_modeset(data_t *data) +static void test_invalid_modeset_two_joiner(data_t *data, bool force_joiner, + bool combined) { + int i, j, ret; + igt_output_t *output; + uint64_t *outputs; + igt_plane_t *primary[INVALID_TEST_OUTPUT]; + igt_fb_t fb[INVALID_TEST_OUTPUT]; drmModeModeInfo *mode; - igt_output_t *output, *bigjoiner_output = NULL; - igt_display_t *display = &data->display; - igt_pipe_t *pipe; - igt_plane_t *plane; - igt_display_reset(display); + outputs = force_joiner ? data->non_big_joiner_outputs : + combined ? data->combined_outputs : data->big_joiner_outputs; - for_each_connected_output(display, output) { - if (data->output[0].output_id == output->id) { - bigjoiner_output = output; - break; + igt_display_reset(&data->display); + for (i = 0; i < data->n_pipes-1; i++) { + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { + output = get_output_by_id(data, outputs[j]); + igt_assert(output); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); + } + igt_output_set_pipe(output, data->pipe_seq[i + j]); + mode = igt_output_get_mode(output); + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d%s", + kmstest_pipe_name(data->pipe_seq[i + j]), + igt_output_name(output), mode->hdisplay, + mode->vdisplay, mode->vrefresh, + j == INVALID_TEST_OUTPUT - 1 ? "\n" : ", "); + primary[j] = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb[j]); + igt_plane_set_fb(primary[j], &fb[j]); + } + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); + if (force_joiner) { + igt_display_reset(&data->display); + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { + output = get_output_by_id(data, outputs[j]); + igt_assert(output); + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 0); + } + igt_display_commit2(&data->display, COMMIT_ATOMIC); } } - - igt_output_set_pipe(bigjoiner_output, data->pipe1); - - mode = &data->output[0].mode; - igt_output_override_mode(bigjoiner_output, mode); - - pipe = &display->pipes[data->pipe1]; - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane, &data->fb); - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); - - igt_display_commit2(display, COMMIT_ATOMIC); - - igt_output_set_pipe(bigjoiner_output, PIPE_NONE); - igt_plane_set_fb(plane, NULL); - igt_display_commit2(display, COMMIT_ATOMIC); } -static void test_dual_display(data_t *data) +static void tets_big_joiner_on_last_pipe(data_t *data, bool force_joiner) { + int i, len, ret; + uint64_t *outputs; + igt_output_t *output; + igt_plane_t *primary; + igt_fb_t fb; drmModeModeInfo *mode; - igt_output_t *output, *bigjoiner_output[2]; - igt_display_t *display = &data->display; - igt_pipe_t *pipe; - igt_plane_t *plane1, *plane2; - int count = 0; - igt_display_reset(display); + len = force_joiner ? data->non_big_joiner_output_count : data->big_joiner_output_count; + outputs = force_joiner ? data->non_big_joiner_outputs : data->big_joiner_outputs; - for_each_connected_output(display, output) { - if (data->output[count].output_id == output->id) { - bigjoiner_output[count] = output; - count++; + for (i = 0; i < len; i++) { + igt_display_reset(&data->display); + output = get_output_by_id(data, outputs[i]); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); } - - if (count > 1) - break; + igt_output_set_pipe(output, data->pipe_seq[data->n_pipes - 1]); + mode = igt_output_get_mode(output); + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d\n", + kmstest_pipe_name(data->pipe_seq[data->n_pipes - 1]), + igt_output_name(output), mode->hdisplay, + mode->vdisplay, mode->vrefresh); + primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb); + igt_plane_set_fb(primary, &fb); + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); } + if (force_joiner) { + for (i = 0; i < len; i++) { + output = get_output_by_id(data, outputs[i]); + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); + } + igt_display_commit2(&data->display, COMMIT_ATOMIC); + } +} - igt_output_set_pipe(bigjoiner_output[0], data->pipe1); - igt_output_set_pipe(bigjoiner_output[1], data->pipe2); - - /* Set up first big joiner output on Pipe A*/ - mode = &data->output[0].mode; - igt_output_override_mode(bigjoiner_output[0], mode); - - pipe = &display->pipes[data->pipe1]; - plane1 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane1, &data->fb); - igt_fb_set_size(&data->fb, plane1, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane1, mode->hdisplay, mode->vdisplay); - - /* Set up second big joiner output on Pipe C*/ - mode = &data->output[1].mode; - igt_output_override_mode(bigjoiner_output[1], mode); - - pipe = &display->pipes[data->pipe2]; - plane2 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane2, &data->fb); - igt_fb_set_size(&data->fb, plane2, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane2, mode->hdisplay, mode->vdisplay); - - igt_display_commit2(display, COMMIT_ATOMIC); +static void test_basic_modeset(data_t *data, int num_outputs, + Combination combinations[MAX_COMBINATIONS], + uint64_t num_combinations, bool force_joiner) +{ + int i, j, ret; + igt_display_t *display = &data->display; + igt_output_t *output[num_outputs]; + igt_plane_t *primary[num_outputs]; + igt_fb_t fb[num_outputs]; + drmModeModeInfo *mode; - /* Clean up */ - igt_output_set_pipe(bigjoiner_output[0], PIPE_NONE); - igt_output_set_pipe(bigjoiner_output[1], PIPE_NONE); - igt_plane_set_fb(plane1, NULL); - igt_plane_set_fb(plane2, NULL); - igt_display_commit2(display, COMMIT_ATOMIC); + for (i = 0; i < num_combinations; i++) { + igt_display_reset(display); + for (j = 0; j < num_outputs; j++) { + output[j] = get_output_by_id(data, + force_joiner ? + data->non_big_joiner_outputs[j] : + data->big_joiner_outputs[j]); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, + output[j]->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, + output[j]->name) == 1); + } + igt_info("Assigning pipe %d to %s%s", + data->pipe_seq[combinations[i].combination[j]], + output[j]->name, j == num_outputs - 1 ? "\n" : ", "); + igt_output_set_pipe(output[j], data->pipe_seq[combinations[i].combination[j]]); + primary[j] = igt_output_get_plane_type(output[j], DRM_PLANE_TYPE_PRIMARY); + mode = igt_output_get_mode(output[j]); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb[j]); + igt_plane_set_fb(primary[j], &fb[j]); + } + ret = igt_display_try_commit2(display, COMMIT_ATOMIC); + if (ret == 0) + igt_display_commit2(display, COMMIT_ATOMIC); + else + igt_assert_f(ret == 0, "Commit failed\n"); + + if (force_joiner) { + for (j = 0; j < num_outputs; j++) { + igt_display_reset(display); + igt_force_bigjoiner_enable(data->drm_fd, output[j]->name, false); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output[j]->name) == 0); + igt_display_commit2(&data->display, COMMIT_ATOMIC); + } + } + } } igt_main { + int i, j; data_t data; igt_output_t *output; - drmModeModeInfo mode; - int valid_output = 0, i, count = 0, j = 0; - uint16_t width = 0, height = 0; - enum pipe pipe_seq[IGT_MAX_PIPES]; + i = j = 0; igt_fixture { data.drm_fd = drm_open_driver_master(DRIVER_INTEL | DRIVER_XE); kmstest_set_vt_graphics_mode(); - igt_display_require(&data.display, data.drm_fd); igt_require(data.display.is_atomic); - max_dotclock = igt_get_max_dotclock(data.drm_fd); + data.big_joiner_output_count = 0; + data.non_big_joiner_output_count = 0; + data.combined_output_count = 0; + data.output_count = 0; for_each_connected_output(&data.display, output) { bool found = false; drmModeConnector *connector = output->config.connector; - - /* - * Bigjoiner will come in to the picture when the - * resolution > 5K or clock > max-dot-clock. - */ found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock); - if (found) { - data.output[count].output_id = output->id; - memcpy(&data.output[count].mode, &mode, sizeof(drmModeModeInfo)); - count++; - - width = max(width, mode.hdisplay); - height = max(height, mode.vdisplay); + data.big_joiner_outputs[data.big_joiner_output_count++] = output->id; + igt_output_override_mode(output, &connector->modes[0]); + } else { + if (output_supports_force_joiner(output)) { + data.non_big_joiner_outputs[data.non_big_joiner_output_count++] = output->id; + igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc); + igt_output_override_mode(output, &connector->modes[0]); + } } - valid_output++; + data.output_count++; } data.n_pipes = 0; for_each_pipe(&data.display, i) { data.n_pipes++; - pipe_seq[j] = i; + data.pipe_seq[j] = i; j++; } - - igt_require_f(count > 0, "No output with 5k+ mode (or) clock > max-dot-clock found\n"); - - igt_create_pattern_fb(data.drm_fd, width, height, DRM_FORMAT_XRGB8888, - DRM_FORMAT_MOD_LINEAR, &data.fb); } igt_describe("Verify the basic modeset on big joiner mode on all pipes"); igt_subtest_with_dynamic("basic") { - for (i = 0; i < data.n_pipes - 1; i++) { - data.pipe1 = pipe_seq[i]; - igt_dynamic_f("pipe-%s", kmstest_pipe_name(pipe_seq[i])) - test_basic_modeset(&data); + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + for (i = 0; i < data.big_joiner_output_count; i++) { + uint64_t num_combinations = 0; + Combination combinations[MAX_COMBINATIONS]; + + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", + i+1, data.n_pipes, num_combinations); + + if (num_combinations > 0) + igt_dynamic_f("%dx-big-joiner", i+1) + test_basic_modeset(&data, i+1, combinations, num_combinations, false); + else + break; } } - igt_describe("Verify if the modeset on the adjoining pipe is rejected " - "when the pipe is active with a big joiner modeset"); - igt_subtest_with_dynamic("invalid-modeset") { - data.pipe1 = pipe_seq[j - 1]; - - igt_display_reset(&data.display); - for_each_connected_output(&data.display, output) { - if (data.output[0].output_id != output->id) - continue; - - mode = data.output[0].mode; - igt_output_set_pipe(output, data.pipe1); - igt_output_override_mode(output, &mode); - - igt_dynamic_f("pipe-%s-%s", - kmstest_pipe_name(data.pipe1), - igt_output_name(output)) - test_invalid_modeset(&data); + igt_describe("Verify the basic modeset on big joiner mode on all pipes"); + igt_subtest_with_dynamic("force-joiner-basic") { + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >= 11, + "force joiner not supported on this platform\n"); + igt_require_f(data.non_big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + for (i = 0; i < data.non_big_joiner_output_count; i++) { + uint64_t num_combinations = 0; + Combination combinations[MAX_COMBINATIONS]; + + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", + i+1, data.n_pipes, num_combinations); + + if (num_combinations > 0) + igt_dynamic_f("%dx-joiner", i+1) + test_basic_modeset(&data, i+1, combinations, num_combinations, true); + else + break; } + } - if(valid_output > 1) { - for (i = 0; i < data.n_pipes - 1; i++) { - igt_output_t *first_output = NULL, *second_output = NULL; - - data.pipe1 = pipe_seq[i]; - data.pipe2 = pipe_seq[i + 1]; - - igt_display_reset(&data.display); - for_each_connected_output(&data.display, output) { - if (data.output[0].output_id == output->id) { - first_output = output; - mode = data.output[0].mode; + igt_subtest_with_dynamic("invalid-modeset") { + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); - igt_output_set_pipe(output, data.pipe1); - igt_output_override_mode(output, &mode); - } else if (second_output == NULL) { - second_output = output; - igt_output_set_pipe(output, data.pipe2); + if (data.big_joiner_output_count >= 1) + igt_dynamic_f("big_joiner_on_last_pipe") + tets_big_joiner_on_last_pipe(&data, false); - break; - } - } + if (data.big_joiner_output_count > 1) + igt_dynamic_f("invalid_combinations") + test_invalid_modeset_two_joiner(&data, false, false); - igt_dynamic_f("pipe-%s-%s-pipe-%s-%s", - kmstest_pipe_name(data.pipe1), - igt_output_name(first_output), - kmstest_pipe_name(data.pipe2), - igt_output_name(second_output)) - test_invalid_modeset(&data); - } + if (data.big_joiner_output_count == 1 && data.non_big_joiner_output_count > 0) { + data.combined_outputs[data.combined_output_count++] = data.big_joiner_outputs[0]; + data.combined_outputs[data.combined_output_count++] = data.non_big_joiner_outputs[0]; + test_invalid_modeset_two_joiner(&data, false, true); } } - igt_describe("Verify simultaneous modeset on 2 big joiner outputs"); - igt_subtest_with_dynamic("2x-modeset") { - igt_require_f(count > 1, "2 outputs with big joiner modes are required\n"); - igt_require_f(data.n_pipes > 3, "Minumum of 4 pipes are required\n"); - for (i = 0; (i + 2) < data.n_pipes - 1; i++) { - data.pipe1 = pipe_seq[i]; - data.pipe2 = pipe_seq[i + 2]; - igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe_seq[i]), kmstest_pipe_name(pipe_seq[i + 2])) - test_dual_display(&data); - } + igt_subtest_with_dynamic("force-joiner-invalid-modeset") { + igt_require_f(intel_display_ver(intel_get_drm_devid(data.drm_fd)) >= 11, + "force joiner not supported on this platform\n"); + igt_require_f(data.non_big_joiner_output_count > 0, "Non big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + if (data.non_big_joiner_output_count >= 1) + igt_dynamic_f("big_joiner_on_last_pipe") + tets_big_joiner_on_last_pipe(&data, true); + + if (data.non_big_joiner_output_count > 1) + igt_dynamic_f("invalid_combinations") + test_invalid_modeset_two_joiner(&data, true, false); } igt_fixture { - igt_remove_fb(data.drm_fd, &data.fb); igt_display_fini(&data.display); drm_close_driver(data.drm_fd); } -- 2.25.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH i-g-t 0/4] revamp big joiner test @ 2024-02-29 18:10 Kunal Joshi 2024-02-29 18:10 ` [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner Kunal Joshi 0 siblings, 1 reply; 14+ messages in thread From: Kunal Joshi @ 2024-02-29 18:10 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi big joiner outputs are statically assigned to pipe, assign dynamically also add support for forcing joiner, support for forcing joiner was introduced with below kmd patch drm/i915: Add bigjoiner force enable option to debugfs Kunal Joshi (4): lib/igt_kms: move bigjoiner_mode_found to lib lib/igt_kms: add helpers to enable/disable force joiner tests/intel/kms_big_joiner: revamp kms_big_joiner tests/intel-ci/fast-feedback: HAX PATCH DO NOT MERGE lib/igt_kms.c | 73 ++++ lib/igt_kms.h | 4 + tests/intel-ci/fast-feedback.testlist | 5 + tests/intel/kms_big_joiner.c | 503 ++++++++++++++------------ 4 files changed, 351 insertions(+), 234 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner 2024-02-29 18:10 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi @ 2024-02-29 18:10 ` Kunal Joshi 0 siblings, 0 replies; 14+ messages in thread From: Kunal Joshi @ 2024-02-29 18:10 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi, Karthik B S, Bhanuprakash Modem big joiner outputs are statically assigned to pipe, assign dynamically also add support for forcing joiner, support for forcing joiner was introduced with below kmd patch drm/i915: Add bigjoiner force enable option to debugfs Cc: Karthik B S <karthik.b.s@intel.com> Cc: Bhanuprakash Modem <bhanuprakash.modem@intel.com> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- tests/intel/kms_big_joiner.c | 493 +++++++++++++++++++---------------- 1 file changed, 270 insertions(+), 223 deletions(-) diff --git a/tests/intel/kms_big_joiner.c b/tests/intel/kms_big_joiner.c index 28678b958..5f5f6f6b4 100644 --- a/tests/intel/kms_big_joiner.c +++ b/tests/intel/kms_big_joiner.c @@ -1,27 +1,6 @@ +/* SPDX-License-Identifier: MIT */ /* - * Copyright © 2020 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Author: - * Karthik B S <karthik.b.s@intel.com> + * Copyright © 2024 Intel Corporation */ /** @@ -37,22 +16,36 @@ #include "igt.h" /** - * SUBTEST: invalid-modeset - * Description: Verify if the modeset on the adjoining pipe is rejected when - * the pipe is active with a big joiner modeset - * * SUBTEST: basic * Description: Verify the basic modeset on big joiner mode on all pipes * - * SUBTEST: 2x-modeset - * Description: Verify simultaneous modeset on 2 big joiner outputs + * SUBTEST: force-joiner-basic + * Description: Verify the basic modeset on force joiner mode on all pipes + * + * SUBTEST: invalid-modeset + * Description: Verify the invalid modeset on big joiner mode on all pipes + * + * SUBTEST: force-joiner-invalid-modeset + * Description: Verify the invalid modeset on force joiner mode on all pipes */ +IGT_TEST_DESCRIPTION("Test big joiner / force joiner"); -IGT_TEST_DESCRIPTION("Test big joiner"); +#define MAX_OUTPUTS 256 +#define MAX_COMBINATIONS 1000 +#define INVALID_TEST_OUTPUT 2 +typedef struct { + int combination[MAX_OUTPUTS]; +} Combination; -struct bigjoiner_output { - uint32_t output_id; - drmModeModeInfo mode; +enum tests { + BASIC, + INVALID_MODESET, + INVALID, +}; + +enum joiner_type { + BIG_JOINER = 1 << 1, + INVALID_JOINER = -1, }; typedef struct { @@ -60,273 +53,327 @@ typedef struct { igt_display_t display; struct igt_fb fb; int n_pipes; - enum pipe pipe1; - enum pipe pipe2; - struct bigjoiner_output output[2]; + uint64_t big_joiner_outputs[IGT_MAX_PIPES]; + uint64_t non_big_joiner_outputs[IGT_MAX_PIPES]; + uint64_t combined_outputs[IGT_MAX_PIPES]; + int big_joiner_output_count; + int non_big_joiner_output_count; + int combined_output_count; + int output_count; + enum pipe pipe_seq[IGT_MAX_PIPES]; } data_t; static int max_dotclock; -static void test_invalid_modeset(data_t *data) +static bool output_supports_force_joiner(igt_output_t *output) { - igt_output_t *output; - igt_display_t *display = &data->display; - int ret; + return output->config.connector->connector_type == + DRM_MODE_CONNECTOR_DisplayPort || + output->config.connector->connector_type == + DRM_MODE_CONNECTOR_eDP; +} - igt_info("Bigjoiner test on "); - for_each_connected_output(display, output){ - enum pipe p = output->pending_pipe; - drmModeModeInfo *mode; - igt_pipe_t *pipe; - igt_plane_t *plane; +static void generate_combinations(int output_count, int pipe_count, + int pipes_per_output, + Combination combinations[MAX_COMBINATIONS], + uint64_t *num_combinations) +{ + int i, index; + int current_combination[MAX_OUTPUTS]; - if (p == PIPE_NONE) - continue; + for (i = 0; i < output_count; ++i) + current_combination[i] = i * pipes_per_output; - mode = igt_output_get_mode(output); - igt_info("pipe:%s, output:%s, mode:", kmstest_pipe_name(p), igt_output_name(output)); - kmstest_dump_mode(mode); + while (current_combination[0] <= pipe_count - output_count * pipes_per_output) { + for (i = 0; i < output_count; ++i) + combinations[*num_combinations].combination[i] = current_combination[i]; - pipe = &display->pipes[p]; - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); + (*num_combinations)++; - igt_plane_set_fb(plane, &data->fb); - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); - } + index = output_count - 1; + while (index >= 0 && current_combination[index] == pipe_count - (output_count - index) * pipes_per_output) + index--; - igt_assert(!igt_check_bigjoiner_support(display)); + if (index < 0) + break; - /* This commit is expectd to fail as this pipe is being used for big joiner */ - ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | - DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + current_combination[index]++; + for (i = index + 1; i < output_count; ++i) + current_combination[i] = current_combination[i - 1] + pipes_per_output; + } +} - igt_display_reset(&data->display); - igt_display_commit2(display, COMMIT_ATOMIC); +static igt_output_t *get_output_by_id(data_t *data, uint64_t output_id) +{ + igt_output_t *output; - igt_assert_lt(ret, 0); + for_each_connected_output(&data->display, output) { + if (output->id == output_id) + return output; + } + igt_assert("Output not found\n"); + return NULL; } -static void test_basic_modeset(data_t *data) +static void test_invalid_modeset_two_joiner(data_t *data, bool force_joiner, + bool combined) { + int i, j, ret; + igt_output_t *output; + uint64_t *outputs; + igt_plane_t *primary[INVALID_TEST_OUTPUT]; + igt_fb_t fb[INVALID_TEST_OUTPUT]; drmModeModeInfo *mode; - igt_output_t *output, *bigjoiner_output = NULL; - igt_display_t *display = &data->display; - igt_pipe_t *pipe; - igt_plane_t *plane; - igt_display_reset(display); + outputs = force_joiner ? data->non_big_joiner_outputs : + combined ? data->combined_outputs : data->big_joiner_outputs; - for_each_connected_output(display, output) { - if (data->output[0].output_id == output->id) { - bigjoiner_output = output; - break; + igt_display_reset(&data->display); + for (i = 0; i < data->n_pipes-1; i++) { + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { + output = get_output_by_id(data, outputs[j]); + igt_assert(output); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); + } + igt_output_set_pipe(output, data->pipe_seq[i + j]); + mode = igt_output_get_mode(output); + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d%s", + kmstest_pipe_name(data->pipe_seq[i + j]), + igt_output_name(output), mode->hdisplay, + mode->vdisplay, mode->vrefresh, + j == INVALID_TEST_OUTPUT - 1 ? "\n" : ", "); + primary[j] = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb[j]); + igt_plane_set_fb(primary[j], &fb[j]); + } + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); + if (force_joiner) { + igt_display_reset(&data->display); + for (j = 0; j < INVALID_TEST_OUTPUT; j++) { + output = get_output_by_id(data, outputs[j]); + igt_assert(output); + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 0); + } + igt_display_commit2(&data->display, COMMIT_ATOMIC); } } - - igt_output_set_pipe(bigjoiner_output, data->pipe1); - - mode = &data->output[0].mode; - igt_output_override_mode(bigjoiner_output, mode); - - pipe = &display->pipes[data->pipe1]; - plane = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane, &data->fb); - igt_fb_set_size(&data->fb, plane, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay); - - igt_display_commit2(display, COMMIT_ATOMIC); - - igt_output_set_pipe(bigjoiner_output, PIPE_NONE); - igt_plane_set_fb(plane, NULL); - igt_display_commit2(display, COMMIT_ATOMIC); } -static void test_dual_display(data_t *data) +static void tets_big_joiner_on_last_pipe(data_t *data, bool force_joiner) { + int i, len, ret; + uint64_t *outputs; + igt_output_t *output; + igt_plane_t *primary; + igt_fb_t fb; drmModeModeInfo *mode; - igt_output_t *output, *bigjoiner_output[2]; - igt_display_t *display = &data->display; - igt_pipe_t *pipe; - igt_plane_t *plane1, *plane2; - int count = 0; - igt_display_reset(display); + len = force_joiner ? data->non_big_joiner_output_count : data->big_joiner_output_count; + outputs = force_joiner ? data->non_big_joiner_outputs : data->big_joiner_outputs; - for_each_connected_output(display, output) { - if (data->output[count].output_id == output->id) { - bigjoiner_output[count] = output; - count++; + for (i = 0; i < len; i++) { + igt_display_reset(&data->display); + output = get_output_by_id(data, outputs[i]); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, output->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output->name) == 1); } - - if (count > 1) - break; + igt_output_set_pipe(output, data->pipe_seq[data->n_pipes - 1]); + mode = igt_output_get_mode(output); + igt_info(" Assigning pipe %s to %s with mode %dx%d@%d\n", + kmstest_pipe_name(data->pipe_seq[data->n_pipes - 1]), + igt_output_name(output), mode->hdisplay, + mode->vdisplay, mode->vrefresh); + primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb); + igt_plane_set_fb(primary, &fb); + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC); + igt_assert_f(ret != 0, "Commit shouldn't have passed\n"); } + if (force_joiner) { + for (i = 0; i < len; i++) { + output = get_output_by_id(data, outputs[i]); + igt_force_bigjoiner_enable(data->drm_fd, output->name, false); + } + igt_display_commit2(&data->display, COMMIT_ATOMIC); + } +} - igt_output_set_pipe(bigjoiner_output[0], data->pipe1); - igt_output_set_pipe(bigjoiner_output[1], data->pipe2); - - /* Set up first big joiner output on Pipe A*/ - mode = &data->output[0].mode; - igt_output_override_mode(bigjoiner_output[0], mode); - - pipe = &display->pipes[data->pipe1]; - plane1 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane1, &data->fb); - igt_fb_set_size(&data->fb, plane1, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane1, mode->hdisplay, mode->vdisplay); - - /* Set up second big joiner output on Pipe C*/ - mode = &data->output[1].mode; - igt_output_override_mode(bigjoiner_output[1], mode); - - pipe = &display->pipes[data->pipe2]; - plane2 = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY); - - igt_plane_set_fb(plane2, &data->fb); - igt_fb_set_size(&data->fb, plane2, mode->hdisplay, mode->vdisplay); - igt_plane_set_size(plane2, mode->hdisplay, mode->vdisplay); - - igt_display_commit2(display, COMMIT_ATOMIC); +static void test_basic_modeset(data_t *data, int num_outputs, + Combination combinations[MAX_COMBINATIONS], + uint64_t num_combinations, bool force_joiner) +{ + int i, j, ret; + igt_display_t *display = &data->display; + igt_output_t *output[num_outputs]; + igt_plane_t *primary[num_outputs]; + igt_fb_t fb[num_outputs]; + drmModeModeInfo *mode; - /* Clean up */ - igt_output_set_pipe(bigjoiner_output[0], PIPE_NONE); - igt_output_set_pipe(bigjoiner_output[1], PIPE_NONE); - igt_plane_set_fb(plane1, NULL); - igt_plane_set_fb(plane2, NULL); - igt_display_commit2(display, COMMIT_ATOMIC); + for (i = 0; i < num_combinations; i++) { + igt_display_reset(display); + for (j = 0; j < num_outputs; j++) { + output[j] = get_output_by_id(data, + force_joiner ? + data->non_big_joiner_outputs[j] : + data->big_joiner_outputs[j]); + if (force_joiner) { + igt_force_bigjoiner_enable(data->drm_fd, + output[j]->name, true); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, + output[j]->name) == 1); + } + igt_info("Assigning pipe %d to %s%s", + data->pipe_seq[combinations[i].combination[j]], + output[j]->name, j == num_outputs - 1 ? "\n" : ", "); + igt_output_set_pipe(output[j], data->pipe_seq[combinations[i].combination[j]]); + primary[j] = igt_output_get_plane_type(output[j], DRM_PLANE_TYPE_PRIMARY); + mode = igt_output_get_mode(output[j]); + igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, &fb[j]); + igt_plane_set_fb(primary[j], &fb[j]); + } + ret = igt_display_try_commit2(display, COMMIT_ATOMIC); + if (ret == 0) + igt_display_commit2(display, COMMIT_ATOMIC); + else + igt_assert_f(ret == 0, "Commit failed\n"); + + if (force_joiner) { + for (j = 0; j < num_outputs; j++) { + igt_display_reset(display); + igt_force_bigjoiner_enable(data->drm_fd, output[j]->name, false); + igt_assert(igt_check_force_bigjoiner_status(data->drm_fd, output[j]->name) == 0); + igt_display_commit2(&data->display, COMMIT_ATOMIC); + } + } + } } igt_main { + int i, j; data_t data; igt_output_t *output; - drmModeModeInfo mode; - int valid_output = 0, i, count = 0, j = 0; - uint16_t width = 0, height = 0; - enum pipe pipe_seq[IGT_MAX_PIPES]; + i = j = 0; igt_fixture { data.drm_fd = drm_open_driver_master(DRIVER_INTEL | DRIVER_XE); kmstest_set_vt_graphics_mode(); - igt_display_require(&data.display, data.drm_fd); igt_require(data.display.is_atomic); - max_dotclock = igt_get_max_dotclock(data.drm_fd); + data.big_joiner_output_count = 0; + data.non_big_joiner_output_count = 0; + data.combined_output_count = 0; + data.output_count = 0; for_each_connected_output(&data.display, output) { bool found = false; drmModeConnector *connector = output->config.connector; - - /* - * Bigjoiner will come in to the picture when the - * resolution > 5K or clock > max-dot-clock. - */ found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock); - if (found) { - data.output[count].output_id = output->id; - memcpy(&data.output[count].mode, &mode, sizeof(drmModeModeInfo)); - count++; - - width = max(width, mode.hdisplay); - height = max(height, mode.vdisplay); + data.big_joiner_outputs[data.big_joiner_output_count++] = output->id; + igt_output_override_mode(output, &connector->modes[0]); + } else { + if (output_supports_force_joiner(output)) { + data.non_big_joiner_outputs[data.non_big_joiner_output_count++] = output->id; + igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc); + igt_output_override_mode(output, &connector->modes[0]); + } } - valid_output++; + data.output_count++; } data.n_pipes = 0; for_each_pipe(&data.display, i) { data.n_pipes++; - pipe_seq[j] = i; + data.pipe_seq[j] = i; j++; } - - igt_require_f(count > 0, "No output with 5k+ mode (or) clock > max-dot-clock found\n"); - - igt_create_pattern_fb(data.drm_fd, width, height, DRM_FORMAT_XRGB8888, - DRM_FORMAT_MOD_LINEAR, &data.fb); } igt_describe("Verify the basic modeset on big joiner mode on all pipes"); igt_subtest_with_dynamic("basic") { - for (i = 0; i < data.n_pipes - 1; i++) { - data.pipe1 = pipe_seq[i]; - igt_dynamic_f("pipe-%s", kmstest_pipe_name(pipe_seq[i])) - test_basic_modeset(&data); + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + for (i = 0; i < data.big_joiner_output_count; i++) { + uint64_t num_combinations = 0; + Combination combinations[MAX_COMBINATIONS]; + + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", + i+1, data.n_pipes, num_combinations); + + if (num_combinations > 0) + igt_dynamic_f("%dx-big-joiner", i+1) + test_basic_modeset(&data, i+1, combinations, num_combinations, false); + else + break; } } - igt_describe("Verify if the modeset on the adjoining pipe is rejected " - "when the pipe is active with a big joiner modeset"); - igt_subtest_with_dynamic("invalid-modeset") { - data.pipe1 = pipe_seq[j - 1]; - - igt_display_reset(&data.display); - for_each_connected_output(&data.display, output) { - if (data.output[0].output_id != output->id) - continue; - - mode = data.output[0].mode; - igt_output_set_pipe(output, data.pipe1); - igt_output_override_mode(output, &mode); - - igt_dynamic_f("pipe-%s-%s", - kmstest_pipe_name(data.pipe1), - igt_output_name(output)) - test_invalid_modeset(&data); + igt_describe("Verify the basic modeset on big joiner mode on all pipes"); + igt_subtest_with_dynamic("force-joiner-basic") { + igt_require_f(data.non_big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + for (i = 0; i < data.non_big_joiner_output_count; i++) { + uint64_t num_combinations = 0; + Combination combinations[MAX_COMBINATIONS]; + + generate_combinations(i+1, data.n_pipes, BIG_JOINER, combinations, &num_combinations); + igt_info("Number of combinations for %d outputs and %d pipes are %ld\n", + i+1, data.n_pipes, num_combinations); + + if (num_combinations > 0) + igt_dynamic_f("%dx-joiner", i+1) + test_basic_modeset(&data, i+1, combinations, num_combinations, true); + else + break; } + } - if(valid_output > 1) { - for (i = 0; i < data.n_pipes - 1; i++) { - igt_output_t *first_output = NULL, *second_output = NULL; - - data.pipe1 = pipe_seq[i]; - data.pipe2 = pipe_seq[i + 1]; - - igt_display_reset(&data.display); - for_each_connected_output(&data.display, output) { - if (data.output[0].output_id == output->id) { - first_output = output; - mode = data.output[0].mode; + igt_subtest_with_dynamic("invalid-modeset") { + igt_require_f(data.big_joiner_output_count > 0, "Big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); - igt_output_set_pipe(output, data.pipe1); - igt_output_override_mode(output, &mode); - } else if (second_output == NULL) { - second_output = output; - igt_output_set_pipe(output, data.pipe2); + if (data.big_joiner_output_count >= 1) + igt_dynamic_f("big_joiner_on_last_pipe") + tets_big_joiner_on_last_pipe(&data, false); - break; - } - } + if (data.big_joiner_output_count > 1) + igt_dynamic_f("invalid_combinations") + test_invalid_modeset_two_joiner(&data, false, false); - igt_dynamic_f("pipe-%s-%s-pipe-%s-%s", - kmstest_pipe_name(data.pipe1), - igt_output_name(first_output), - kmstest_pipe_name(data.pipe2), - igt_output_name(second_output)) - test_invalid_modeset(&data); - } + if (data.big_joiner_output_count == 1 && data.non_big_joiner_output_count > 0) { + data.combined_outputs[data.combined_output_count++] = data.big_joiner_outputs[0]; + data.combined_outputs[data.combined_output_count++] = data.non_big_joiner_outputs[0]; + test_invalid_modeset_two_joiner(&data, false, true); } } - igt_describe("Verify simultaneous modeset on 2 big joiner outputs"); - igt_subtest_with_dynamic("2x-modeset") { - igt_require_f(count > 1, "2 outputs with big joiner modes are required\n"); - igt_require_f(data.n_pipes > 3, "Minumum of 4 pipes are required\n"); - for (i = 0; (i + 2) < data.n_pipes - 1; i++) { - data.pipe1 = pipe_seq[i]; - data.pipe2 = pipe_seq[i + 2]; - igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe_seq[i]), kmstest_pipe_name(pipe_seq[i + 2])) - test_dual_display(&data); - } + igt_subtest_with_dynamic("force-joiner-invalid-modeset") { + igt_require_f(data.non_big_joiner_output_count > 0, "Non big joiner output not found\n"); + igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n"); + + if (data.non_big_joiner_output_count >= 1) + igt_dynamic_f("big_joiner_on_last_pipe") + tets_big_joiner_on_last_pipe(&data, true); + + if (data.non_big_joiner_output_count > 1) + igt_dynamic_f("invalid_combinations") + test_invalid_modeset_two_joiner(&data, true, false); } igt_fixture { - igt_remove_fb(data.drm_fd, &data.fb); igt_display_fini(&data.display); drm_close_driver(data.drm_fd); } -- 2.25.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-03-05 17:34 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-03-03 17:22 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi 2024-03-03 17:22 ` [PATCH i-g-t 1/4] lib/igt_kms: move bigjoiner_mode_found to lib Kunal Joshi 2024-03-03 17:22 ` [PATCH i-g-t 2/4] lib/igt_kms: add helpers to enable/disable force joiner Kunal Joshi 2024-03-05 11:44 ` Modem, Bhanuprakash 2024-03-05 12:50 ` Joshi, Kunal1 2024-03-03 17:22 ` [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner Kunal Joshi 2024-03-05 11:44 ` Modem, Bhanuprakash 2024-03-05 13:14 ` Joshi, Kunal1 2024-03-05 17:34 ` Kamil Konieczny 2024-03-03 17:22 ` [PATCH i-g-t 4/4] tests/intel-ci/fast-feedback: HAX PATCH DO NOT MERGE Kunal Joshi 2024-03-03 17:46 ` ✓ CI.xeBAT: success for revamp big joiner test (rev3) Patchwork 2024-03-03 18:07 ` ✗ Fi.CI.BAT: failure " Patchwork -- strict thread matches above, loose matches on Subject: below -- 2024-03-01 8:25 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi 2024-03-01 8:26 ` [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner Kunal Joshi 2024-02-29 18:10 [PATCH i-g-t 0/4] revamp big joiner test Kunal Joshi 2024-02-29 18:10 ` [PATCH i-g-t 3/4] tests/intel/kms_big_joiner: revamp kms_big_joiner Kunal Joshi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox