[PATCH i-g-t v1] tests/intel/kms_joiner: vblank test for joiner secondary crtc

Santhosh Reddy Guddati <[email protected]>
Newsgroups org.freedesktop.lists.igt-dev
Message-ID <[email protected]>
In joiner mode, add new subtests to validate vblank events are delivered
on secondary crtc.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Santhosh Reddy Guddati <[email protected]>
---
 tests/intel/kms_joiner.c | 94 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/tests/intel/kms_joiner.c b/tests/intel/kms_joiner.c
index dfcb24004..ff33256a3 100644
--- a/tests/intel/kms_joiner.c
+++ b/tests/intel/kms_joiner.c
@@ -76,6 +76,10 @@
  * SUBTEST: basic-max-non-joiner
  * Description: Validate basic max non-joiner modeset by selecting the max mode
  *		supported on single pipe.
+ *
+ * SUBTEST: vblank-joiner-secondary
+ * Description: Verify that vblank interrupts are generated on all pipes in a
+ *		joiner configuration including the secondary pipe.
  */
 IGT_TEST_DESCRIPTION("Test joiner / force joiner");
 
@@ -275,6 +279,74 @@ static void switch_modeset_ultra_joiner_big_joiner(data_t *data, igt_output_t *o
 	}
 }
 
+static void test_joiner_vblank(data_t *data, bool force_joiner)
+{
+	int i;
+	enum pipe pipe, master_pipe;
+	uint32_t available_pipe_mask = BIT(data->n_pipes) - 1;
+	igt_output_t *output;
+	igt_plane_t *primary;
+	igt_output_t **outputs;
+	igt_fb_t fb;
+	drmModeModeInfo *mode;
+	int count;
+	drmVBlank wait_vbl;
+	uint32_t pipe_flag;
+
+	outputs = force_joiner ? data->non_big_joiner_output : data->big_joiner_output;
+	count = force_joiner ? data->non_big_joiner_output_count : data->big_joiner_output_count;
+	igt_display_reset(&data->display);
+	igt_display_commit2(&data->display, COMMIT_ATOMIC);
+
+	for (i = 0; i < count; i++) {
+		output = outputs[i];
+		for (pipe = 0; pipe < data->n_pipes - 1; pipe++) {
+			igt_crtc_t *primary_crtc, *secondary_crtc;
+			int ret;
+
+			master_pipe = setup_pipe(data, output, pipe, available_pipe_mask);
+			if (master_pipe == PIPE_NONE)
+				continue;
+
+			mode = igt_output_get_mode(output);
+			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_display_commit2(&data->display, COMMIT_ATOMIC);
+
+			primary_crtc = igt_crtc_for_pipe(&data->display, master_pipe);
+			secondary_crtc = igt_crtc_for_pipe(&data->display, master_pipe + 1);
+
+			/* Verify vblank works on the primary joiner pipe */
+			igt_wait_for_vblank(primary_crtc);
+			igt_info("Pipe %s (primary): vblank wait OK\n",
+				 kmstest_pipe_name(master_pipe));
+
+			/* Verify vblank works on the secondary joiner pipe */
+			pipe_flag = kmstest_get_vbl_flag(secondary_crtc->crtc_index);
+			memset(&wait_vbl, 0, sizeof(wait_vbl));
+
+			wait_vbl.request.type = DRM_VBLANK_RELATIVE | pipe_flag;
+			wait_vbl.request.sequence = 1;
+			ret = drmWaitVBlank(data->drm_fd, &wait_vbl);
+
+			igt_assert_f(ret == 0,
+				     "Pipe %s (joiner secondary): vblank wait timed out - "
+				     "no vblank interrupt delivered\n",
+				     kmstest_pipe_name(master_pipe + 1));
+			igt_info("Pipe %s (secondary): vblank wait OK\n",
+				 kmstest_pipe_name(master_pipe + 1));
+
+			igt_plane_set_fb(primary, NULL);
+			igt_output_set_crtc(output, NULL);
+			igt_display_commit2(&data->display, COMMIT_ATOMIC);
+			igt_remove_fb(data->drm_fd, &fb);
+		}
+	}
+}
+
 static void test_single_joiner(data_t *data, int output_count, bool force_joiner)
 {
 	int i;
@@ -836,6 +908,28 @@ int igt_main()
 			test_basic_max_non_joiner(&data);
 	}
 
+	igt_describe("Verify vblank interrupts arrive on joiner secondary pipes");
+	igt_subtest_with_dynamic("vblank-joiner-secondary") {
+		igt_require_f(data.n_pipes >= 2, "Minimum 2 pipes required\n");
+		igt_require_f(data.big_joiner_output_count > 0 ||
+			      data.non_big_joiner_output_count > 0,
+			      "No big joiner or force big joiner output found\n");
+
+		if (data.big_joiner_output_count > 0) {
+			igt_dynamic_f("big-joiner") {
+				test_joiner_vblank(&data, false);
+			}
+		}
+
+		if (data.non_big_joiner_output_count > 0) {
+			igt_dynamic_f("force-big-joiner") {
+				enable_force_joiner_on_all_non_big_joiner_outputs(&data);
+				test_joiner_vblank(&data, true);
+				igt_reset_connectors();
+			}
+		}
+	}
+
 	igt_fixture() {
 		igt_display_fini(&data.display);
 		drm_close_driver(data.drm_fd);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.