<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Hi,<br>
</p>
<div class="moz-cite-prefix">On 1/30/2025 10:50 PM, Jeevan B wrote:<br>
</div>
<blockquote type="cite" cite="mid:20250130172031.4126606-6-jeevan.b@intel.com">
<pre wrap="" class="moz-quote-pre">We need to ensure that the system does not use a joiner for modes that do
not require it. This test will validate that the correct non-joiner mode
is selected, and then forcing a modeset and flip on the last pipe. If the
joiner is mistakenly enabled for a non-joiner mode, the test should fail.
otherwise, the commit should proceed as expected.
v2: Fix nonjoiner_mode_found to find the required case(6K@30).
Remove clk sort and minor fixes. (Karthik)
v3: Rename nonjoiner to non_joiner and minor modifications. (Swati)
v4: Add joiner check. (Karthik)
Signed-off-by: Jeevan B <a class="moz-txt-link-rfc2396E" href="mailto:jeevan.b@intel.com"><jeevan.b@intel.com></a>
---
tests/intel/kms_joiner.c | 78 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/tests/intel/kms_joiner.c b/tests/intel/kms_joiner.c
index 0a9910046..08a9c0cb3 100644
--- a/tests/intel/kms_joiner.c
+++ b/tests/intel/kms_joiner.c
@@ -75,6 +75,9 @@
*
* SUBTEST: switch-modeset-ultra-joiner-big-joiner
* Description: Verify switching between ultra joiner and big joiner modeset.
+ *
+ * SUBTEST: basic-non-joiner
+ * Description: Vefiry basic non-joiner mode across all pipes.</pre>
</blockquote>
Please have a different name and a more accurate description. The
intention of this test should be to enable corner case modes which
are changing b/n different platforms.<br>
<blockquote type="cite" cite="mid:20250130172031.4126606-6-jeevan.b@intel.com">
<pre wrap="" class="moz-quote-pre">
*/
IGT_TEST_DESCRIPTION("Test joiner / force joiner");
@@ -86,6 +89,7 @@ typedef struct {
int ultra_joiner_output_count;
int non_big_joiner_output_count;
int non_ultra_joiner_output_count;
+ int non_joiner_output_count;
int mixed_output_count;
int output_count;
int n_pipes;
@@ -95,6 +99,7 @@ typedef struct {
igt_output_t *non_big_joiner_output[IGT_MAX_PIPES];
igt_output_t *non_ultra_joiner_output[IGT_MAX_PIPES];
igt_output_t *mixed_output[IGT_MAX_PIPES];
+ igt_output_t *non_joiner_output[IGT_MAX_PIPES];
enum pipe pipe_seq[IGT_MAX_PIPES];
igt_display_t display;
} data_t;
@@ -153,6 +158,23 @@ static enum pipe setup_pipe(data_t *data, igt_output_t *output, enum pipe pipe,
return master_pipe;
}
+static bool non_joiner_mode_found(int drm_fd, drmModeConnector *connector,
+ drmModeModeInfo *mode)
+{
+ igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc);
+
+ for (int i = 0; i < connector->count_modes; i++) {
+ drmModeModeInfo *current_mode = &connector->modes[i];
+
+ if ((current_mode->hdisplay == 6144 && current_mode->vrefresh == 30) ||
+ mode->clock < max_dotclock) {</pre>
</blockquote>
We should not be using hard coded values here as this will be
different between platforms. Please update the check to use the
maximum possible mode supported on single pipe for each platform.<br>
<blockquote type="cite" cite="mid:20250130172031.4126606-6-jeevan.b@intel.com">
<pre wrap="" class="moz-quote-pre">
+ *mode = *current_mode;
+ return true;
+ }
+ }
+ return false;
+}
+
static void set_joiner_mode(data_t *data, igt_output_t *output, drmModeModeInfo *mode)
{
igt_plane_t *primary;
@@ -480,6 +502,48 @@ static void test_ultra_joiner(data_t *data, bool invalid_pipe, bool two_display,
}
}
+static void test_single_non_joiner(data_t *data)
+{
+ int count;
+ igt_output_t **outputs, *output;
+ igt_fb_t fb;
+ igt_plane_t *primary;
+ drmModeModeInfo mode;
+ drmModeConnector *con;
+
+ count = data->non_joiner_output_count;
+ outputs = data->non_joiner_output;
+ igt_display_reset(&data->display);
+
+ for (int i = 0; i < count; i++) {
+ output = outputs[i];
+ con = output->config.connector;
+
+ if (non_joiner_mode_found(data->drm_fd, con, &mode)) {
+ igt_output_override_mode(output, &mode);
+ 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);
+
+ igt_output_set_pipe(output, data->pipe_seq[data->n_pipes - 1]);
+
+ 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);
+ igt_assert(igt_display_try_commit2(&data->display, COMMIT_ATOMIC));
+ igt_assert(!is_joiner_has(data->drm_fd));</pre>
</blockquote>
Please fix the function name.<br>
<blockquote type="cite" cite="mid:20250130172031.4126606-6-jeevan.b@intel.com">
<pre wrap="" class="moz-quote-pre">
+ igt_plane_set_fb(primary, NULL);
+ igt_remove_fb(data->drm_fd, &fb);
+ } else {
+ igt_warn("No valid non-joiner mode found for output %s\n", igt_output_name(output));
+ }
+ }
+}
+
igt_main
{
bool ultra_joiner_supported, is_dgfx;
@@ -494,6 +558,7 @@ igt_main
data.ultra_joiner_output_count = 0;
data.non_big_joiner_output_count = 0;
data.non_ultra_joiner_output_count = 0;
+ data.non_joiner_output_count = 0;
data.mixed_output_count = 0;
data.output_count = 0;
j = 0;
@@ -512,6 +577,7 @@ igt_main
for_each_connected_output(&data.display, output) {
bool ultrajoiner_found = false, bigjoiner_found = false, force_joiner_supported = false;
+ bool non_joiner_found = false;
drmModeConnector *connector = output->config.connector;
/*
@@ -522,6 +588,7 @@ igt_main
*/
bigjoiner_found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock, &mode);
ultrajoiner_found = ultrajoiner_mode_found(data.drm_fd, connector, max_dotclock, &mode);
+ non_joiner_found = non_joiner_mode_found(data.drm_fd, connector, &mode);
if (igt_has_force_joiner_debugfs(data.drm_fd, output->name))
force_joiner_supported = true;
@@ -537,6 +604,9 @@ igt_main
else if (force_joiner_supported)
data.non_big_joiner_output[data.non_big_joiner_output_count++] = output;
+ if (non_joiner_found)
+ data.non_joiner_output[data.non_joiner_output_count++] = output;
+
data.output_count++;
}
if (data.big_joiner_output_count == 1 && data.non_big_joiner_output_count >= 1) {
@@ -702,6 +772,14 @@ igt_main
}
}
+ igt_describe("Verify the basic modeset on big joiner mode on all pipes");
+ igt_subtest_with_dynamic("basic-non-joiner") {</pre>
</blockquote>
Please update the subtest name to convey what is being validated in
this subtest.<br>
<blockquote type="cite" cite="mid:20250130172031.4126606-6-jeevan.b@intel.com">
<pre wrap="" class="moz-quote-pre">
+ igt_require_f(data.n_pipes >= 1,
+ "Minimum of 1 pipe is required.\n");</pre>
</blockquote>
<p>This is a redundant check IMHO as we have only 1 pipe needed
here, although the check is in line with the other subtests in
this binary. So your call if you want to still keep it.</p>
<p>But please add '<span style="white-space: pre-wrap">non_joiner_found<span style="white-space: normal">' check here and skip the test from here only if not found.
</span></span></p>
<blockquote type="cite" cite="mid:20250130172031.4126606-6-jeevan.b@intel.com">
<pre wrap="" class="moz-quote-pre">
+ igt_dynamic_f("non-joiner")</pre>
</blockquote>
<p>Have the output/pipe name in dynamic subtest. Otherwise this
dynamic subtest isn't required.</p>
Thanks,<br>
Karthik.B.S<br>
<blockquote type="cite" cite="mid:20250130172031.4126606-6-jeevan.b@intel.com">
<pre wrap="" class="moz-quote-pre">
+ test_single_non_joiner(&data);
+ }
+
igt_fixture {
igt_display_fini(&data.display);
drm_close_driver(data.drm_fd);
</pre>
</blockquote>
</body>
</html>