[igt-dev] [PATCH i-g-t 4/4] tests/kms_chamelium: Test HPD for different mode handling scenarios

Arkadiusz Hiler arkadiusz.hiler at intel.com
Tue Mar 31 12:38:57 UTC 2020


The default scenario is now performing all hotplugs with modes disabled
on all connectors. This is the quickest of the tests and represents
userspace not caring about the new display (e.g. explicitly disabled).

*-hpd-enable-disable-mode covers the most common userspace behavior
where each hotplug event is accompanied by a corresponding enabling /
disabling commit.

*-hpd-with-enabled-mode explicitly targets the scenario where we have
mode enabled and never disable it as we do hotplugs to reproduce the
issue we see with TypeC connectors for ICL and TGL.

Cc: Kunal Joshi <kunal1.joshi at intel.com>
Cc: Imre Deak <imre.deak at intel.com>
Issue: https://gitlab.freedesktop.org/drm/intel/issues/323
Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler at intel.com>
---
 tests/kms_chamelium.c | 285 ++++++++++++++++++++++++++++--------------
 1 file changed, 189 insertions(+), 96 deletions(-)

diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 236e1010..09068da4 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -45,6 +45,12 @@ enum test_edid {
 };
 #define TEST_EDID_COUNT 5
 
+enum test_modeset_mode {
+	TEST_MODESET_ON,
+	TEST_MODESET_ON_OFF,
+	TEST_MODESET_OFF,
+};
+
 typedef struct {
 	struct chamelium *chamelium;
 	struct chamelium_port **ports;
@@ -294,14 +300,127 @@ reset_state(data_t *data, struct chamelium_port *port)
 	}
 }
 
+static void chamelium_paint_xr24_pattern(uint32_t *data,
+					 size_t width, size_t height,
+					 size_t stride, size_t block_size)
+{
+	uint32_t colors[] = { 0xff000000,
+			      0xffff0000,
+			      0xff00ff00,
+			      0xff0000ff,
+			      0xffffffff };
+	unsigned i, j;
+
+	for (i = 0; i < height; i++)
+		for (j = 0; j < width; j++)
+			*(data + i * stride / 4 + j) = colors[((j / block_size) + (i / block_size)) % 5];
+}
+
+static int chamelium_get_pattern_fb(data_t *data, size_t width, size_t height,
+				    uint32_t fourcc, size_t block_size,
+				    struct igt_fb *fb)
+{
+	int fb_id;
+	void *ptr;
+
+	igt_assert(fourcc == DRM_FORMAT_XRGB8888);
+
+	fb_id = igt_create_fb(data->drm_fd, width, height, fourcc,
+			      LOCAL_DRM_FORMAT_MOD_NONE, fb);
+	igt_assert(fb_id > 0);
+
+	ptr = igt_fb_map_buffer(fb->fd, fb);
+	igt_assert(ptr);
+
+	chamelium_paint_xr24_pattern(ptr, width, height, fb->strides[0],
+				     block_size);
+	igt_fb_unmap_buffer(fb, ptr);
+
+	return fb_id;
+}
+
+static void
+enable_output(data_t *data,
+	      struct chamelium_port *port,
+	      igt_output_t *output,
+	      drmModeModeInfo *mode,
+	      struct igt_fb *fb)
+{
+	igt_display_t *display = output->display;
+	igt_plane_t *primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+	drmModeConnector *connector = chamelium_port_get_connector(
+	    data->chamelium, port, false);
+
+	igt_assert(primary);
+
+	igt_plane_set_size(primary, mode->hdisplay, mode->vdisplay);
+	igt_plane_set_fb(primary, fb);
+	igt_output_override_mode(output, mode);
+
+	/* Clear any color correction values that might be enabled */
+	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_DEGAMMA_LUT))
+		igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0);
+	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT))
+		igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
+	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_CTM))
+		igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM, NULL, 0);
+
+	igt_display_commit2(display, COMMIT_ATOMIC);
+
+	if (chamelium_port_get_type(port) == DRM_MODE_CONNECTOR_VGA)
+		usleep(250000);
+
+	drmModeFreeConnector(connector);
+}
+
+static enum pipe get_pipe_for_output(igt_display_t *display, igt_output_t *output)
+{
+	enum pipe pipe;
+
+	for_each_pipe(display, pipe) {
+		if (igt_pipe_connector_valid(pipe, output)) {
+			return pipe;
+		}
+	}
+
+	igt_assert_f(false, "No pipe found for output %s\n",
+		     igt_output_name(output));
+}
+
 static const char test_basic_hotplug_desc[] =
 	"Check that we get uevents and updated connector status on "
 	"hotplug and unplug";
 static void
-test_basic_hotplug(data_t *data, struct chamelium_port *port, int toggle_count)
+test_hotplug(data_t *data, struct chamelium_port *port, int toggle_count,
+	     enum test_modeset_mode modeset_mode)
 {
-	struct udev_monitor *mon = igt_watch_hotplug();
 	int i;
+	enum pipe pipe;
+	struct igt_fb fb = {0};
+	struct udev_monitor *mon = igt_watch_hotplug();
+	drmModeConnector *connector =
+		chamelium_port_get_connector(data->chamelium, port, false);
+	igt_output_t *output = igt_output_from_connector(&data->display,
+							 connector);
+	drmModeModeInfo *mode = &connector->modes[0];
+
+	if (modeset_mode == TEST_MODESET_ON_OFF ||
+	    modeset_mode == TEST_MODESET_ON) {
+		struct igt_fb temp_fb;
+		int temp_fb_id;
+		int fb_id;
+
+		temp_fb_id = chamelium_get_pattern_fb(data, mode->hdisplay, mode->vdisplay,
+						 DRM_FORMAT_XRGB8888, 64, &temp_fb);
+		igt_assert(temp_fb_id > 0);
+
+		fb_id = igt_fb_convert(&fb, &temp_fb, DRM_FORMAT_XRGB8888,
+					  LOCAL_DRM_FORMAT_MOD_NONE);
+		igt_remove_fb(data->drm_fd, &temp_fb);
+		igt_assert(fb_id > 0);
+
+		pipe = get_pipe_for_output(&data->display, output);
+	}
 
 	reset_state(data, NULL);
 	igt_hpd_storm_set_threshold(data->drm_fd, 0);
@@ -316,15 +435,30 @@ test_basic_hotplug(data_t *data, struct chamelium_port *port, int toggle_count)
 						 DRM_MODE_CONNECTED);
 		igt_flush_hotplugs(mon);
 
+		if (modeset_mode == TEST_MODESET_ON_OFF ||
+		    (modeset_mode == TEST_MODESET_ON && i == 0 )) {
+			igt_output_set_pipe(output, pipe);
+			enable_output(data, port, output, mode, &fb);
+		}
+
 		/* Now check if we get a hotplug from disconnection */
 		chamelium_unplug(data->chamelium, port);
 
 		wait_for_connector_after_hotplug(data, mon, port,
 						 DRM_MODE_DISCONNECTED);
+
+		igt_flush_hotplugs(mon);
+
+		if (modeset_mode == TEST_MODESET_ON_OFF) {
+			igt_output_set_pipe(output, PIPE_NONE);
+			igt_display_commit2(&data->display, COMMIT_ATOMIC);
+		}
 	}
 
 	igt_cleanup_hotplug(mon);
 	igt_hpd_storm_reset(data->drm_fd);
+	igt_remove_fb(data->drm_fd, &fb);
+	drmModeFreeConnector(connector);
 }
 
 static const struct edid *get_edid(enum test_edid edid);
@@ -533,7 +667,6 @@ prepare_output(data_t *data, struct chamelium_port *port, enum test_edid edid)
 	drmModeConnector *connector =
 		chamelium_port_get_connector(data->chamelium, port, false);
 	enum pipe pipe;
-	bool found = false;
 
 	/* The chamelium's default EDID has a lot of resolutions, way more then
 	 * we need to test. Additionally the default EDID doesn't support HDMI
@@ -551,16 +684,7 @@ prepare_output(data_t *data, struct chamelium_port *port, enum test_edid edid)
 	/* Refresh pipe to update connected status */
 	igt_output_set_pipe(output, PIPE_NONE);
 
-	for_each_pipe(display, pipe) {
-		if (!igt_pipe_connector_valid(pipe, output))
-			continue;
-
-		found = true;
-		break;
-	}
-
-	igt_assert_f(found, "No pipe found for output %s\n", igt_output_name(output));
-
+	pipe = get_pipe_for_output(display, output);
 	igt_output_set_pipe(output, pipe);
 
 	drmModeFreeConnector(connector);
@@ -568,79 +692,6 @@ prepare_output(data_t *data, struct chamelium_port *port, enum test_edid edid)
 	return output;
 }
 
-static void
-enable_output(data_t *data,
-	      struct chamelium_port *port,
-	      igt_output_t *output,
-	      drmModeModeInfo *mode,
-	      struct igt_fb *fb)
-{
-	igt_display_t *display = output->display;
-	igt_plane_t *primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
-	drmModeConnector *connector = chamelium_port_get_connector(
-	    data->chamelium, port, false);
-
-	igt_assert(primary);
-
-	igt_plane_set_size(primary, mode->hdisplay, mode->vdisplay);
-	igt_plane_set_fb(primary, fb);
-	igt_output_override_mode(output, mode);
-
-	/* Clear any color correction values that might be enabled */
-	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_DEGAMMA_LUT))
-		igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0);
-	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT))
-		igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
-	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_CTM))
-		igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM, NULL, 0);
-
-	igt_display_commit2(display, COMMIT_ATOMIC);
-
-	if (chamelium_port_get_type(port) == DRM_MODE_CONNECTOR_VGA)
-		usleep(250000);
-
-	drmModeFreeConnector(connector);
-}
-
-static void chamelium_paint_xr24_pattern(uint32_t *data,
-					 size_t width, size_t height,
-					 size_t stride, size_t block_size)
-{
-	uint32_t colors[] = { 0xff000000,
-			      0xffff0000,
-			      0xff00ff00,
-			      0xff0000ff,
-			      0xffffffff };
-	unsigned i, j;
-
-	for (i = 0; i < height; i++)
-		for (j = 0; j < width; j++)
-			*(data + i * stride / 4 + j) = colors[((j / block_size) + (i / block_size)) % 5];
-}
-
-static int chamelium_get_pattern_fb(data_t *data, size_t width, size_t height,
-				    uint32_t fourcc, size_t block_size,
-				    struct igt_fb *fb)
-{
-	int fb_id;
-	void *ptr;
-
-	igt_assert(fourcc == DRM_FORMAT_XRGB8888);
-
-	fb_id = igt_create_fb(data->drm_fd, width, height, fourcc,
-			      LOCAL_DRM_FORMAT_MOD_NONE, fb);
-	igt_assert(fb_id > 0);
-
-	ptr = igt_fb_map_buffer(fb->fd, fb);
-	igt_assert(ptr);
-
-	chamelium_paint_xr24_pattern(ptr, width, height, fb->strides[0],
-				     block_size);
-	igt_fb_unmap_buffer(fb, ptr);
-
-	return fb_id;
-}
-
 static void do_test_display(data_t *data, struct chamelium_port *port,
 			    igt_output_t *output, drmModeModeInfo *mode,
 			    uint32_t fourcc, enum chamelium_check check,
@@ -2539,13 +2590,27 @@ igt_main
 
 		igt_describe(test_basic_hotplug_desc);
 		connector_subtest("dp-hpd", DisplayPort)
-			test_basic_hotplug(&data, port,
-					   HPD_TOGGLE_COUNT_DP_HDMI);
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_DP_HDMI,
+				     TEST_MODESET_OFF);
 
 		igt_describe(test_basic_hotplug_desc);
 		connector_subtest("dp-hpd-fast", DisplayPort)
-			test_basic_hotplug(&data, port,
-					   HPD_TOGGLE_COUNT_FAST);
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_OFF);
+
+		igt_describe(test_basic_hotplug_desc);
+		connector_subtest("dp-hpd-enable-disable-mode", DisplayPort)
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_ON_OFF);
+
+		igt_describe(test_basic_hotplug_desc);
+		connector_subtest("dp-hpd-with-enabled-mode", DisplayPort)
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_ON);
 
 		igt_describe(test_edid_read_desc);
 		connector_subtest("dp-edid-read", DisplayPort) {
@@ -2634,13 +2699,27 @@ igt_main
 
 		igt_describe(test_basic_hotplug_desc);
 		connector_subtest("hdmi-hpd", HDMIA)
-			test_basic_hotplug(&data, port,
-					   HPD_TOGGLE_COUNT_DP_HDMI);
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_DP_HDMI,
+				     TEST_MODESET_OFF);
 
 		igt_describe(test_basic_hotplug_desc);
 		connector_subtest("hdmi-hpd-fast", HDMIA)
-			test_basic_hotplug(&data, port,
-					   HPD_TOGGLE_COUNT_FAST);
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_OFF);
+
+		igt_describe(test_basic_hotplug_desc);
+		connector_subtest("hdmi-hpd-enable-disable-mode", HDMIA)
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_ON_OFF);
+
+		igt_describe(test_basic_hotplug_desc);
+		connector_subtest("hdmi-hpd-with-enabled-mode", HDMIA)
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_ON);
 
 		igt_describe(test_edid_read_desc);
 		connector_subtest("hdmi-edid-read", HDMIA) {
@@ -2795,11 +2874,25 @@ igt_main
 
 		igt_describe(test_basic_hotplug_desc);
 		connector_subtest("vga-hpd", VGA)
-			test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_VGA);
+			test_hotplug(&data, port, HPD_TOGGLE_COUNT_VGA,
+				     TEST_MODESET_OFF);
 
 		igt_describe(test_basic_hotplug_desc);
 		connector_subtest("vga-hpd-fast", VGA)
-			test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_FAST);
+			test_hotplug(&data, port, HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_OFF);
+
+		igt_describe(test_basic_hotplug_desc);
+		connector_subtest("hdmi-hpd-enable-disable-mode", VGA)
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_ON_OFF);
+
+		igt_describe(test_basic_hotplug_desc);
+		connector_subtest("hdmi-hpd-with-enabled-mode", VGA)
+			test_hotplug(&data, port,
+				     HPD_TOGGLE_COUNT_FAST,
+				     TEST_MODESET_ON);
 
 		igt_describe(test_edid_read_desc);
 		connector_subtest("vga-edid-read", VGA) {
-- 
2.24.1



More information about the igt-dev mailing list