blob: 55b346a9e1c40e81ec2642a00c9f389057197cfa [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
Paul Kocialkowskif7271fe2018-11-14 16:29:18 +0100178 if (chamelium_port_get_type(port) != DRM_MODE_CONNECTOR_VGA) {
179 drmModeFreeConnector(connector);
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300180 return false;
Paul Kocialkowskif7271fe2018-11-14 16:29:18 +0100181 }
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300182
183 igt_assert(kmstest_get_property(data->drm_fd, connector->connector_id,
184 DRM_MODE_OBJECT_CONNECTOR, "EDID", NULL,
185 &edid_blob_id, NULL));
186 igt_assert(edid_blob = drmModeGetPropertyBlob(data->drm_fd,
187 edid_blob_id));
188
189 edid = (unsigned char *) edid_blob->data;
190
191 edid_vendor[0] = ((edid[8] & 0x7c) >> 2) + '@';
192 edid_vendor[1] = (((edid[8] & 0x03) << 3) |
193 ((edid[9] & 0xe0) >> 5)) + '@';
194 edid_vendor[2] = (edid[9] & 0x1f) + '@';
195
Paul Kocialkowskif7271fe2018-11-14 16:29:18 +0100196 drmModeFreePropertyBlob(edid_blob);
197 drmModeFreeConnector(connector);
198
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300199 /* Analog bridges provide their own EDID */
200 if (edid_vendor[0] != 'I' || edid_vendor[1] != 'G' ||
201 edid_vendor[0] != 'T')
202 return true;
203
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300204 return false;
205}
206
Lyudec99f8b72016-10-18 14:12:09 -0400207static void
208reset_state(data_t *data, struct chamelium_port *port)
209{
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300210 int p;
211
Lyudec99f8b72016-10-18 14:12:09 -0400212 chamelium_reset(data->chamelium);
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300213
214 if (port) {
215 wait_for_connector(data, port, DRM_MODE_DISCONNECTED);
216 } else {
217 for (p = 0; p < data->port_count; p++) {
218 port = data->ports[p];
219 wait_for_connector(data, port, DRM_MODE_DISCONNECTED);
220 }
221 }
Lyudec99f8b72016-10-18 14:12:09 -0400222}
223
224static void
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300225test_basic_hotplug(data_t *data, struct chamelium_port *port, int toggle_count)
Lyudec99f8b72016-10-18 14:12:09 -0400226{
227 struct udev_monitor *mon = igt_watch_hotplug();
228 int i;
229
Paul Kocialkowkia22b4b12017-06-26 16:59:01 +0300230 reset_state(data, NULL);
Chris Wilson83884e92017-03-21 17:16:03 +0000231 igt_hpd_storm_set_threshold(data->drm_fd, 0);
Lyudec99f8b72016-10-18 14:12:09 -0400232
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300233 for (i = 0; i < toggle_count; i++) {
Lyudec99f8b72016-10-18 14:12:09 -0400234 igt_flush_hotplugs(mon);
235
236 /* Check if we get a sysfs hotplug event */
237 chamelium_plug(data->chamelium, port);
238 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
239 igt_assert_eq(reprobe_connector(data, port),
240 DRM_MODE_CONNECTED);
241
242 igt_flush_hotplugs(mon);
243
244 /* Now check if we get a hotplug from disconnection */
245 chamelium_unplug(data->chamelium, port);
246 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
247 igt_assert_eq(reprobe_connector(data, port),
248 DRM_MODE_DISCONNECTED);
Lyudec99f8b72016-10-18 14:12:09 -0400249 }
250
251 igt_cleanup_hotplug(mon);
Chris Wilson83884e92017-03-21 17:16:03 +0000252 igt_hpd_storm_reset(data->drm_fd);
Lyudec99f8b72016-10-18 14:12:09 -0400253}
254
255static void
256test_edid_read(data_t *data, struct chamelium_port *port,
257 int edid_id, const unsigned char *edid)
258{
259 drmModePropertyBlobPtr edid_blob = NULL;
260 drmModeConnector *connector = chamelium_port_get_connector(
261 data->chamelium, port, false);
262 uint64_t edid_blob_id;
263
264 reset_state(data, port);
265
266 chamelium_port_set_edid(data->chamelium, port, edid_id);
267 chamelium_plug(data->chamelium, port);
268 wait_for_connector(data, port, DRM_MODE_CONNECTED);
269
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300270 igt_skip_on(check_analog_bridge(data, port));
271
Lyudec99f8b72016-10-18 14:12:09 -0400272 igt_assert(kmstest_get_property(data->drm_fd, connector->connector_id,
273 DRM_MODE_OBJECT_CONNECTOR, "EDID", NULL,
274 &edid_blob_id, NULL));
275 igt_assert(edid_blob = drmModeGetPropertyBlob(data->drm_fd,
276 edid_blob_id));
277
278 igt_assert(memcmp(edid, edid_blob->data, EDID_LENGTH) == 0);
279
280 drmModeFreePropertyBlob(edid_blob);
281 drmModeFreeConnector(connector);
282}
283
284static void
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300285try_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
286 enum igt_suspend_state state, enum igt_suspend_test test,
287 struct udev_monitor *mon, bool connected)
288{
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300289 int delay;
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300290 int p;
291
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300292 igt_flush_hotplugs(mon);
293
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300294 delay = igt_get_autoresume_delay(state) * 1000 / 2;
295
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300296 if (port) {
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300297 chamelium_schedule_hpd_toggle(data->chamelium, port, delay,
Paul Kocialkowkifa8b6ee2017-06-27 13:53:06 +0300298 !connected);
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300299 } else {
300 for (p = 0; p < data->port_count; p++) {
301 port = data->ports[p];
Paul Kocialkowkifa8b6ee2017-06-27 13:53:06 +0300302 chamelium_schedule_hpd_toggle(data->chamelium, port,
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300303 delay, !connected);
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300304 }
305
306 port = NULL;
307 }
308
309 igt_system_suspend_autoresume(state, test);
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300310
311 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
312 if (port) {
313 igt_assert_eq(reprobe_connector(data, port), connected ?
314 DRM_MODE_DISCONNECTED : DRM_MODE_CONNECTED);
315 } else {
316 for (p = 0; p < data->port_count; p++) {
317 port = data->ports[p];
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300318 igt_assert_eq(reprobe_connector(data, port), connected ?
319 DRM_MODE_DISCONNECTED :
320 DRM_MODE_CONNECTED);
321 }
322
323 port = NULL;
324 }
325}
326
327static void
Lyudec99f8b72016-10-18 14:12:09 -0400328test_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
329 enum igt_suspend_state state,
330 enum igt_suspend_test test)
331{
332 struct udev_monitor *mon = igt_watch_hotplug();
333
334 reset_state(data, port);
335
Lyudec99f8b72016-10-18 14:12:09 -0400336 /* Make sure we notice new connectors after resuming */
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300337 try_suspend_resume_hpd(data, port, state, test, mon, false);
Lyudec99f8b72016-10-18 14:12:09 -0400338
339 /* Now make sure we notice disconnected connectors after resuming */
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300340 try_suspend_resume_hpd(data, port, state, test, mon, true);
Lyudec99f8b72016-10-18 14:12:09 -0400341
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300342 igt_cleanup_hotplug(mon);
343}
344
345static void
346test_suspend_resume_hpd_common(data_t *data, enum igt_suspend_state state,
347 enum igt_suspend_test test)
348{
349 struct udev_monitor *mon = igt_watch_hotplug();
350 struct chamelium_port *port;
351 int p;
352
353 for (p = 0; p < data->port_count; p++) {
354 port = data->ports[p];
Paul Kocialkowkifea6f862017-06-19 12:39:05 +0300355 igt_debug("Testing port %s\n", chamelium_port_get_name(port));
356 }
357
358 reset_state(data, NULL);
359
360 /* Make sure we notice new connectors after resuming */
361 try_suspend_resume_hpd(data, NULL, state, test, mon, false);
362
363 /* Now make sure we notice disconnected connectors after resuming */
364 try_suspend_resume_hpd(data, NULL, state, test, mon, true);
Lyudec99f8b72016-10-18 14:12:09 -0400365
366 igt_cleanup_hotplug(mon);
367}
368
369static void
370test_suspend_resume_edid_change(data_t *data, struct chamelium_port *port,
371 enum igt_suspend_state state,
372 enum igt_suspend_test test,
373 int edid_id,
374 int alt_edid_id)
375{
376 struct udev_monitor *mon = igt_watch_hotplug();
Paul Kocialkowskia9443942017-07-18 18:15:52 +0300377 bool link_status_failed[2][data->port_count];
378 int p;
Lyudec99f8b72016-10-18 14:12:09 -0400379
380 reset_state(data, port);
381
Paul Kocialkowskifb1ddc42017-07-18 18:16:27 +0300382 /* Catch the event and flush all remaining ones. */
383 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
384 igt_flush_hotplugs(mon);
385
Lyudec99f8b72016-10-18 14:12:09 -0400386 /* First plug in the port */
387 chamelium_port_set_edid(data->chamelium, port, edid_id);
388 chamelium_plug(data->chamelium, port);
Paul Kocialkowskifb1ddc42017-07-18 18:16:27 +0300389 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
Lyudec99f8b72016-10-18 14:12:09 -0400390
Paul Kocialkowskifb1ddc42017-07-18 18:16:27 +0300391 wait_for_connector(data, port, DRM_MODE_CONNECTED);
Lyudec99f8b72016-10-18 14:12:09 -0400392
393 /*
394 * Change the edid before we suspend. On resume, the machine should
395 * notice the EDID change and fire a hotplug event.
396 */
397 chamelium_port_set_edid(data->chamelium, port, alt_edid_id);
398
Paul Kocialkowskia9443942017-07-18 18:15:52 +0300399 get_connectors_link_status_failed(data, link_status_failed[0]);
400
Paul Kocialkowskifb1ddc42017-07-18 18:16:27 +0300401 igt_flush_hotplugs(mon);
402
Lyudec99f8b72016-10-18 14:12:09 -0400403 igt_system_suspend_autoresume(state, test);
Paul Kocialkowskia9443942017-07-18 18:15:52 +0300404
Lyudec99f8b72016-10-18 14:12:09 -0400405 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
Paul Kocialkowskia9443942017-07-18 18:15:52 +0300406
407 get_connectors_link_status_failed(data, link_status_failed[1]);
408
409 for (p = 0; p < data->port_count; p++)
410 igt_skip_on(!link_status_failed[0][p] && link_status_failed[1][p]);
Lyudec99f8b72016-10-18 14:12:09 -0400411}
412
413static igt_output_t *
414prepare_output(data_t *data,
Lyudec99f8b72016-10-18 14:12:09 -0400415 struct chamelium_port *port)
416{
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100417 igt_display_t *display = &data->display;
Lyudec99f8b72016-10-18 14:12:09 -0400418 igt_output_t *output;
419 drmModeRes *res;
420 drmModeConnector *connector =
421 chamelium_port_get_connector(data->chamelium, port, false);
Maarten Lankhorstd6fe4df2017-10-12 13:04:49 +0200422 enum pipe pipe;
423 bool found = false;
Lyudec99f8b72016-10-18 14:12:09 -0400424
Chris Wilson519003c2018-10-03 20:43:49 +0100425 igt_require(res = drmModeGetResources(data->drm_fd));
Lyudec99f8b72016-10-18 14:12:09 -0400426
427 /* The chamelium's default EDID has a lot of resolutions, way more then
428 * we need to test
429 */
430 chamelium_port_set_edid(data->chamelium, port, data->edid_id);
431
432 chamelium_plug(data->chamelium, port);
433 wait_for_connector(data, port, DRM_MODE_CONNECTED);
434
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100435 igt_display_reset(display);
Lyudec99f8b72016-10-18 14:12:09 -0400436
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100437 output = igt_output_from_connector(display, connector);
Maarten Lankhorstd6fe4df2017-10-12 13:04:49 +0200438
439 for_each_pipe(display, pipe) {
440 if (!igt_pipe_connector_valid(pipe, output))
441 continue;
442
443 found = true;
444 break;
445 }
446
447 igt_assert_f(found, "No pipe found for output %s\n", igt_output_name(output));
448
449 igt_output_set_pipe(output, pipe);
Lyudec99f8b72016-10-18 14:12:09 -0400450
451 drmModeFreeConnector(connector);
452 drmModeFreeResources(res);
453
454 return output;
455}
456
457static void
458enable_output(data_t *data,
459 struct chamelium_port *port,
460 igt_output_t *output,
461 drmModeModeInfo *mode,
462 struct igt_fb *fb)
463{
464 igt_display_t *display = output->display;
Petri Latvala26cde2a2017-02-01 12:56:34 +0200465 igt_plane_t *primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Lyudec99f8b72016-10-18 14:12:09 -0400466 drmModeConnector *connector = chamelium_port_get_connector(
467 data->chamelium, port, false);
468
469 igt_assert(primary);
470
471 igt_plane_set_size(primary, mode->hdisplay, mode->vdisplay);
472 igt_plane_set_fb(primary, fb);
473 igt_output_override_mode(output, mode);
474
475 /* Clear any color correction values that might be enabled */
Maarten Lankhorstd7fcd332018-03-05 19:11:15 +0100476 if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_DEGAMMA_LUT))
477 igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0);
478 if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT))
479 igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
480 if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_CTM))
481 igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM, NULL, 0);
Lyudec99f8b72016-10-18 14:12:09 -0400482
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100483 igt_display_commit2(display, COMMIT_ATOMIC);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300484
485 if (chamelium_port_get_type(port) == DRM_MODE_CONNECTOR_VGA)
486 usleep(250000);
487
Lyudec99f8b72016-10-18 14:12:09 -0400488 drmModeFreeConnector(connector);
489}
490
Maxime Ripard9aecda22018-10-04 14:39:06 +0200491static void chamelium_paint_xr24_pattern(uint32_t *data,
492 size_t width, size_t height)
493{
494 uint32_t colors[] = { 0xff000000,
495 0xffff0000,
496 0xff00ff00,
497 0xff0000ff,
498 0xffffffff };
499 unsigned i, j;
500
501 for (i = 0; i < height; i++)
502 for (j = 0; j < width; j++)
503 *(data + i * width + j) = colors[((j / 64) + (i / 64)) % 5];
504}
505
506static int chamelium_get_pattern_fb(data_t *data, drmModeModeInfo *mode,
507 uint32_t fourcc, struct igt_fb *fb)
508{
509 int fb_id;
510 void *ptr;
511
512 igt_assert(fourcc == DRM_FORMAT_XRGB8888);
513
514 fb_id = igt_create_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
515 fourcc, LOCAL_DRM_FORMAT_MOD_NONE, fb);
516 igt_assert(fb_id > 0);
517
518 ptr = igt_fb_map_buffer(fb->fd, fb);
519 igt_assert(ptr);
520
521 chamelium_paint_xr24_pattern(ptr, mode->vdisplay, mode->hdisplay);
522 igt_fb_unmap_buffer(fb, ptr);
523
524 return fb_id;
525}
526
Maxime Ripardc5262912018-10-04 14:39:05 +0200527static void do_test_display_crc(data_t *data, struct chamelium_port *port,
528 igt_output_t *output, drmModeModeInfo *mode,
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200529 uint32_t fourcc, int count)
Lyudec99f8b72016-10-18 14:12:09 -0400530{
Lyudec99f8b72016-10-18 14:12:09 -0400531 igt_crc_t *crc;
Paul Kocialkowskie0802ba2017-07-19 16:46:05 +0300532 igt_crc_t *expected_crc;
533 struct chamelium_fb_crc_async_data *fb_crc;
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200534 struct igt_fb frame_fb, fb;
Maxime Ripardc5262912018-10-04 14:39:05 +0200535 int i, fb_id, captured_frame_count;
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200536 int frame_id;
Maxime Ripardc5262912018-10-04 14:39:05 +0200537
Maxime Ripard9aecda22018-10-04 14:39:06 +0200538 fb_id = chamelium_get_pattern_fb(data, mode,
539 DRM_FORMAT_XRGB8888, &fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200540 igt_assert(fb_id > 0);
541
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200542 frame_id = igt_fb_convert(&frame_fb, &fb, fourcc);
543 igt_assert(frame_id > 0);
544
Maxime Ripardc5262912018-10-04 14:39:05 +0200545 fb_crc = chamelium_calculate_fb_crc_async_start(data->drm_fd,
546 &fb);
547
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200548 enable_output(data, port, output, mode, &frame_fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200549
550 /* We want to keep the display running for a little bit, since
551 * there's always the potential the driver isn't able to keep
552 * the display running properly for very long
553 */
554 chamelium_capture(data->chamelium, port, 0, 0, 0, 0, count);
555 crc = chamelium_read_captured_crcs(data->chamelium,
556 &captured_frame_count);
557
558 igt_assert(captured_frame_count == count);
559
560 igt_debug("Captured %d frames\n", captured_frame_count);
561
562 expected_crc = chamelium_calculate_fb_crc_async_finish(fb_crc);
563
564 for (i = 0; i < captured_frame_count; i++)
565 chamelium_assert_crc_eq_or_dump(data->chamelium,
566 expected_crc, &crc[i],
567 &fb, i);
568
569 free(expected_crc);
570 free(crc);
571
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200572 igt_remove_fb(data->drm_fd, &frame_fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200573 igt_remove_fb(data->drm_fd, &fb);
574}
575
576static void test_display_crc_one_mode(data_t *data, struct chamelium_port *port,
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200577 uint32_t fourcc, int count)
Maxime Ripardc5262912018-10-04 14:39:05 +0200578{
579 igt_output_t *output;
Lyudec99f8b72016-10-18 14:12:09 -0400580 drmModeConnector *connector;
Maxime Ripardc5262912018-10-04 14:39:05 +0200581 igt_plane_t *primary;
Lyudec99f8b72016-10-18 14:12:09 -0400582
Paul Kocialkowski80aa69f2017-07-03 15:01:12 +0300583 reset_state(data, port);
584
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100585 output = prepare_output(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400586 connector = chamelium_port_get_connector(data->chamelium, port, false);
Petri Latvala26cde2a2017-02-01 12:56:34 +0200587 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Lyudec99f8b72016-10-18 14:12:09 -0400588 igt_assert(primary);
589
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200590 do_test_display_crc(data, port, output, &connector->modes[0], fourcc, count);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300591
Maxime Ripardc5262912018-10-04 14:39:05 +0200592 drmModeFreeConnector(connector);
593}
Lyudec99f8b72016-10-18 14:12:09 -0400594
Maxime Ripardc5262912018-10-04 14:39:05 +0200595static void test_display_crc_all_modes(data_t *data, struct chamelium_port *port,
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200596 uint32_t fourcc, int count)
Maxime Ripardc5262912018-10-04 14:39:05 +0200597{
598 igt_output_t *output;
599 igt_plane_t *primary;
600 drmModeConnector *connector;
601 int i;
Lyudec99f8b72016-10-18 14:12:09 -0400602
Maxime Ripardc5262912018-10-04 14:39:05 +0200603 reset_state(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400604
Maxime Ripardc5262912018-10-04 14:39:05 +0200605 output = prepare_output(data, port);
606 connector = chamelium_port_get_connector(data->chamelium, port, false);
607 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
608 igt_assert(primary);
Lyudec99f8b72016-10-18 14:12:09 -0400609
Maxime Ripardc5262912018-10-04 14:39:05 +0200610 for (i = 0; i < connector->count_modes; i++) {
611 drmModeModeInfo *mode = &connector->modes[i];
Paul Kocialkowski4b5ea652017-07-19 16:46:10 +0300612
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200613 do_test_display_crc(data, port, output, mode, fourcc, count);
Lyudec99f8b72016-10-18 14:12:09 -0400614 }
615
616 drmModeFreeConnector(connector);
Lyudec99f8b72016-10-18 14:12:09 -0400617}
618
619static void
620test_display_frame_dump(data_t *data, struct chamelium_port *port)
621{
Lyudec99f8b72016-10-18 14:12:09 -0400622 igt_output_t *output;
623 igt_plane_t *primary;
624 struct igt_fb fb;
625 struct chamelium_frame_dump *frame;
626 drmModeModeInfo *mode;
627 drmModeConnector *connector;
628 int fb_id, i, j;
629
Paul Kocialkowski80aa69f2017-07-03 15:01:12 +0300630 reset_state(data, port);
631
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100632 output = prepare_output(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400633 connector = chamelium_port_get_connector(data->chamelium, port, false);
Petri Latvala26cde2a2017-02-01 12:56:34 +0200634 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Lyudec99f8b72016-10-18 14:12:09 -0400635 igt_assert(primary);
636
637 for (i = 0; i < connector->count_modes; i++) {
638 mode = &connector->modes[i];
639 fb_id = igt_create_color_pattern_fb(data->drm_fd,
640 mode->hdisplay, mode->vdisplay,
641 DRM_FORMAT_XRGB8888,
642 LOCAL_DRM_FORMAT_MOD_NONE,
643 0, 0, 0, &fb);
644 igt_assert(fb_id > 0);
645
646 enable_output(data, port, output, mode, &fb);
647
648 igt_debug("Reading frame dumps from Chamelium...\n");
649 chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 5);
650 for (j = 0; j < 5; j++) {
651 frame = chamelium_read_captured_frame(
652 data->chamelium, j);
653 chamelium_assert_frame_eq(data->chamelium, frame, &fb);
654 chamelium_destroy_frame_dump(frame);
655 }
656
Lyudec99f8b72016-10-18 14:12:09 -0400657 igt_remove_fb(data->drm_fd, &fb);
658 }
659
660 drmModeFreeConnector(connector);
Lyudec99f8b72016-10-18 14:12:09 -0400661}
662
663static void
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300664test_analog_frame_dump(data_t *data, struct chamelium_port *port)
665{
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300666 igt_output_t *output;
667 igt_plane_t *primary;
668 struct igt_fb fb;
669 struct chamelium_frame_dump *frame;
670 drmModeModeInfo *mode;
671 drmModeConnector *connector;
672 int fb_id, i;
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300673 bool bridge;
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300674
Paul Kocialkowski60f6a122017-08-25 15:03:37 +0300675 reset_state(data, port);
676
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100677 output = prepare_output(data, port);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300678 connector = chamelium_port_get_connector(data->chamelium, port, false);
679 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
680 igt_assert(primary);
681
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300682 bridge = check_analog_bridge(data, port);
683
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300684 for (i = 0; i < connector->count_modes; i++) {
685 mode = &connector->modes[i];
686
Paul Kocialkowskif8d6afa2017-07-19 16:50:37 +0300687 if (bridge && prune_vga_mode(data, mode))
688 continue;
689
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300690 fb_id = igt_create_color_pattern_fb(data->drm_fd,
691 mode->hdisplay, mode->vdisplay,
692 DRM_FORMAT_XRGB8888,
693 LOCAL_DRM_FORMAT_MOD_NONE,
694 0, 0, 0, &fb);
695 igt_assert(fb_id > 0);
696
697 enable_output(data, port, output, mode, &fb);
698
699 igt_debug("Reading frame dumps from Chamelium...\n");
700
701 frame = chamelium_port_dump_pixels(data->chamelium, port, 0, 0,
702 0, 0);
703
704 chamelium_crop_analog_frame(frame, mode->hdisplay,
705 mode->vdisplay);
706
707 chamelium_assert_analog_frame_match_or_dump(data->chamelium,
708 port, frame, &fb);
709
710 chamelium_destroy_frame_dump(frame);
711
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300712 igt_remove_fb(data->drm_fd, &fb);
713 }
714
715 drmModeFreeConnector(connector);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +0300716}
717
718static void
Lyudec99f8b72016-10-18 14:12:09 -0400719test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
720{
721 struct udev_monitor *mon = igt_watch_hotplug();
722
723 reset_state(data, port);
Lyude808a1aa2017-02-01 18:17:49 -0500724 igt_flush_hotplugs(mon);
Lyudec99f8b72016-10-18 14:12:09 -0400725
726 /* Disable the DDC on the connector and make sure we still get a
727 * hotplug
728 */
729 chamelium_port_set_ddc_state(data->chamelium, port, false);
730 chamelium_plug(data->chamelium, port);
731
732 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
733 igt_assert_eq(reprobe_connector(data, port), DRM_MODE_CONNECTED);
734
735 igt_cleanup_hotplug(mon);
736}
737
Lyudea8ea5dd2017-02-22 21:16:16 -0500738static void
739test_hpd_storm_detect(data_t *data, struct chamelium_port *port, int width)
740{
741 struct udev_monitor *mon;
742 int count = 0;
743
Chris Wilson83884e92017-03-21 17:16:03 +0000744 igt_require_hpd_storm_ctl(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500745 reset_state(data, port);
746
Chris Wilson83884e92017-03-21 17:16:03 +0000747 igt_hpd_storm_set_threshold(data->drm_fd, 1);
Lyudea8ea5dd2017-02-22 21:16:16 -0500748 chamelium_fire_hpd_pulses(data->chamelium, port, width, 10);
Chris Wilson83884e92017-03-21 17:16:03 +0000749 igt_assert(igt_hpd_storm_detected(data->drm_fd));
Lyudea8ea5dd2017-02-22 21:16:16 -0500750
751 mon = igt_watch_hotplug();
752 chamelium_fire_hpd_pulses(data->chamelium, port, width, 10);
753
754 /*
755 * Polling should have been enabled by the HPD storm at this point,
756 * so we should only get at most 1 hotplug event
757 */
758 igt_until_timeout(5)
759 count += igt_hotplug_detected(mon, 1);
760 igt_assert_lt(count, 2);
761
762 igt_cleanup_hotplug(mon);
Chris Wilson83884e92017-03-21 17:16:03 +0000763 igt_hpd_storm_reset(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500764}
765
766static void
767test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width)
768{
Chris Wilson83884e92017-03-21 17:16:03 +0000769 igt_require_hpd_storm_ctl(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500770 reset_state(data, port);
771
Chris Wilson83884e92017-03-21 17:16:03 +0000772 igt_hpd_storm_set_threshold(data->drm_fd, 0);
Lyudea8ea5dd2017-02-22 21:16:16 -0500773 chamelium_fire_hpd_pulses(data->chamelium, port,
774 width, 10);
Chris Wilson83884e92017-03-21 17:16:03 +0000775 igt_assert(!igt_hpd_storm_detected(data->drm_fd));
Lyudea8ea5dd2017-02-22 21:16:16 -0500776
Chris Wilson83884e92017-03-21 17:16:03 +0000777 igt_hpd_storm_reset(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500778}
779
Lyudec99f8b72016-10-18 14:12:09 -0400780#define for_each_port(p, port) \
781 for (p = 0, port = data.ports[p]; \
782 p < data.port_count; \
783 p++, port = data.ports[p])
784
785#define connector_subtest(name__, type__) \
786 igt_subtest(name__) \
787 for_each_port(p, port) \
788 if (chamelium_port_get_type(port) == \
789 DRM_MODE_CONNECTOR_ ## type__)
790
791static data_t data;
792
793igt_main
794{
795 struct chamelium_port *port;
796 int edid_id, alt_edid_id, p;
797
798 igt_fixture {
799 igt_skip_on_simulation();
800
801 data.drm_fd = drm_open_driver_master(DRIVER_ANY);
802 data.chamelium = chamelium_init(data.drm_fd);
803 igt_require(data.chamelium);
804
805 data.ports = chamelium_get_ports(data.chamelium,
806 &data.port_count);
807
808 edid_id = chamelium_new_edid(data.chamelium,
809 igt_kms_get_base_edid());
810 alt_edid_id = chamelium_new_edid(data.chamelium,
811 igt_kms_get_alt_edid());
812 data.edid_id = edid_id;
813 data.alt_edid_id = alt_edid_id;
814
815 /* So fbcon doesn't try to reprobe things itself */
816 kmstest_set_vt_graphics_mode();
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100817
Chris Wilson7f41adf2018-09-14 21:10:05 +0100818 igt_display_require(&data.display, data.drm_fd);
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100819 igt_require(data.display.is_atomic);
Lyudec99f8b72016-10-18 14:12:09 -0400820 }
821
822 igt_subtest_group {
823 igt_fixture {
824 require_connector_present(
825 &data, DRM_MODE_CONNECTOR_DisplayPort);
826 }
827
828 connector_subtest("dp-hpd", DisplayPort)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300829 test_basic_hotplug(&data, port,
830 HPD_TOGGLE_COUNT_DP_HDMI);
Lyudec99f8b72016-10-18 14:12:09 -0400831
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +0300832 connector_subtest("dp-hpd-fast", DisplayPort)
833 test_basic_hotplug(&data, port,
834 HPD_TOGGLE_COUNT_FAST);
835
Lyudec99f8b72016-10-18 14:12:09 -0400836 connector_subtest("dp-edid-read", DisplayPort) {
837 test_edid_read(&data, port, edid_id,
838 igt_kms_get_base_edid());
839 test_edid_read(&data, port, alt_edid_id,
840 igt_kms_get_alt_edid());
841 }
842
843 connector_subtest("dp-hpd-after-suspend", DisplayPort)
844 test_suspend_resume_hpd(&data, port,
845 SUSPEND_STATE_MEM,
846 SUSPEND_TEST_NONE);
847
848 connector_subtest("dp-hpd-after-hibernate", DisplayPort)
849 test_suspend_resume_hpd(&data, port,
850 SUSPEND_STATE_DISK,
851 SUSPEND_TEST_DEVICES);
852
Lyudea8ea5dd2017-02-22 21:16:16 -0500853 connector_subtest("dp-hpd-storm", DisplayPort)
854 test_hpd_storm_detect(&data, port,
855 HPD_STORM_PULSE_INTERVAL_DP);
856
857 connector_subtest("dp-hpd-storm-disable", DisplayPort)
858 test_hpd_storm_disable(&data, port,
859 HPD_STORM_PULSE_INTERVAL_DP);
860
Lyudec99f8b72016-10-18 14:12:09 -0400861 connector_subtest("dp-edid-change-during-suspend", DisplayPort)
862 test_suspend_resume_edid_change(&data, port,
863 SUSPEND_STATE_MEM,
864 SUSPEND_TEST_NONE,
865 edid_id, alt_edid_id);
866
867 connector_subtest("dp-edid-change-during-hibernate", DisplayPort)
868 test_suspend_resume_edid_change(&data, port,
869 SUSPEND_STATE_DISK,
870 SUSPEND_TEST_DEVICES,
871 edid_id, alt_edid_id);
872
873 connector_subtest("dp-crc-single", DisplayPort)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200874 test_display_crc_all_modes(&data, port,
875 DRM_FORMAT_XRGB8888, 1);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300876
877 connector_subtest("dp-crc-fast", DisplayPort)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200878 test_display_crc_one_mode(&data, port,
879 DRM_FORMAT_XRGB8888, 1);
Lyudec99f8b72016-10-18 14:12:09 -0400880
881 connector_subtest("dp-crc-multiple", DisplayPort)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200882 test_display_crc_all_modes(&data, port,
883 DRM_FORMAT_XRGB8888, 3);
Lyudec99f8b72016-10-18 14:12:09 -0400884
885 connector_subtest("dp-frame-dump", DisplayPort)
886 test_display_frame_dump(&data, port);
887 }
888
889 igt_subtest_group {
890 igt_fixture {
891 require_connector_present(
892 &data, DRM_MODE_CONNECTOR_HDMIA);
893 }
894
895 connector_subtest("hdmi-hpd", HDMIA)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300896 test_basic_hotplug(&data, port,
897 HPD_TOGGLE_COUNT_DP_HDMI);
Lyudec99f8b72016-10-18 14:12:09 -0400898
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +0300899 connector_subtest("hdmi-hpd-fast", HDMIA)
900 test_basic_hotplug(&data, port,
901 HPD_TOGGLE_COUNT_FAST);
902
Lyudec99f8b72016-10-18 14:12:09 -0400903 connector_subtest("hdmi-edid-read", HDMIA) {
904 test_edid_read(&data, port, edid_id,
905 igt_kms_get_base_edid());
906 test_edid_read(&data, port, alt_edid_id,
907 igt_kms_get_alt_edid());
908 }
909
910 connector_subtest("hdmi-hpd-after-suspend", HDMIA)
911 test_suspend_resume_hpd(&data, port,
912 SUSPEND_STATE_MEM,
913 SUSPEND_TEST_NONE);
914
915 connector_subtest("hdmi-hpd-after-hibernate", HDMIA)
916 test_suspend_resume_hpd(&data, port,
917 SUSPEND_STATE_DISK,
918 SUSPEND_TEST_DEVICES);
919
Lyudea8ea5dd2017-02-22 21:16:16 -0500920 connector_subtest("hdmi-hpd-storm", HDMIA)
921 test_hpd_storm_detect(&data, port,
922 HPD_STORM_PULSE_INTERVAL_HDMI);
923
924 connector_subtest("hdmi-hpd-storm-disable", HDMIA)
925 test_hpd_storm_disable(&data, port,
926 HPD_STORM_PULSE_INTERVAL_HDMI);
927
Lyudec99f8b72016-10-18 14:12:09 -0400928 connector_subtest("hdmi-edid-change-during-suspend", HDMIA)
929 test_suspend_resume_edid_change(&data, port,
930 SUSPEND_STATE_MEM,
931 SUSPEND_TEST_NONE,
932 edid_id, alt_edid_id);
933
934 connector_subtest("hdmi-edid-change-during-hibernate", HDMIA)
935 test_suspend_resume_edid_change(&data, port,
936 SUSPEND_STATE_DISK,
937 SUSPEND_TEST_DEVICES,
938 edid_id, alt_edid_id);
939
940 connector_subtest("hdmi-crc-single", HDMIA)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200941 test_display_crc_all_modes(&data, port,
942 DRM_FORMAT_XRGB8888, 1);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300943
944 connector_subtest("hdmi-crc-fast", HDMIA)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200945 test_display_crc_one_mode(&data, port,
946 DRM_FORMAT_XRGB8888, 1);
Lyudec99f8b72016-10-18 14:12:09 -0400947
948 connector_subtest("hdmi-crc-multiple", HDMIA)
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200949 test_display_crc_all_modes(&data, port,
950 DRM_FORMAT_XRGB8888, 3);
Lyudec99f8b72016-10-18 14:12:09 -0400951
Maxime Ripard44975912018-10-04 14:39:08 +0200952 connector_subtest("hdmi-crc-argb8888", HDMIA)
953 test_display_crc_one_mode(&data, port,
954 DRM_FORMAT_ARGB8888, 1);
955
956 connector_subtest("hdmi-crc-abgr8888", HDMIA)
957 test_display_crc_one_mode(&data, port,
958 DRM_FORMAT_ABGR8888, 1);
959
960 connector_subtest("hdmi-crc-xrgb8888", HDMIA)
961 test_display_crc_one_mode(&data, port,
962 DRM_FORMAT_XRGB8888, 1);
963
964 connector_subtest("hdmi-crc-xbgr8888", HDMIA)
965 test_display_crc_one_mode(&data, port,
966 DRM_FORMAT_XBGR8888, 1);
967
968 connector_subtest("hdmi-crc-rgb888", HDMIA)
969 test_display_crc_one_mode(&data, port,
970 DRM_FORMAT_RGB888, 1);
971
972 connector_subtest("hdmi-crc-bgr888", HDMIA)
973 test_display_crc_one_mode(&data, port,
974 DRM_FORMAT_BGR888, 1);
975
976 connector_subtest("hdmi-crc-rgb565", HDMIA)
977 test_display_crc_one_mode(&data, port,
978 DRM_FORMAT_RGB565, 1);
979
980 connector_subtest("hdmi-crc-bgr565", HDMIA)
981 test_display_crc_one_mode(&data, port,
982 DRM_FORMAT_BGR565, 1);
983
984 connector_subtest("hdmi-crc-argb1555", HDMIA)
985 test_display_crc_one_mode(&data, port,
986 DRM_FORMAT_ARGB1555, 1);
987
988 connector_subtest("hdmi-crc-xrgb1555", HDMIA)
989 test_display_crc_one_mode(&data, port,
990 DRM_FORMAT_XRGB1555, 1);
991
Lyudec99f8b72016-10-18 14:12:09 -0400992 connector_subtest("hdmi-frame-dump", HDMIA)
993 test_display_frame_dump(&data, port);
994 }
995
996 igt_subtest_group {
997 igt_fixture {
998 require_connector_present(
999 &data, DRM_MODE_CONNECTOR_VGA);
1000 }
1001
1002 connector_subtest("vga-hpd", VGA)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +03001003 test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_VGA);
Lyudec99f8b72016-10-18 14:12:09 -04001004
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +03001005 connector_subtest("vga-hpd-fast", VGA)
1006 test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_FAST);
1007
Lyudec99f8b72016-10-18 14:12:09 -04001008 connector_subtest("vga-edid-read", VGA) {
1009 test_edid_read(&data, port, edid_id,
1010 igt_kms_get_base_edid());
1011 test_edid_read(&data, port, alt_edid_id,
1012 igt_kms_get_alt_edid());
1013 }
1014
Paul Kocialkowki2b15b2d2017-06-27 13:53:07 +03001015 connector_subtest("vga-hpd-after-suspend", VGA)
1016 test_suspend_resume_hpd(&data, port,
1017 SUSPEND_STATE_MEM,
1018 SUSPEND_TEST_NONE);
1019
1020 connector_subtest("vga-hpd-after-hibernate", VGA)
1021 test_suspend_resume_hpd(&data, port,
1022 SUSPEND_STATE_DISK,
1023 SUSPEND_TEST_DEVICES);
Lyudec99f8b72016-10-18 14:12:09 -04001024
1025 connector_subtest("vga-hpd-without-ddc", VGA)
1026 test_hpd_without_ddc(&data, port);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +03001027
1028 connector_subtest("vga-frame-dump", VGA)
1029 test_analog_frame_dump(&data, port);
Lyudec99f8b72016-10-18 14:12:09 -04001030 }
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +03001031
Paul Kocialkowkifea6f862017-06-19 12:39:05 +03001032 igt_subtest_group {
1033 igt_subtest("common-hpd-after-suspend")
1034 test_suspend_resume_hpd_common(&data,
1035 SUSPEND_STATE_MEM,
1036 SUSPEND_TEST_NONE);
1037
1038 igt_subtest("common-hpd-after-hibernate")
1039 test_suspend_resume_hpd_common(&data,
1040 SUSPEND_STATE_DISK,
1041 SUSPEND_TEST_DEVICES);
1042 }
1043
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +03001044 igt_fixture {
Maarten Lankhorst0b735f12017-11-16 11:33:50 +01001045 igt_display_fini(&data.display);
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +03001046 close(data.drm_fd);
1047 }
Lyudec99f8b72016-10-18 14:12:09 -04001048}