All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Ser <simon.ser@intel.com>
To: igt-dev@lists.freedesktop.org
Subject: [igt-dev] [PATCH i-g-t 3/3] tests/kms_chamelium: add a link-status test
Date: Tue, 13 Aug 2019 17:17:48 +0300	[thread overview]
Message-ID: <20190813141748.18876-4-simon.ser@intel.com> (raw)
In-Reply-To: <20190813141748.18876-1-simon.ser@intel.com>

This test first checks that on normal hotplug, the link-status property is set
to GOOD. It then triggers a link failure, checks that the property is updated
to BAD. Checks are performed to make sure the new mode list is a subset of the
previous one. After that, a new modeset is performed if necessary and the
link-status property is set back to GOOD.

This whole dance is repeated until we reach fallback modes.

Signed-off-by: Simon Ser <simon.ser@intel.com>
---
 tests/kms_chamelium.c | 142 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 142 insertions(+)

diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index b7d30a2d0f55..bef4d6d3bbd8 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -539,6 +539,145 @@ enable_output(data_t *data,
 	drmModeFreeConnector(connector);
 }
 
+static bool find_mode(const drmModeModeInfo *list, size_t list_len,
+		      const drmModeModeInfo *mode)
+{
+	size_t i;
+
+	for (i = 0; i < list_len; i++) {
+		if (memcmp(&list[i], mode, sizeof(*mode)) == 0) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static void check_modes_subset(const drmModeModeInfo *prev, size_t prev_len,
+			       const drmModeModeInfo *cur, size_t cur_len)
+{
+	size_t i;
+
+	for (i = 0; i < cur_len; i++) {
+		igt_assert_f(find_mode(prev, prev_len, &cur[i]),
+			     "Got new mode %s after link status failure\n",
+			     cur[i].name);
+	}
+
+	igt_assert(cur_len <= prev_len); /* safety net */
+	igt_debug("New mode list contains %zu less modes\n",
+		  prev_len - cur_len);
+}
+
+static bool are_fallback_modes(const drmModeModeInfo *modes, size_t modes_len)
+{
+	igt_assert(modes_len > 0);
+
+	return modes[0].hdisplay <= 1024 && modes[0].vdisplay <= 768;
+}
+
+static void
+test_link_status(data_t *data, struct chamelium_port *port)
+{
+	drmModeConnector *connector;
+	igt_output_t *output;
+	igt_plane_t *primary;
+	drmModeModeInfo *prev_modes;
+	size_t prev_modes_len;
+	drmModeModeInfo mode = {0};
+	uint32_t link_status_id;
+	uint64_t link_status;
+	bool has_prop;
+	unsigned int fb_id = 0;
+	struct igt_fb fb;
+	struct udev_monitor *mon;
+
+	igt_require(chamelium_supports_trigger_link_failure(data->chamelium));
+
+	reset_state(data, port);
+
+	output = prepare_output(data, port, TEST_EDID_BASE);
+	connector = chamelium_port_get_connector(data->chamelium, port, false);
+	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+	igt_assert(primary);
+
+	has_prop = kmstest_get_property(data->drm_fd, connector->connector_id,
+					DRM_MODE_OBJECT_CONNECTOR,
+					"link-status", &link_status_id,
+					&link_status, NULL);
+	igt_require(has_prop);
+	igt_assert_f(link_status == DRM_MODE_LINK_STATUS_GOOD,
+		     "Expected link status to be %d initially, got %"PRIu64"\n",
+		     DRM_MODE_LINK_STATUS_GOOD, link_status);
+
+	igt_debug("Connector has %d modes\n", connector->count_modes);
+	prev_modes_len = connector->count_modes;
+	prev_modes = malloc(prev_modes_len * sizeof(drmModeModeInfo));
+	memcpy(prev_modes, connector->modes,
+	       prev_modes_len * sizeof(drmModeModeInfo));
+
+	mon = igt_watch_hotplug();
+
+	while (1) {
+		if (link_status == DRM_MODE_LINK_STATUS_BAD) {
+			igt_output_set_prop_value(output,
+						  IGT_CONNECTOR_LINK_STATUS,
+						  DRM_MODE_LINK_STATUS_GOOD);
+		}
+
+		if (memcmp(&connector->modes[0], &mode, sizeof(mode)) != 0) {
+			igt_assert(connector->count_modes > 0);
+			mode = connector->modes[0];
+			igt_debug("Modesetting with %s\n", mode.name);
+			if (fb_id > 0)
+				igt_remove_fb(data->drm_fd, &fb);
+			fb_id = igt_create_color_pattern_fb(data->drm_fd,
+							    mode.hdisplay,
+							    mode.vdisplay,
+							    DRM_FORMAT_XRGB8888,
+							    LOCAL_DRM_FORMAT_MOD_NONE,
+							    0, 0, 0, &fb);
+			igt_assert(fb_id > 0);
+			enable_output(data, port, output, &mode, &fb);
+		} else {
+			igt_display_commit2(&data->display, COMMIT_ATOMIC);
+		}
+
+		igt_debug("Triggering link failure\n");
+		chamelium_trigger_link_failure(data->chamelium, port);
+
+		igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
+		igt_assert_eq(reprobe_connector(data, port),
+			      DRM_MODE_CONNECTED);
+
+		igt_flush_hotplugs(mon);
+
+		drmModeFreeConnector(connector);
+		connector = chamelium_port_get_connector(data->chamelium, port,
+							 false);
+		link_status = igt_output_get_prop(output, IGT_CONNECTOR_LINK_STATUS);
+		igt_assert_f(link_status == DRM_MODE_LINK_STATUS_BAD,
+			     "Expected link status to be %d after link failure, "
+			     "got %"PRIu64"\n",
+			     DRM_MODE_LINK_STATUS_BAD, link_status);
+		check_modes_subset(prev_modes, prev_modes_len,
+				   connector->modes, connector->count_modes);
+		prev_modes_len = connector->count_modes;
+		memcpy(prev_modes, connector->modes,
+		       connector->count_modes * sizeof(drmModeModeInfo));
+
+		if (are_fallback_modes(connector->modes, connector->count_modes)) {
+			igt_debug("Reached fallback modes\n");
+			break;
+		}
+	}
+
+	igt_cleanup_hotplug(mon);
+	igt_remove_fb(data->drm_fd, &fb);
+	free(prev_modes);
+	drmModeFreeConnector(connector);
+}
+
 static void chamelium_paint_xr24_pattern(uint32_t *data,
 					 size_t width, size_t height,
 					 size_t stride, size_t block_size)
@@ -2234,6 +2373,9 @@ igt_main
 			test_hpd_storm_disable(&data, port,
 					       HPD_STORM_PULSE_INTERVAL_DP);
 
+		connector_subtest("dp-link-status", DisplayPort)
+			test_link_status(&data, port);
+
 		connector_subtest("dp-edid-change-during-suspend", DisplayPort)
 			test_suspend_resume_edid_change(&data, port,
 							SUSPEND_STATE_MEM,
-- 
2.22.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  parent reply	other threads:[~2019-08-13 14:17 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-13 14:17 [igt-dev] [PATCH i-g-t 0/3] Chamelium link-status test Simon Ser
2019-08-13 14:17 ` [igt-dev] [PATCH i-g-t 1/3] lib/igt_chamelium: add chamelium_trigger_link_failure Simon Ser
2019-08-15  9:59   ` Arkadiusz Hiler
2019-08-13 14:17 ` [igt-dev] [PATCH i-g-t 2/3] lib/igt_kms: add support for link-status Simon Ser
2019-08-13 18:31   ` Manasi Navare
2019-08-13 14:17 ` Simon Ser [this message]
2019-08-13 18:44   ` [igt-dev] [PATCH i-g-t 3/3] tests/kms_chamelium: add a link-status test Manasi Navare
2019-08-13 15:30 ` [igt-dev] ✓ Fi.CI.BAT: success for Chamelium " Patchwork
2019-08-14  0:58 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190813141748.18876-4-simon.ser@intel.com \
    --to=simon.ser@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.