blob: 0c082f9c9c8e7e4c34f85f6b489d38d1e4b40898 [file] [log] [blame]
Lyudec99f8b72016-10-18 14:12:09 -04001/*
2 * Copyright © 2016 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Lyude Paul <lyude@redhat.com>
25 */
26
27#include "config.h"
28#include "igt.h"
29
30#include <fcntl.h>
31#include <string.h>
32
33typedef struct {
34 struct chamelium *chamelium;
35 struct chamelium_port **ports;
Maarten Lankhorst0b735f12017-11-16 11:33:50 +010036 igt_display_t display;
Lyudec99f8b72016-10-18 14:12:09 -040037 int port_count;
38
39 int drm_fd;
40
41 int edid_id;
42 int alt_edid_id;
43} data_t;
44
45#define HOTPLUG_TIMEOUT 20 /* seconds */
Lyudec99f8b72016-10-18 14:12:09 -040046
Lyudea8ea5dd2017-02-22 21:16:16 -050047#define HPD_STORM_PULSE_INTERVAL_DP 100 /* ms */
48#define HPD_STORM_PULSE_INTERVAL_HDMI 200 /* ms */
49
Paul Kocialkowki7d714b22017-06-27 13:53:08 +030050#define HPD_TOGGLE_COUNT_VGA 5
51#define HPD_TOGGLE_COUNT_DP_HDMI 15
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +030052#define HPD_TOGGLE_COUNT_FAST 3
Paul Kocialkowki7d714b22017-06-27 13:53:08 +030053
Lyudec99f8b72016-10-18 14:12:09 -040054static void
Paul Kocialkowskia9443942017-07-18 18:15:52 +030055get_connectors_link_status_failed(data_t *data, bool *link_status_failed)
56{
57 drmModeConnector *connector;
58 uint64_t link_status;
59 drmModePropertyPtr prop;
60 int p;
61
62 for (p = 0; p < data->port_count; p++) {
63 connector = chamelium_port_get_connector(data->chamelium,
64 data->ports[p], false);
65
66 igt_assert(kmstest_get_property(data->drm_fd,
67 connector->connector_id,
68 DRM_MODE_OBJECT_CONNECTOR,
69 "link-status", NULL,
70 &link_status, &prop));
71
72 link_status_failed[p] = link_status == DRM_MODE_LINK_STATUS_BAD;
73
74 drmModeFreeProperty(prop);
75 drmModeFreeConnector(connector);
76 }
77}
78
79static void
Lyudec99f8b72016-10-18 14:12:09 -040080require_connector_present(data_t *data, unsigned int type)
81{
82 int i;
83 bool found = false;
84
85 for (i = 0; i < data->port_count && !found; i++) {
86 if (chamelium_port_get_type(data->ports[i]) == type)
87 found = true;
88 }
89
90 igt_require_f(found, "No port of type %s was found\n",
91 kmstest_connector_type_str(type));
92}
93
94static drmModeConnection
95reprobe_connector(data_t *data, struct chamelium_port *port)
96{
97 drmModeConnector *connector;
98 drmModeConnection status;
99
100 igt_debug("Reprobing %s...\n", chamelium_port_get_name(port));
101 connector = chamelium_port_get_connector(data->chamelium, port, true);
102 igt_assert(connector);
103 status = connector->connection;
104
105 drmModeFreeConnector(connector);
106 return status;
107}
108
109static void
110wait_for_connector(data_t *data, struct chamelium_port *port,
111 drmModeConnection status)
112{
113 bool finished = false;
114
115 igt_debug("Waiting for %s to %sconnect...\n",
116 chamelium_port_get_name(port),
117 status == DRM_MODE_DISCONNECTED ? "dis" : "");
118
119 /*
120 * Rely on simple reprobing so we don't fail tests that don't require
121 * that hpd events work in the event that hpd doesn't work on the system
122 */
123 igt_until_timeout(HOTPLUG_TIMEOUT) {
124 if (reprobe_connector(data, port) == status) {
125 finished = true;
126 return;
127 }
128
Paul Kocialkowki8d300212017-06-26 16:59:02 +0300129 usleep(50000);
Lyudec99f8b72016-10-18 14:12:09 -0400130 }
131
132 igt_assert(finished);
133}
134
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300135static int chamelium_vga_modes[][2] = {
136 { 1600, 1200 },
137 { 1920, 1200 },
138 { 1920, 1080 },
139 { 1680, 1050 },
140 { 1280, 1024 },
141 { 1280, 960 },
142 { 1440, 900 },
143 { 1280, 800 },
144 { 1024, 768 },
145 { 1360, 768 },
146 { 1280, 720 },
147 { 800, 600 },
148 { 640, 480 },
149 { -1, -1 },
150};
151
152static bool
153prune_vga_mode(data_t *data, drmModeModeInfo *mode)
154{
155 int i = 0;
156
157 while (chamelium_vga_modes[i][0] != -1) {
158 if (mode->hdisplay == chamelium_vga_modes[i][0] &&
159 mode->vdisplay == chamelium_vga_modes[i][1])
160 return false;
161
162 i++;
163 }
164
165 return true;
166}
167
168static bool
169check_analog_bridge(data_t *data, struct chamelium_port *port)
170{
171 drmModePropertyBlobPtr edid_blob = NULL;
172 drmModeConnector *connector = chamelium_port_get_connector(
173 data->chamelium, port, false);
174 uint64_t edid_blob_id;
175 unsigned char *edid;
176 char edid_vendor[3];
177
178 if (chamelium_port_get_type(port) != DRM_MODE_CONNECTOR_VGA)
179 return false;
180
181 igt_assert(kmstest_get_property(data->drm_fd, connector->connector_id,
182 DRM_MODE_OBJECT_CONNECTOR, "EDID", NULL,
183 &edid_blob_id, NULL));
184 igt_assert(edid_blob = drmModeGetPropertyBlob(data->drm_fd,
185 edid_blob_id));
186
187 edid = (unsigned char *) edid_blob->data;
188
189 edid_vendor[0] = ((edid[8] & 0x7c) >> 2) + '@';
190 edid_vendor[1] = (((edid[8] & 0x03) << 3) |
191 ((edid[9] & 0xe0) >> 5)) + '@';
192 edid_vendor[2] = (edid[9] & 0x1f) + '@';
193
194 /* Analog bridges provide their own EDID */
195 if (edid_vendor[0] != 'I' || edid_vendor[1] != 'G' ||
196 edid_vendor[0] != 'T')
197 return true;
198
199 drmModeFreePropertyBlob(edid_blob);
200 drmModeFreeConnector(connector);
201
202 return false;
203}
204
Lyudec99f8b72016-10-18 14:12:09 -0400205static void
206reset_state(data_t *data, struct chamelium_port *port)
207{
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300208 int p;
209
Lyudec99f8b72016-10-18 14:12:09 -0400210 chamelium_reset(data->chamelium);
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300211
212 if (port) {
213 wait_for_connector(data, port, DRM_MODE_DISCONNECTED);
214 } else {
215 for (p = 0; p < data->port_count; p++) {
216 port = data->ports[p];
217 wait_for_connector(data, port, DRM_MODE_DISCONNECTED);
218 }
219 }
Lyudec99f8b72016-10-18 14:12:09 -0400220}
221
222static void
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300223test_basic_hotplug(data_t *data, struct chamelium_port *port, int toggle_count)
Lyudec99f8b72016-10-18 14:12:09 -0400224{
225 struct udev_monitor *mon = igt_watch_hotplug();
226 int i;
227
Paul Kocialkowkia22b4b12017-06-26 16:59:01 +0300228 reset_state(data, NULL);
Chris Wilson83884e92017-03-21 17:16:03 +0000229 igt_hpd_storm_set_threshold(data->drm_fd, 0);
Lyudec99f8b72016-10-18 14:12:09 -0400230
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300231 for (i = 0; i < toggle_count; i++) {
Lyudec99f8b72016-10-18 14:12:09 -0400232 igt_flush_hotplugs(mon);
233
234 /* Check if we get a sysfs hotplug event */
235 chamelium_plug(data->chamelium, port);
236 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
237 igt_assert_eq(reprobe_connector(data, port),
238 DRM_MODE_CONNECTED);
239
240 igt_flush_hotplugs(mon);
241
242 /* Now check if we get a hotplug from disconnection */
243 chamelium_unplug(data->chamelium, port);
244 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
245 igt_assert_eq(reprobe_connector(data, port),
246 DRM_MODE_DISCONNECTED);
Lyudec99f8b72016-10-18 14:12:09 -0400247 }
248
249 igt_cleanup_hotplug(mon);
Chris Wilson83884e92017-03-21 17:16:03 +0000250 igt_hpd_storm_reset(data->drm_fd);
Lyudec99f8b72016-10-18 14:12:09 -0400251}
252
253static void
254test_edid_read(data_t *data, struct chamelium_port *port,
255 int edid_id, const unsigned char *edid)
256{
257 drmModePropertyBlobPtr edid_blob = NULL;
258 drmModeConnector *connector = chamelium_port_get_connector(
259 data->chamelium, port, false);
260 uint64_t edid_blob_id;
261
262 reset_state(data, port);
263
264 chamelium_port_set_edid(data->chamelium, port, edid_id);
265 chamelium_plug(data->chamelium, port);
266 wait_for_connector(data, port, DRM_MODE_CONNECTED);
267
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300268 igt_skip_on(check_analog_bridge(data, port));
269
Lyudec99f8b72016-10-18 14:12:09 -0400270 igt_assert(kmstest_get_property(data->drm_fd, connector->connector_id,
271 DRM_MODE_OBJECT_CONNECTOR, "EDID", NULL,
272 &edid_blob_id, NULL));
273 igt_assert(edid_blob = drmModeGetPropertyBlob(data->drm_fd,
274 edid_blob_id));
275
276 igt_assert(memcmp(edid, edid_blob->data, EDID_LENGTH) == 0);
277
278 drmModeFreePropertyBlob(edid_blob);
279 drmModeFreeConnector(connector);
280}
281
282static void
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300283try_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
284 enum igt_suspend_state state, enum igt_suspend_test test,
285 struct udev_monitor *mon, bool connected)
286{
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300287 int delay;
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300288 int p;
289
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300290 igt_flush_hotplugs(mon);
291
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300292 delay = igt_get_autoresume_delay(state) * 1000 / 2;
293
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300294 if (port) {
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300295 chamelium_schedule_hpd_toggle(data->chamelium, port, delay,
Paul Kocialkowkifa8b6ee2017-06-27 13:53:06 +0300296 !connected);
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300297 } else {
298 for (p = 0; p < data->port_count; p++) {
299 port = data->ports[p];
Paul Kocialkowkifa8b6ee2017-06-27 13:53:06 +0300300 chamelium_schedule_hpd_toggle(data->chamelium, port,
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300301 delay, !connected);
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300302 }
303
304 port = NULL;
305 }
306
307 igt_system_suspend_autoresume(state, test);
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300308
309 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
310 if (port) {
311 igt_assert_eq(reprobe_connector(data, port), connected ?
312 DRM_MODE_DISCONNECTED : DRM_MODE_CONNECTED);
313 } else {
314 for (p = 0; p < data->port_count; p++) {
315 port = data->ports[p];
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300316 igt_assert_eq(reprobe_connector(data, port), connected ?
317 DRM_MODE_DISCONNECTED :
318 DRM_MODE_CONNECTED);
319 }
320
321 port = NULL;
322 }
323}
324
325static void
Lyudec99f8b72016-10-18 14:12:09 -0400326test_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
327 enum igt_suspend_state state,
328 enum igt_suspend_test test)
329{
330 struct udev_monitor *mon = igt_watch_hotplug();
331
332 reset_state(data, port);
333
Lyudec99f8b72016-10-18 14:12:09 -0400334 /* Make sure we notice new connectors after resuming */
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300335 try_suspend_resume_hpd(data, port, state, test, mon, false);
Lyudec99f8b72016-10-18 14:12:09 -0400336
337 /* Now make sure we notice disconnected connectors after resuming */
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300338 try_suspend_resume_hpd(data, port, state, test, mon, true);
Lyudec99f8b72016-10-18 14:12:09 -0400339
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300340 igt_cleanup_hotplug(mon);
341}
342
343static void
344test_suspend_resume_hpd_common(data_t *data, enum igt_suspend_state state,
345 enum igt_suspend_test test)
346{
347 struct udev_monitor *mon = igt_watch_hotplug();
348 struct chamelium_port *port;
349 int p;
350
351 for (p = 0; p < data->port_count; p++) {
352 port = data->ports[p];
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300353 igt_debug("Testing port %s\n", chamelium_port_get_name(port));
354 }
355
356 reset_state(data, NULL);
357
358 /* Make sure we notice new connectors after resuming */
359 try_suspend_resume_hpd(data, NULL, state, test, mon, false);
360
361 /* Now make sure we notice disconnected connectors after resuming */
362 try_suspend_resume_hpd(data, NULL, state, test, mon, true);
Lyudec99f8b72016-10-18 14:12:09 -0400363
364 igt_cleanup_hotplug(mon);
365}
366
367static void
368test_suspend_resume_edid_change(data_t *data, struct chamelium_port *port,
369 enum igt_suspend_state state,
370 enum igt_suspend_test test,
371 int edid_id,
372 int alt_edid_id)
373{
374 struct udev_monitor *mon = igt_watch_hotplug();
Paul Kocialkowskia9443942017-07-18 18:15:52 +0300375 bool link_status_failed[2][data->port_count];
376 int p;
Lyudec99f8b72016-10-18 14:12:09 -0400377
378 reset_state(data, port);
379
Paul Kocialkowskifb1ddc42017-07-18 18:16:27 +0300380 /* Catch the event and flush all remaining ones. */
381 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
382 igt_flush_hotplugs(mon);
383
Lyudec99f8b72016-10-18 14:12:09 -0400384 /* First plug in the port */
385 chamelium_port_set_edid(data->chamelium, port, edid_id);
386 chamelium_plug(data->chamelium, port);
Paul Kocialkowskifb1ddc42017-07-18 18:16:27 +0300387 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
Lyudec99f8b72016-10-18 14:12:09 -0400388
Paul Kocialkowskifb1ddc42017-07-18 18:16:27 +0300389 wait_for_connector(data, port, DRM_MODE_CONNECTED);
Lyudec99f8b72016-10-18 14:12:09 -0400390
391 /*
392 * Change the edid before we suspend. On resume, the machine should
393 * notice the EDID change and fire a hotplug event.
394 */
395 chamelium_port_set_edid(data->chamelium, port, alt_edid_id);
396
Paul Kocialkowskia9443942017-07-18 18:15:52 +0300397 get_connectors_link_status_failed(data, link_status_failed[0]);
398
Paul Kocialkowskifb1ddc42017-07-18 18:16:27 +0300399 igt_flush_hotplugs(mon);
400
Lyudec99f8b72016-10-18 14:12:09 -0400401 igt_system_suspend_autoresume(state, test);
Paul Kocialkowskia9443942017-07-18 18:15:52 +0300402
Lyudec99f8b72016-10-18 14:12:09 -0400403 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
Paul Kocialkowskia9443942017-07-18 18:15:52 +0300404
405 get_connectors_link_status_failed(data, link_status_failed[1]);
406
407 for (p = 0; p < data->port_count; p++)
408 igt_skip_on(!link_status_failed[0][p] && link_status_failed[1][p]);
Lyudec99f8b72016-10-18 14:12:09 -0400409}
410
411static igt_output_t *
412prepare_output(data_t *data,
Lyudec99f8b72016-10-18 14:12:09 -0400413 struct chamelium_port *port)
414{
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100415 igt_display_t *display = &data->display;
Lyudec99f8b72016-10-18 14:12:09 -0400416 igt_output_t *output;
417 drmModeRes *res;
418 drmModeConnector *connector =
419 chamelium_port_get_connector(data->chamelium, port, false);
Maarten Lankhorstd6fe4df2017-10-12 13:04:49 +0200420 enum pipe pipe;
421 bool found = false;
Lyudec99f8b72016-10-18 14:12:09 -0400422
Chris Wilson519003c2018-10-03 20:43:49 +0100423 igt_require(res = drmModeGetResources(data->drm_fd));
Lyudec99f8b72016-10-18 14:12:09 -0400424
425 /* The chamelium's default EDID has a lot of resolutions, way more then
426 * we need to test
427 */
428 chamelium_port_set_edid(data->chamelium, port, data->edid_id);
429
430 chamelium_plug(data->chamelium, port);
431 wait_for_connector(data, port, DRM_MODE_CONNECTED);
432
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100433 igt_display_reset(display);
Lyudec99f8b72016-10-18 14:12:09 -0400434
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100435 output = igt_output_from_connector(display, connector);
Maarten Lankhorstd6fe4df2017-10-12 13:04:49 +0200436
437 for_each_pipe(display, pipe) {
438 if (!igt_pipe_connector_valid(pipe, output))
439 continue;
440
441 found = true;
442 break;
443 }
444
445 igt_assert_f(found, "No pipe found for output %s\n", igt_output_name(output));
446
447 igt_output_set_pipe(output, pipe);
Lyudec99f8b72016-10-18 14:12:09 -0400448
449 drmModeFreeConnector(connector);
450 drmModeFreeResources(res);
451
452 return output;
453}
454
455static void
456enable_output(data_t *data,
457 struct chamelium_port *port,
458 igt_output_t *output,
459 drmModeModeInfo *mode,
460 struct igt_fb *fb)
461{
462 igt_display_t *display = output->display;
Petri Latvala26cde2a2017-02-01 12:56:34 +0200463 igt_plane_t *primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Lyudec99f8b72016-10-18 14:12:09 -0400464 drmModeConnector *connector = chamelium_port_get_connector(
465 data->chamelium, port, false);
466
467 igt_assert(primary);
468
469 igt_plane_set_size(primary, mode->hdisplay, mode->vdisplay);
470 igt_plane_set_fb(primary, fb);
471 igt_output_override_mode(output, mode);
472
473 /* Clear any color correction values that might be enabled */
Maarten Lankhorstd7fcd332018-03-05 19:11:15 +0100474 if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_DEGAMMA_LUT))
475 igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0);
476 if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT))
477 igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
478 if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_CTM))
479 igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM, NULL, 0);
Lyudec99f8b72016-10-18 14:12:09 -0400480
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100481 igt_display_commit2(display, COMMIT_ATOMIC);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300482
483 if (chamelium_port_get_type(port) == DRM_MODE_CONNECTOR_VGA)
484 usleep(250000);
485
Lyudec99f8b72016-10-18 14:12:09 -0400486 drmModeFreeConnector(connector);
487}
488
Maxime Ripard9aecda22018-10-04 14:39:06 +0200489static void chamelium_paint_xr24_pattern(uint32_t *data,
490 size_t width, size_t height)
491{
492 uint32_t colors[] = { 0xff000000,
493 0xffff0000,
494 0xff00ff00,
495 0xff0000ff,
496 0xffffffff };
497 unsigned i, j;
498
499 for (i = 0; i < height; i++)
500 for (j = 0; j < width; j++)
501 *(data + i * width + j) = colors[((j / 64) + (i / 64)) % 5];
502}
503
504static int chamelium_get_pattern_fb(data_t *data, drmModeModeInfo *mode,
505 uint32_t fourcc, struct igt_fb *fb)
506{
507 int fb_id;
508 void *ptr;
509
510 igt_assert(fourcc == DRM_FORMAT_XRGB8888);
511
512 fb_id = igt_create_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
513 fourcc, LOCAL_DRM_FORMAT_MOD_NONE, fb);
514 igt_assert(fb_id > 0);
515
516 ptr = igt_fb_map_buffer(fb->fd, fb);
517 igt_assert(ptr);
518
519 chamelium_paint_xr24_pattern(ptr, mode->vdisplay, mode->hdisplay);
520 igt_fb_unmap_buffer(fb, ptr);
521
522 return fb_id;
523}
524
Maxime Ripardc5262912018-10-04 14:39:05 +0200525static void do_test_display_crc(data_t *data, struct chamelium_port *port,
526 igt_output_t *output, drmModeModeInfo *mode,
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200527 uint32_t fourcc, int count)
Lyudec99f8b72016-10-18 14:12:09 -0400528{
Lyudec99f8b72016-10-18 14:12:09 -0400529 igt_crc_t *crc;
Paul Kocialkowskie0802ba2017-07-19 16:46:05 +0300530 igt_crc_t *expected_crc;
531 struct chamelium_fb_crc_async_data *fb_crc;
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200532 struct igt_fb frame_fb, fb;
Maxime Ripardc5262912018-10-04 14:39:05 +0200533 int i, fb_id, captured_frame_count;
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200534 int frame_id;
Maxime Ripardc5262912018-10-04 14:39:05 +0200535
Maxime Ripard9aecda22018-10-04 14:39:06 +0200536 fb_id = chamelium_get_pattern_fb(data, mode,
537 DRM_FORMAT_XRGB8888, &fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200538 igt_assert(fb_id > 0);
539
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200540 frame_id = igt_fb_convert(&frame_fb, &fb, fourcc);
541 igt_assert(frame_id > 0);
542
Maxime Ripardc5262912018-10-04 14:39:05 +0200543 fb_crc = chamelium_calculate_fb_crc_async_start(data->drm_fd,
544 &fb);
545
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200546 enable_output(data, port, output, mode, &frame_fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200547
548 /* We want to keep the display running for a little bit, since
549 * there's always the potential the driver isn't able to keep
550 * the display running properly for very long
551 */
552 chamelium_capture(data->chamelium, port, 0, 0, 0, 0, count);
553 crc = chamelium_read_captured_crcs(data->chamelium,
554 &captured_frame_count);
555
556 igt_assert(captured_frame_count == count);
557
558 igt_debug("Captured %d frames\n", captured_frame_count);
559
560 expected_crc = chamelium_calculate_fb_crc_async_finish(fb_crc);
561
562 for (i = 0; i < captured_frame_count; i++)
563 chamelium_assert_crc_eq_or_dump(data->chamelium,
564 expected_crc, &crc[i],
565 &fb, i);
566
567 free(expected_crc);
568 free(crc);
569
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200570 igt_remove_fb(data->drm_fd, &frame_fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200571 igt_remove_fb(data->drm_fd, &fb);
572}
573
574static void test_display_crc_one_mode(data_t *data, struct chamelium_port *port,
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200575 uint32_t fourcc, int count)
Maxime Ripardc5262912018-10-04 14:39:05 +0200576{
577 igt_output_t *output;
Lyudec99f8b72016-10-18 14:12:09 -0400578 drmModeConnector *connector;
Maxime Ripardc5262912018-10-04 14:39:05 +0200579 igt_plane_t *primary;
Lyudec99f8b72016-10-18 14:12:09 -0400580
Paul Kocialkowski80aa69f2017-07-03 15:01:12 +0300581 reset_state(data, port);
582
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100583 output = prepare_output(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400584 connector = chamelium_port_get_connector(data->chamelium, port, false);
Petri Latvala26cde2a2017-02-01 12:56:34 +0200585 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Lyudec99f8b72016-10-18 14:12:09 -0400586 igt_assert(primary);
587
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200588 do_test_display_crc(data, port, output, &connector->modes[0], fourcc, count);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300589
Maxime Ripardc5262912018-10-04 14:39:05 +0200590 drmModeFreeConnector(connector);
591}
Lyudec99f8b72016-10-18 14:12:09 -0400592
Maxime Ripardc5262912018-10-04 14:39:05 +0200593static void test_display_crc_all_modes(data_t *data, struct chamelium_port *port,
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200594 uint32_t fourcc, int count)
Maxime Ripardc5262912018-10-04 14:39:05 +0200595{
596 igt_output_t *output;
597 igt_plane_t *primary;
598 drmModeConnector *connector;
599 int i;
Lyudec99f8b72016-10-18 14:12:09 -0400600
Maxime Ripardc5262912018-10-04 14:39:05 +0200601 reset_state(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400602
Maxime Ripardc5262912018-10-04 14:39:05 +0200603 output = prepare_output(data, port);
604 connector = chamelium_port_get_connector(data->chamelium, port, false);
605 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
606 igt_assert(primary);
Lyudec99f8b72016-10-18 14:12:09 -0400607
Maxime Ripardc5262912018-10-04 14:39:05 +0200608 for (i = 0; i < connector->count_modes; i++) {
609 drmModeModeInfo *mode = &connector->modes[i];
Paul Kocialkowski4b5ea652017-07-19 16:46:10 +0300610
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200611 do_test_display_crc(data, port, output, mode, fourcc, count);
Lyudec99f8b72016-10-18 14:12:09 -0400612 }
613
614 drmModeFreeConnector(connector);
Lyudec99f8b72016-10-18 14:12:09 -0400615}
616
617static void
618test_display_frame_dump(data_t *data, struct chamelium_port *port)
619{
Lyudec99f8b72016-10-18 14:12:09 -0400620 igt_output_t *output;
621 igt_plane_t *primary;
622 struct igt_fb fb;
623 struct chamelium_frame_dump *frame;
624 drmModeModeInfo *mode;
625 drmModeConnector *connector;
626 int fb_id, i, j;
627
Paul Kocialkowski80aa69f2017-07-03 15:01:12 +0300628 reset_state(data, port);
629
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100630 output = prepare_output(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400631 connector = chamelium_port_get_connector(data->chamelium, port, false);
Petri Latvala26cde2a2017-02-01 12:56:34 +0200632 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Lyudec99f8b72016-10-18 14:12:09 -0400633 igt_assert(primary);
634
635 for (i = 0; i < connector->count_modes; i++) {
636 mode = &connector->modes[i];
637 fb_id = igt_create_color_pattern_fb(data->drm_fd,
638 mode->hdisplay, mode->vdisplay,
639 DRM_FORMAT_XRGB8888,
640 LOCAL_DRM_FORMAT_MOD_NONE,
641 0, 0, 0, &fb);
642 igt_assert(fb_id > 0);
643
644 enable_output(data, port, output, mode, &fb);
645
646 igt_debug("Reading frame dumps from Chamelium...\n");
647 chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 5);
648 for (j = 0; j < 5; j++) {
649 frame = chamelium_read_captured_frame(
650 data->chamelium, j);
651 chamelium_assert_frame_eq(data->chamelium, frame, &fb);
652 chamelium_destroy_frame_dump(frame);
653 }
654
Lyudec99f8b72016-10-18 14:12:09 -0400655 igt_remove_fb(data->drm_fd, &fb);
656 }
657
658 drmModeFreeConnector(connector);
Lyudec99f8b72016-10-18 14:12:09 -0400659}
660
661static void
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300662test_analog_frame_dump(data_t *data, struct chamelium_port *port)
663{
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300664 igt_output_t *output;
665 igt_plane_t *primary;
666 struct igt_fb fb;
667 struct chamelium_frame_dump *frame;
668 drmModeModeInfo *mode;
669 drmModeConnector *connector;
670 int fb_id, i;
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300671 bool bridge;
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300672
Paul Kocialkowski60f6a122017-08-25 15:03:37 +0300673 reset_state(data, port);
674
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100675 output = prepare_output(data, port);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300676 connector = chamelium_port_get_connector(data->chamelium, port, false);
677 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
678 igt_assert(primary);
679
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300680 bridge = check_analog_bridge(data, port);
681
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300682 for (i = 0; i < connector->count_modes; i++) {
683 mode = &connector->modes[i];
684
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300685 if (bridge && prune_vga_mode(data, mode))
686 continue;
687
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300688 fb_id = igt_create_color_pattern_fb(data->drm_fd,
689 mode->hdisplay, mode->vdisplay,
690 DRM_FORMAT_XRGB8888,
691 LOCAL_DRM_FORMAT_MOD_NONE,
692 0, 0, 0, &fb);
693 igt_assert(fb_id > 0);
694
695 enable_output(data, port, output, mode, &fb);
696
697 igt_debug("Reading frame dumps from Chamelium...\n");
698
699 frame = chamelium_port_dump_pixels(data->chamelium, port, 0, 0,
700 0, 0);
701
702 chamelium_crop_analog_frame(frame, mode->hdisplay,
703 mode->vdisplay);
704
705 chamelium_assert_analog_frame_match_or_dump(data->chamelium,
706 port, frame, &fb);
707
708 chamelium_destroy_frame_dump(frame);
709
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300710 igt_remove_fb(data->drm_fd, &fb);
711 }
712
713 drmModeFreeConnector(connector);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300714}
715
716static void
Lyudec99f8b72016-10-18 14:12:09 -0400717test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
718{
719 struct udev_monitor *mon = igt_watch_hotplug();
720
721 reset_state(data, port);
Lyude808a1aa2017-02-01 18:17:49 -0500722 igt_flush_hotplugs(mon);
Lyudec99f8b72016-10-18 14:12:09 -0400723
724 /* Disable the DDC on the connector and make sure we still get a
725 * hotplug
726 */
727 chamelium_port_set_ddc_state(data->chamelium, port, false);
728 chamelium_plug(data->chamelium, port);
729
730 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
731 igt_assert_eq(reprobe_connector(data, port), DRM_MODE_CONNECTED);
732
733 igt_cleanup_hotplug(mon);
734}
735
Lyudea8ea5dd2017-02-22 21:16:16 -0500736static void
737test_hpd_storm_detect(data_t *data, struct chamelium_port *port, int width)
738{
739 struct udev_monitor *mon;
740 int count = 0;
741
Chris Wilson83884e92017-03-21 17:16:03 +0000742 igt_require_hpd_storm_ctl(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500743 reset_state(data, port);
744
Chris Wilson83884e92017-03-21 17:16:03 +0000745 igt_hpd_storm_set_threshold(data->drm_fd, 1);
Lyudea8ea5dd2017-02-22 21:16:16 -0500746 chamelium_fire_hpd_pulses(data->chamelium, port, width, 10);
Chris Wilson83884e92017-03-21 17:16:03 +0000747 igt_assert(igt_hpd_storm_detected(data->drm_fd));
Lyudea8ea5dd2017-02-22 21:16:16 -0500748
749 mon = igt_watch_hotplug();
750 chamelium_fire_hpd_pulses(data->chamelium, port, width, 10);
751
752 /*
753 * Polling should have been enabled by the HPD storm at this point,
754 * so we should only get at most 1 hotplug event
755 */
756 igt_until_timeout(5)
757 count += igt_hotplug_detected(mon, 1);
758 igt_assert_lt(count, 2);
759
760 igt_cleanup_hotplug(mon);
Chris Wilson83884e92017-03-21 17:16:03 +0000761 igt_hpd_storm_reset(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500762}
763
764static void
765test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width)
766{
Chris Wilson83884e92017-03-21 17:16:03 +0000767 igt_require_hpd_storm_ctl(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500768 reset_state(data, port);
769
Chris Wilson83884e92017-03-21 17:16:03 +0000770 igt_hpd_storm_set_threshold(data->drm_fd, 0);
Lyudea8ea5dd2017-02-22 21:16:16 -0500771 chamelium_fire_hpd_pulses(data->chamelium, port,
772 width, 10);
Chris Wilson83884e92017-03-21 17:16:03 +0000773 igt_assert(!igt_hpd_storm_detected(data->drm_fd));
Lyudea8ea5dd2017-02-22 21:16:16 -0500774
Chris Wilson83884e92017-03-21 17:16:03 +0000775 igt_hpd_storm_reset(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500776}
777
Lyudec99f8b72016-10-18 14:12:09 -0400778#define for_each_port(p, port) \
779 for (p = 0, port = data.ports[p]; \
780 p < data.port_count; \
781 p++, port = data.ports[p])
782
783#define connector_subtest(name__, type__) \
784 igt_subtest(name__) \
785 for_each_port(p, port) \
786 if (chamelium_port_get_type(port) == \
787 DRM_MODE_CONNECTOR_ ## type__)
788
789static data_t data;
790
791igt_main
792{
793 struct chamelium_port *port;
794 int edid_id, alt_edid_id, p;
795
796 igt_fixture {
797 igt_skip_on_simulation();
798
799 data.drm_fd = drm_open_driver_master(DRIVER_ANY);
800 data.chamelium = chamelium_init(data.drm_fd);
801 igt_require(data.chamelium);
802
803 data.ports = chamelium_get_ports(data.chamelium,
804 &data.port_count);
805
806 edid_id = chamelium_new_edid(data.chamelium,
807 igt_kms_get_base_edid());
808 alt_edid_id = chamelium_new_edid(data.chamelium,
809 igt_kms_get_alt_edid());
810 data.edid_id = edid_id;
811 data.alt_edid_id = alt_edid_id;
812
813 /* So fbcon doesn't try to reprobe things itself */
814 kmstest_set_vt_graphics_mode();
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100815
Chris Wilson7f41adf2018-09-14 21:10:05 +0100816 igt_display_require(&data.display, data.drm_fd);
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100817 igt_require(data.display.is_atomic);
Lyudec99f8b72016-10-18 14:12:09 -0400818 }
819
820 igt_subtest_group {
821 igt_fixture {
822 require_connector_present(
823 &data, DRM_MODE_CONNECTOR_DisplayPort);
824 }
825
826 connector_subtest("dp-hpd", DisplayPort)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300827 test_basic_hotplug(&data, port,
828 HPD_TOGGLE_COUNT_DP_HDMI);
Lyudec99f8b72016-10-18 14:12:09 -0400829
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +0300830 connector_subtest("dp-hpd-fast", DisplayPort)
831 test_basic_hotplug(&data, port,
832 HPD_TOGGLE_COUNT_FAST);
833
Lyudec99f8b72016-10-18 14:12:09 -0400834 connector_subtest("dp-edid-read", DisplayPort) {
835 test_edid_read(&data, port, edid_id,
836 igt_kms_get_base_edid());
837 test_edid_read(&data, port, alt_edid_id,
838 igt_kms_get_alt_edid());
839 }
840
841 connector_subtest("dp-hpd-after-suspend", DisplayPort)
842 test_suspend_resume_hpd(&data, port,
843 SUSPEND_STATE_MEM,
844 SUSPEND_TEST_NONE);
845
846 connector_subtest("dp-hpd-after-hibernate", DisplayPort)
847 test_suspend_resume_hpd(&data, port,
848 SUSPEND_STATE_DISK,
849 SUSPEND_TEST_DEVICES);
850
Lyudea8ea5dd2017-02-22 21:16:16 -0500851 connector_subtest("dp-hpd-storm", DisplayPort)
852 test_hpd_storm_detect(&data, port,
853 HPD_STORM_PULSE_INTERVAL_DP);
854
855 connector_subtest("dp-hpd-storm-disable", DisplayPort)
856 test_hpd_storm_disable(&data, port,
857 HPD_STORM_PULSE_INTERVAL_DP);
858
Lyudec99f8b72016-10-18 14:12:09 -0400859 connector_subtest("dp-edid-change-during-suspend", DisplayPort)
860 test_suspend_resume_edid_change(&data, port,
861 SUSPEND_STATE_MEM,
862 SUSPEND_TEST_NONE,
863 edid_id, alt_edid_id);
864
865 connector_subtest("dp-edid-change-during-hibernate", DisplayPort)
866 test_suspend_resume_edid_change(&data, port,
867 SUSPEND_STATE_DISK,
868 SUSPEND_TEST_DEVICES,
869 edid_id, alt_edid_id);
870
871 connector_subtest("dp-crc-single", DisplayPort)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200872 test_display_crc_all_modes(&data, port,
873 DRM_FORMAT_XRGB8888, 1);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300874
875 connector_subtest("dp-crc-fast", DisplayPort)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200876 test_display_crc_one_mode(&data, port,
877 DRM_FORMAT_XRGB8888, 1);
Lyudec99f8b72016-10-18 14:12:09 -0400878
879 connector_subtest("dp-crc-multiple", DisplayPort)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200880 test_display_crc_all_modes(&data, port,
881 DRM_FORMAT_XRGB8888, 3);
Lyudec99f8b72016-10-18 14:12:09 -0400882
883 connector_subtest("dp-frame-dump", DisplayPort)
884 test_display_frame_dump(&data, port);
885 }
886
887 igt_subtest_group {
888 igt_fixture {
889 require_connector_present(
890 &data, DRM_MODE_CONNECTOR_HDMIA);
891 }
892
893 connector_subtest("hdmi-hpd", HDMIA)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300894 test_basic_hotplug(&data, port,
895 HPD_TOGGLE_COUNT_DP_HDMI);
Lyudec99f8b72016-10-18 14:12:09 -0400896
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +0300897 connector_subtest("hdmi-hpd-fast", HDMIA)
898 test_basic_hotplug(&data, port,
899 HPD_TOGGLE_COUNT_FAST);
900
Lyudec99f8b72016-10-18 14:12:09 -0400901 connector_subtest("hdmi-edid-read", HDMIA) {
902 test_edid_read(&data, port, edid_id,
903 igt_kms_get_base_edid());
904 test_edid_read(&data, port, alt_edid_id,
905 igt_kms_get_alt_edid());
906 }
907
908 connector_subtest("hdmi-hpd-after-suspend", HDMIA)
909 test_suspend_resume_hpd(&data, port,
910 SUSPEND_STATE_MEM,
911 SUSPEND_TEST_NONE);
912
913 connector_subtest("hdmi-hpd-after-hibernate", HDMIA)
914 test_suspend_resume_hpd(&data, port,
915 SUSPEND_STATE_DISK,
916 SUSPEND_TEST_DEVICES);
917
Lyudea8ea5dd2017-02-22 21:16:16 -0500918 connector_subtest("hdmi-hpd-storm", HDMIA)
919 test_hpd_storm_detect(&data, port,
920 HPD_STORM_PULSE_INTERVAL_HDMI);
921
922 connector_subtest("hdmi-hpd-storm-disable", HDMIA)
923 test_hpd_storm_disable(&data, port,
924 HPD_STORM_PULSE_INTERVAL_HDMI);
925
Lyudec99f8b72016-10-18 14:12:09 -0400926 connector_subtest("hdmi-edid-change-during-suspend", HDMIA)
927 test_suspend_resume_edid_change(&data, port,
928 SUSPEND_STATE_MEM,
929 SUSPEND_TEST_NONE,
930 edid_id, alt_edid_id);
931
932 connector_subtest("hdmi-edid-change-during-hibernate", HDMIA)
933 test_suspend_resume_edid_change(&data, port,
934 SUSPEND_STATE_DISK,
935 SUSPEND_TEST_DEVICES,
936 edid_id, alt_edid_id);
937
938 connector_subtest("hdmi-crc-single", HDMIA)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200939 test_display_crc_all_modes(&data, port,
940 DRM_FORMAT_XRGB8888, 1);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300941
942 connector_subtest("hdmi-crc-fast", HDMIA)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200943 test_display_crc_one_mode(&data, port,
944 DRM_FORMAT_XRGB8888, 1);
Lyudec99f8b72016-10-18 14:12:09 -0400945
946 connector_subtest("hdmi-crc-multiple", HDMIA)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200947 test_display_crc_all_modes(&data, port,
948 DRM_FORMAT_XRGB8888, 3);
Lyudec99f8b72016-10-18 14:12:09 -0400949
950 connector_subtest("hdmi-frame-dump", HDMIA)
951 test_display_frame_dump(&data, port);
952 }
953
954 igt_subtest_group {
955 igt_fixture {
956 require_connector_present(
957 &data, DRM_MODE_CONNECTOR_VGA);
958 }
959
960 connector_subtest("vga-hpd", VGA)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300961 test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_VGA);
Lyudec99f8b72016-10-18 14:12:09 -0400962
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +0300963 connector_subtest("vga-hpd-fast", VGA)
964 test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_FAST);
965
Lyudec99f8b72016-10-18 14:12:09 -0400966 connector_subtest("vga-edid-read", VGA) {
967 test_edid_read(&data, port, edid_id,
968 igt_kms_get_base_edid());
969 test_edid_read(&data, port, alt_edid_id,
970 igt_kms_get_alt_edid());
971 }
972
Paul Kocialkowki2b15b2d2017-06-27 13:53:07 +0300973 connector_subtest("vga-hpd-after-suspend", VGA)
974 test_suspend_resume_hpd(&data, port,
975 SUSPEND_STATE_MEM,
976 SUSPEND_TEST_NONE);
977
978 connector_subtest("vga-hpd-after-hibernate", VGA)
979 test_suspend_resume_hpd(&data, port,
980 SUSPEND_STATE_DISK,
981 SUSPEND_TEST_DEVICES);
Lyudec99f8b72016-10-18 14:12:09 -0400982
983 connector_subtest("vga-hpd-without-ddc", VGA)
984 test_hpd_without_ddc(&data, port);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300985
986 connector_subtest("vga-frame-dump", VGA)
987 test_analog_frame_dump(&data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400988 }
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +0300989
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300990 igt_subtest_group {
991 igt_subtest("common-hpd-after-suspend")
992 test_suspend_resume_hpd_common(&data,
993 SUSPEND_STATE_MEM,
994 SUSPEND_TEST_NONE);
995
996 igt_subtest("common-hpd-after-hibernate")
997 test_suspend_resume_hpd_common(&data,
998 SUSPEND_STATE_DISK,
999 SUSPEND_TEST_DEVICES);
1000 }
1001
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +03001002 igt_fixture {
Maarten Lankhorst0b735f12017-11-16 11:33:50 +01001003 igt_display_fini(&data.display);
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +03001004 close(data.drm_fd);
1005 }
Lyudec99f8b72016-10-18 14:12:09 -04001006}