blob: fe58aea98e86d267bddb845ac7bd85f47a0ebba3 [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,
Paul Kocialkowskiacaaa8e2018-12-27 15:57:37 +0100492 size_t width, size_t height,
Paul Kocialkowskid28cca32018-12-27 15:57:39 +0100493 size_t stride, size_t block_size)
Maxime Ripard9aecda22018-10-04 14:39:06 +0200494{
495 uint32_t colors[] = { 0xff000000,
496 0xffff0000,
497 0xff00ff00,
498 0xff0000ff,
499 0xffffffff };
500 unsigned i, j;
501
502 for (i = 0; i < height; i++)
503 for (j = 0; j < width; j++)
Paul Kocialkowskid28cca32018-12-27 15:57:39 +0100504 *(data + i * stride / 4 + j) = colors[((j / block_size) + (i / block_size)) % 5];
Maxime Ripard9aecda22018-10-04 14:39:06 +0200505}
506
Paul Kocialkowski7eeb13d2018-12-27 15:57:38 +0100507static int chamelium_get_pattern_fb(data_t *data, size_t width, size_t height,
Paul Kocialkowskid28cca32018-12-27 15:57:39 +0100508 uint32_t fourcc, size_t block_size,
509 struct igt_fb *fb)
Maxime Ripard9aecda22018-10-04 14:39:06 +0200510{
511 int fb_id;
512 void *ptr;
513
514 igt_assert(fourcc == DRM_FORMAT_XRGB8888);
515
Paul Kocialkowski7eeb13d2018-12-27 15:57:38 +0100516 fb_id = igt_create_fb(data->drm_fd, width, height, fourcc,
517 LOCAL_DRM_FORMAT_MOD_NONE, fb);
Maxime Ripard9aecda22018-10-04 14:39:06 +0200518 igt_assert(fb_id > 0);
519
520 ptr = igt_fb_map_buffer(fb->fd, fb);
521 igt_assert(ptr);
522
Paul Kocialkowskid28cca32018-12-27 15:57:39 +0100523 chamelium_paint_xr24_pattern(ptr, width, height, fb->strides[0],
524 block_size);
Maxime Ripard9aecda22018-10-04 14:39:06 +0200525 igt_fb_unmap_buffer(fb, ptr);
526
527 return fb_id;
528}
529
Maxime Ripard28424392019-02-08 14:18:59 +0100530enum chamelium_check {
Maxime Riparde69086d2019-02-08 14:19:00 +0100531 CHAMELIUM_CHECK_ANALOG,
Maxime Ripard28424392019-02-08 14:18:59 +0100532 CHAMELIUM_CHECK_CRC,
533};
534
535static void do_test_display(data_t *data, struct chamelium_port *port,
536 igt_output_t *output, drmModeModeInfo *mode,
537 uint32_t fourcc, enum chamelium_check check,
538 int count)
Lyudec99f8b72016-10-18 14:12:09 -0400539{
Paul Kocialkowskie0802ba2017-07-19 16:46:05 +0300540 struct chamelium_fb_crc_async_data *fb_crc;
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200541 struct igt_fb frame_fb, fb;
Maxime Ripardc5262912018-10-04 14:39:05 +0200542 int i, fb_id, captured_frame_count;
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200543 int frame_id;
Maxime Ripardc5262912018-10-04 14:39:05 +0200544
Paul Kocialkowski7eeb13d2018-12-27 15:57:38 +0100545 fb_id = chamelium_get_pattern_fb(data, mode->hdisplay, mode->vdisplay,
Paul Kocialkowskid28cca32018-12-27 15:57:39 +0100546 DRM_FORMAT_XRGB8888, 64, &fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200547 igt_assert(fb_id > 0);
548
Paul Kocialkowskicf8438a2019-01-24 16:30:48 +0100549 frame_id = igt_fb_convert(&frame_fb, &fb, fourcc,
550 LOCAL_DRM_FORMAT_MOD_NONE);
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200551 igt_assert(frame_id > 0);
552
Maxime Ripard28424392019-02-08 14:18:59 +0100553 if (check == CHAMELIUM_CHECK_CRC)
554 fb_crc = chamelium_calculate_fb_crc_async_start(data->drm_fd,
555 &fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200556
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200557 enable_output(data, port, output, mode, &frame_fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200558
Maxime Ripard28424392019-02-08 14:18:59 +0100559 if (check == CHAMELIUM_CHECK_CRC) {
560 igt_crc_t *expected_crc;
561 igt_crc_t *crc;
Maxime Ripardc5262912018-10-04 14:39:05 +0200562
Maxime Ripard28424392019-02-08 14:18:59 +0100563 /* We want to keep the display running for a little bit, since
564 * there's always the potential the driver isn't able to keep
565 * the display running properly for very long
566 */
567 chamelium_capture(data->chamelium, port, 0, 0, 0, 0, count);
568 crc = chamelium_read_captured_crcs(data->chamelium,
569 &captured_frame_count);
Maxime Ripardc5262912018-10-04 14:39:05 +0200570
Maxime Ripard28424392019-02-08 14:18:59 +0100571 igt_assert(captured_frame_count == count);
Maxime Ripardc5262912018-10-04 14:39:05 +0200572
Maxime Ripard28424392019-02-08 14:18:59 +0100573 igt_debug("Captured %d frames\n", captured_frame_count);
Maxime Ripardc5262912018-10-04 14:39:05 +0200574
Maxime Ripard28424392019-02-08 14:18:59 +0100575 expected_crc = chamelium_calculate_fb_crc_async_finish(fb_crc);
Maxime Ripardc5262912018-10-04 14:39:05 +0200576
Maxime Ripard28424392019-02-08 14:18:59 +0100577 for (i = 0; i < captured_frame_count; i++)
578 chamelium_assert_crc_eq_or_dump(data->chamelium,
579 expected_crc, &crc[i],
580 &fb, i);
581
582 free(expected_crc);
583 free(crc);
Maxime Riparde69086d2019-02-08 14:19:00 +0100584 } else if (check == CHAMELIUM_CHECK_ANALOG) {
585 struct chamelium_frame_dump *dump;
586
587 igt_assert(count == 1);
588
589 dump = chamelium_port_dump_pixels(data->chamelium, port, 0, 0,
590 0, 0);
591 chamelium_crop_analog_frame(dump, mode->hdisplay,
592 mode->vdisplay);
593 chamelium_assert_analog_frame_match_or_dump(data->chamelium,
594 port, dump, &fb);
595 chamelium_destroy_frame_dump(dump);
Maxime Ripard28424392019-02-08 14:18:59 +0100596 }
Maxime Ripardc5262912018-10-04 14:39:05 +0200597
Maxime Ripardc55a8c62018-10-04 14:39:07 +0200598 igt_remove_fb(data->drm_fd, &frame_fb);
Maxime Ripardc5262912018-10-04 14:39:05 +0200599 igt_remove_fb(data->drm_fd, &fb);
600}
601
Maxime Ripard28424392019-02-08 14:18:59 +0100602static void test_display_one_mode(data_t *data, struct chamelium_port *port,
603 uint32_t fourcc, enum chamelium_check check,
604 int count)
Maxime Ripardc5262912018-10-04 14:39:05 +0200605{
Lyudec99f8b72016-10-18 14:12:09 -0400606 drmModeConnector *connector;
Maxime Riparde69086d2019-02-08 14:19:00 +0100607 drmModeModeInfo *mode;
608 igt_output_t *output;
Maxime Ripardc5262912018-10-04 14:39:05 +0200609 igt_plane_t *primary;
Lyudec99f8b72016-10-18 14:12:09 -0400610
Paul Kocialkowski80aa69f2017-07-03 15:01:12 +0300611 reset_state(data, port);
612
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100613 output = prepare_output(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400614 connector = chamelium_port_get_connector(data->chamelium, port, false);
Petri Latvala26cde2a2017-02-01 12:56:34 +0200615 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Lyudec99f8b72016-10-18 14:12:09 -0400616 igt_assert(primary);
617
Maxime Riparde69086d2019-02-08 14:19:00 +0100618 mode = &connector->modes[0];
619 if (check == CHAMELIUM_CHECK_ANALOG) {
620 bool bridge = check_analog_bridge(data, port);
621
622 igt_assert(!(bridge && prune_vga_mode(data, mode)));
623 }
624
625 do_test_display(data, port, output, mode, fourcc, check, count);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300626
Maxime Ripardc5262912018-10-04 14:39:05 +0200627 drmModeFreeConnector(connector);
628}
Lyudec99f8b72016-10-18 14:12:09 -0400629
Maxime Ripard28424392019-02-08 14:18:59 +0100630static void test_display_all_modes(data_t *data, struct chamelium_port *port,
631 uint32_t fourcc, enum chamelium_check check,
632 int count)
Maxime Ripardc5262912018-10-04 14:39:05 +0200633{
634 igt_output_t *output;
635 igt_plane_t *primary;
636 drmModeConnector *connector;
Maxime Riparde69086d2019-02-08 14:19:00 +0100637 bool bridge;
Maxime Ripardc5262912018-10-04 14:39:05 +0200638 int i;
Lyudec99f8b72016-10-18 14:12:09 -0400639
Maxime Ripardc5262912018-10-04 14:39:05 +0200640 reset_state(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400641
Maxime Ripardc5262912018-10-04 14:39:05 +0200642 output = prepare_output(data, port);
643 connector = chamelium_port_get_connector(data->chamelium, port, false);
644 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
645 igt_assert(primary);
Lyudec99f8b72016-10-18 14:12:09 -0400646
Maxime Riparde69086d2019-02-08 14:19:00 +0100647 if (check == CHAMELIUM_CHECK_ANALOG)
648 bridge = check_analog_bridge(data, port);
649
Maxime Ripardc5262912018-10-04 14:39:05 +0200650 for (i = 0; i < connector->count_modes; i++) {
651 drmModeModeInfo *mode = &connector->modes[i];
Paul Kocialkowski4b5ea652017-07-19 16:46:10 +0300652
Maxime Riparde69086d2019-02-08 14:19:00 +0100653 if (check == CHAMELIUM_CHECK_ANALOG && bridge &&
654 prune_vga_mode(data, mode))
655 continue;
656
Maxime Ripard28424392019-02-08 14:18:59 +0100657 do_test_display(data, port, output, mode, fourcc, check, count);
Lyudec99f8b72016-10-18 14:12:09 -0400658 }
659
660 drmModeFreeConnector(connector);
Lyudec99f8b72016-10-18 14:12:09 -0400661}
662
663static void
664test_display_frame_dump(data_t *data, struct chamelium_port *port)
665{
Lyudec99f8b72016-10-18 14:12:09 -0400666 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, j;
673
Paul Kocialkowski80aa69f2017-07-03 15:01:12 +0300674 reset_state(data, port);
675
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100676 output = prepare_output(data, port);
Lyudec99f8b72016-10-18 14:12:09 -0400677 connector = chamelium_port_get_connector(data->chamelium, port, false);
Petri Latvala26cde2a2017-02-01 12:56:34 +0200678 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Lyudec99f8b72016-10-18 14:12:09 -0400679 igt_assert(primary);
680
681 for (i = 0; i < connector->count_modes; i++) {
682 mode = &connector->modes[i];
683 fb_id = igt_create_color_pattern_fb(data->drm_fd,
684 mode->hdisplay, mode->vdisplay,
685 DRM_FORMAT_XRGB8888,
686 LOCAL_DRM_FORMAT_MOD_NONE,
687 0, 0, 0, &fb);
688 igt_assert(fb_id > 0);
689
690 enable_output(data, port, output, mode, &fb);
691
692 igt_debug("Reading frame dumps from Chamelium...\n");
693 chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 5);
694 for (j = 0; j < 5; j++) {
695 frame = chamelium_read_captured_frame(
696 data->chamelium, j);
697 chamelium_assert_frame_eq(data->chamelium, frame, &fb);
698 chamelium_destroy_frame_dump(frame);
699 }
700
Lyudec99f8b72016-10-18 14:12:09 -0400701 igt_remove_fb(data->drm_fd, &fb);
702 }
703
704 drmModeFreeConnector(connector);
Lyudec99f8b72016-10-18 14:12:09 -0400705}
706
707static void
708test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
709{
710 struct udev_monitor *mon = igt_watch_hotplug();
711
712 reset_state(data, port);
Lyude808a1aa2017-02-01 18:17:49 -0500713 igt_flush_hotplugs(mon);
Lyudec99f8b72016-10-18 14:12:09 -0400714
715 /* Disable the DDC on the connector and make sure we still get a
716 * hotplug
717 */
718 chamelium_port_set_ddc_state(data->chamelium, port, false);
719 chamelium_plug(data->chamelium, port);
720
721 igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
722 igt_assert_eq(reprobe_connector(data, port), DRM_MODE_CONNECTED);
723
724 igt_cleanup_hotplug(mon);
725}
726
Lyudea8ea5dd2017-02-22 21:16:16 -0500727static void
728test_hpd_storm_detect(data_t *data, struct chamelium_port *port, int width)
729{
730 struct udev_monitor *mon;
731 int count = 0;
732
Chris Wilson83884e92017-03-21 17:16:03 +0000733 igt_require_hpd_storm_ctl(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500734 reset_state(data, port);
735
Chris Wilson83884e92017-03-21 17:16:03 +0000736 igt_hpd_storm_set_threshold(data->drm_fd, 1);
Lyudea8ea5dd2017-02-22 21:16:16 -0500737 chamelium_fire_hpd_pulses(data->chamelium, port, width, 10);
Chris Wilson83884e92017-03-21 17:16:03 +0000738 igt_assert(igt_hpd_storm_detected(data->drm_fd));
Lyudea8ea5dd2017-02-22 21:16:16 -0500739
740 mon = igt_watch_hotplug();
741 chamelium_fire_hpd_pulses(data->chamelium, port, width, 10);
742
743 /*
744 * Polling should have been enabled by the HPD storm at this point,
745 * so we should only get at most 1 hotplug event
746 */
747 igt_until_timeout(5)
748 count += igt_hotplug_detected(mon, 1);
749 igt_assert_lt(count, 2);
750
751 igt_cleanup_hotplug(mon);
Chris Wilson83884e92017-03-21 17:16:03 +0000752 igt_hpd_storm_reset(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500753}
754
755static void
756test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width)
757{
Chris Wilson83884e92017-03-21 17:16:03 +0000758 igt_require_hpd_storm_ctl(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500759 reset_state(data, port);
760
Chris Wilson83884e92017-03-21 17:16:03 +0000761 igt_hpd_storm_set_threshold(data->drm_fd, 0);
Lyudea8ea5dd2017-02-22 21:16:16 -0500762 chamelium_fire_hpd_pulses(data->chamelium, port,
763 width, 10);
Chris Wilson83884e92017-03-21 17:16:03 +0000764 igt_assert(!igt_hpd_storm_detected(data->drm_fd));
Lyudea8ea5dd2017-02-22 21:16:16 -0500765
Chris Wilson83884e92017-03-21 17:16:03 +0000766 igt_hpd_storm_reset(data->drm_fd);
Lyudea8ea5dd2017-02-22 21:16:16 -0500767}
768
Lyudec99f8b72016-10-18 14:12:09 -0400769#define for_each_port(p, port) \
770 for (p = 0, port = data.ports[p]; \
771 p < data.port_count; \
772 p++, port = data.ports[p])
773
774#define connector_subtest(name__, type__) \
775 igt_subtest(name__) \
776 for_each_port(p, port) \
777 if (chamelium_port_get_type(port) == \
778 DRM_MODE_CONNECTOR_ ## type__)
779
780static data_t data;
781
782igt_main
783{
784 struct chamelium_port *port;
785 int edid_id, alt_edid_id, p;
786
787 igt_fixture {
788 igt_skip_on_simulation();
789
790 data.drm_fd = drm_open_driver_master(DRIVER_ANY);
791 data.chamelium = chamelium_init(data.drm_fd);
792 igt_require(data.chamelium);
793
794 data.ports = chamelium_get_ports(data.chamelium,
795 &data.port_count);
796
797 edid_id = chamelium_new_edid(data.chamelium,
798 igt_kms_get_base_edid());
799 alt_edid_id = chamelium_new_edid(data.chamelium,
800 igt_kms_get_alt_edid());
801 data.edid_id = edid_id;
802 data.alt_edid_id = alt_edid_id;
803
804 /* So fbcon doesn't try to reprobe things itself */
805 kmstest_set_vt_graphics_mode();
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100806
Chris Wilson7f41adf2018-09-14 21:10:05 +0100807 igt_display_require(&data.display, data.drm_fd);
Maarten Lankhorst0b735f12017-11-16 11:33:50 +0100808 igt_require(data.display.is_atomic);
Lyudec99f8b72016-10-18 14:12:09 -0400809 }
810
811 igt_subtest_group {
812 igt_fixture {
813 require_connector_present(
814 &data, DRM_MODE_CONNECTOR_DisplayPort);
815 }
816
817 connector_subtest("dp-hpd", DisplayPort)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300818 test_basic_hotplug(&data, port,
819 HPD_TOGGLE_COUNT_DP_HDMI);
Lyudec99f8b72016-10-18 14:12:09 -0400820
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +0300821 connector_subtest("dp-hpd-fast", DisplayPort)
822 test_basic_hotplug(&data, port,
823 HPD_TOGGLE_COUNT_FAST);
824
Lyudec99f8b72016-10-18 14:12:09 -0400825 connector_subtest("dp-edid-read", DisplayPort) {
826 test_edid_read(&data, port, edid_id,
827 igt_kms_get_base_edid());
828 test_edid_read(&data, port, alt_edid_id,
829 igt_kms_get_alt_edid());
830 }
831
832 connector_subtest("dp-hpd-after-suspend", DisplayPort)
833 test_suspend_resume_hpd(&data, port,
834 SUSPEND_STATE_MEM,
835 SUSPEND_TEST_NONE);
836
837 connector_subtest("dp-hpd-after-hibernate", DisplayPort)
838 test_suspend_resume_hpd(&data, port,
839 SUSPEND_STATE_DISK,
840 SUSPEND_TEST_DEVICES);
841
Lyudea8ea5dd2017-02-22 21:16:16 -0500842 connector_subtest("dp-hpd-storm", DisplayPort)
843 test_hpd_storm_detect(&data, port,
844 HPD_STORM_PULSE_INTERVAL_DP);
845
846 connector_subtest("dp-hpd-storm-disable", DisplayPort)
847 test_hpd_storm_disable(&data, port,
848 HPD_STORM_PULSE_INTERVAL_DP);
849
Lyudec99f8b72016-10-18 14:12:09 -0400850 connector_subtest("dp-edid-change-during-suspend", DisplayPort)
851 test_suspend_resume_edid_change(&data, port,
852 SUSPEND_STATE_MEM,
853 SUSPEND_TEST_NONE,
854 edid_id, alt_edid_id);
855
856 connector_subtest("dp-edid-change-during-hibernate", DisplayPort)
857 test_suspend_resume_edid_change(&data, port,
858 SUSPEND_STATE_DISK,
859 SUSPEND_TEST_DEVICES,
860 edid_id, alt_edid_id);
861
862 connector_subtest("dp-crc-single", DisplayPort)
Maxime Ripard28424392019-02-08 14:18:59 +0100863 test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
864 CHAMELIUM_CHECK_CRC, 1);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300865
866 connector_subtest("dp-crc-fast", DisplayPort)
Maxime Ripard28424392019-02-08 14:18:59 +0100867 test_display_one_mode(&data, port, DRM_FORMAT_XRGB8888,
868 CHAMELIUM_CHECK_CRC, 1);
Lyudec99f8b72016-10-18 14:12:09 -0400869
870 connector_subtest("dp-crc-multiple", DisplayPort)
Maxime Ripard28424392019-02-08 14:18:59 +0100871 test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
872 CHAMELIUM_CHECK_CRC, 3);
Lyudec99f8b72016-10-18 14:12:09 -0400873
874 connector_subtest("dp-frame-dump", DisplayPort)
875 test_display_frame_dump(&data, port);
876 }
877
878 igt_subtest_group {
879 igt_fixture {
880 require_connector_present(
881 &data, DRM_MODE_CONNECTOR_HDMIA);
882 }
883
884 connector_subtest("hdmi-hpd", HDMIA)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +0300885 test_basic_hotplug(&data, port,
886 HPD_TOGGLE_COUNT_DP_HDMI);
Lyudec99f8b72016-10-18 14:12:09 -0400887
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +0300888 connector_subtest("hdmi-hpd-fast", HDMIA)
889 test_basic_hotplug(&data, port,
890 HPD_TOGGLE_COUNT_FAST);
891
Lyudec99f8b72016-10-18 14:12:09 -0400892 connector_subtest("hdmi-edid-read", HDMIA) {
893 test_edid_read(&data, port, edid_id,
894 igt_kms_get_base_edid());
895 test_edid_read(&data, port, alt_edid_id,
896 igt_kms_get_alt_edid());
897 }
898
899 connector_subtest("hdmi-hpd-after-suspend", HDMIA)
900 test_suspend_resume_hpd(&data, port,
901 SUSPEND_STATE_MEM,
902 SUSPEND_TEST_NONE);
903
904 connector_subtest("hdmi-hpd-after-hibernate", HDMIA)
905 test_suspend_resume_hpd(&data, port,
906 SUSPEND_STATE_DISK,
907 SUSPEND_TEST_DEVICES);
908
Lyudea8ea5dd2017-02-22 21:16:16 -0500909 connector_subtest("hdmi-hpd-storm", HDMIA)
910 test_hpd_storm_detect(&data, port,
911 HPD_STORM_PULSE_INTERVAL_HDMI);
912
913 connector_subtest("hdmi-hpd-storm-disable", HDMIA)
914 test_hpd_storm_disable(&data, port,
915 HPD_STORM_PULSE_INTERVAL_HDMI);
916
Lyudec99f8b72016-10-18 14:12:09 -0400917 connector_subtest("hdmi-edid-change-during-suspend", HDMIA)
918 test_suspend_resume_edid_change(&data, port,
919 SUSPEND_STATE_MEM,
920 SUSPEND_TEST_NONE,
921 edid_id, alt_edid_id);
922
923 connector_subtest("hdmi-edid-change-during-hibernate", HDMIA)
924 test_suspend_resume_edid_change(&data, port,
925 SUSPEND_STATE_DISK,
926 SUSPEND_TEST_DEVICES,
927 edid_id, alt_edid_id);
928
929 connector_subtest("hdmi-crc-single", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100930 test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
931 CHAMELIUM_CHECK_CRC, 1);
Paul Kocialkowskic4f1f8a2017-08-23 18:21:13 +0300932
933 connector_subtest("hdmi-crc-fast", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100934 test_display_one_mode(&data, port, DRM_FORMAT_XRGB8888,
935 CHAMELIUM_CHECK_CRC, 1);
Lyudec99f8b72016-10-18 14:12:09 -0400936
937 connector_subtest("hdmi-crc-multiple", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100938 test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
939 CHAMELIUM_CHECK_CRC, 3);
Lyudec99f8b72016-10-18 14:12:09 -0400940
Maxime Ripard44975912018-10-04 14:39:08 +0200941 connector_subtest("hdmi-crc-argb8888", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100942 test_display_one_mode(&data, port, DRM_FORMAT_ARGB8888,
943 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200944
945 connector_subtest("hdmi-crc-abgr8888", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100946 test_display_one_mode(&data, port, DRM_FORMAT_ABGR8888,
947 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200948
949 connector_subtest("hdmi-crc-xrgb8888", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100950 test_display_one_mode(&data, port, DRM_FORMAT_XRGB8888,
951 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200952
953 connector_subtest("hdmi-crc-xbgr8888", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100954 test_display_one_mode(&data, port, DRM_FORMAT_XBGR8888,
955 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200956
957 connector_subtest("hdmi-crc-rgb888", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100958 test_display_one_mode(&data, port, DRM_FORMAT_RGB888,
959 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200960
961 connector_subtest("hdmi-crc-bgr888", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100962 test_display_one_mode(&data, port, DRM_FORMAT_BGR888,
963 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200964
965 connector_subtest("hdmi-crc-rgb565", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100966 test_display_one_mode(&data, port, DRM_FORMAT_RGB565,
967 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200968
969 connector_subtest("hdmi-crc-bgr565", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100970 test_display_one_mode(&data, port, DRM_FORMAT_BGR565,
971 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200972
973 connector_subtest("hdmi-crc-argb1555", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100974 test_display_one_mode(&data, port, DRM_FORMAT_ARGB1555,
975 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200976
977 connector_subtest("hdmi-crc-xrgb1555", HDMIA)
Maxime Ripard28424392019-02-08 14:18:59 +0100978 test_display_one_mode(&data, port, DRM_FORMAT_XRGB1555,
979 CHAMELIUM_CHECK_CRC, 1);
Maxime Ripard44975912018-10-04 14:39:08 +0200980
Maxime Ripardf62577c2019-02-08 14:19:01 +0100981 connector_subtest("hdmi-cmp-nv12", HDMIA)
982 test_display_one_mode(&data, port, DRM_FORMAT_NV12,
983 CHAMELIUM_CHECK_ANALOG, 1);
984
985 connector_subtest("hdmi-cmp-nv16", HDMIA)
986 test_display_one_mode(&data, port, DRM_FORMAT_NV16,
987 CHAMELIUM_CHECK_ANALOG, 1);
988
989 connector_subtest("hdmi-cmp-nv21", HDMIA)
990 test_display_one_mode(&data, port, DRM_FORMAT_NV21,
991 CHAMELIUM_CHECK_ANALOG, 1);
992
993 connector_subtest("hdmi-cmp-nv61", HDMIA)
994 test_display_one_mode(&data, port, DRM_FORMAT_NV61,
995 CHAMELIUM_CHECK_ANALOG, 1);
996
997 connector_subtest("hdmi-cmp-yu12", HDMIA)
998 test_display_one_mode(&data, port, DRM_FORMAT_YUV420,
999 CHAMELIUM_CHECK_ANALOG, 1);
1000
1001 connector_subtest("hdmi-cmp-yu16", HDMIA)
1002 test_display_one_mode(&data, port, DRM_FORMAT_YUV422,
1003 CHAMELIUM_CHECK_ANALOG, 1);
1004
1005 connector_subtest("hdmi-cmp-yv12", HDMIA)
1006 test_display_one_mode(&data, port, DRM_FORMAT_YVU420,
1007 CHAMELIUM_CHECK_ANALOG, 1);
1008
1009 connector_subtest("hdmi-cmp-yv16", HDMIA)
1010 test_display_one_mode(&data, port, DRM_FORMAT_YVU422,
1011 CHAMELIUM_CHECK_ANALOG, 1);
1012
Lyudec99f8b72016-10-18 14:12:09 -04001013 connector_subtest("hdmi-frame-dump", HDMIA)
1014 test_display_frame_dump(&data, port);
1015 }
1016
1017 igt_subtest_group {
1018 igt_fixture {
1019 require_connector_present(
1020 &data, DRM_MODE_CONNECTOR_VGA);
1021 }
1022
1023 connector_subtest("vga-hpd", VGA)
Paul Kocialkowki7d714b22017-06-27 13:53:08 +03001024 test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_VGA);
Lyudec99f8b72016-10-18 14:12:09 -04001025
Paul Kocialkowski4ee824e2017-08-23 18:21:12 +03001026 connector_subtest("vga-hpd-fast", VGA)
1027 test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_FAST);
1028
Lyudec99f8b72016-10-18 14:12:09 -04001029 connector_subtest("vga-edid-read", VGA) {
1030 test_edid_read(&data, port, edid_id,
1031 igt_kms_get_base_edid());
1032 test_edid_read(&data, port, alt_edid_id,
1033 igt_kms_get_alt_edid());
1034 }
1035
Paul Kocialkowki2b15b2d2017-06-27 13:53:07 +03001036 connector_subtest("vga-hpd-after-suspend", VGA)
1037 test_suspend_resume_hpd(&data, port,
1038 SUSPEND_STATE_MEM,
1039 SUSPEND_TEST_NONE);
1040
1041 connector_subtest("vga-hpd-after-hibernate", VGA)
1042 test_suspend_resume_hpd(&data, port,
1043 SUSPEND_STATE_DISK,
1044 SUSPEND_TEST_DEVICES);
Lyudec99f8b72016-10-18 14:12:09 -04001045
1046 connector_subtest("vga-hpd-without-ddc", VGA)
1047 test_hpd_without_ddc(&data, port);
Paul Kocialkowskie246ff02017-07-20 18:13:37 +03001048
1049 connector_subtest("vga-frame-dump", VGA)
Maxime Riparde69086d2019-02-08 14:19:00 +01001050 test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
1051 CHAMELIUM_CHECK_ANALOG, 1);
Lyudec99f8b72016-10-18 14:12:09 -04001052 }
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +03001053
Paul Kocialkowkifea6f862017-06-19 12:39:05 +03001054 igt_subtest_group {
1055 igt_subtest("common-hpd-after-suspend")
1056 test_suspend_resume_hpd_common(&data,
1057 SUSPEND_STATE_MEM,
1058 SUSPEND_TEST_NONE);
1059
1060 igt_subtest("common-hpd-after-hibernate")
1061 test_suspend_resume_hpd_common(&data,
1062 SUSPEND_STATE_DISK,
1063 SUSPEND_TEST_DEVICES);
1064 }
1065
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +03001066 igt_fixture {
Maarten Lankhorst0b735f12017-11-16 11:33:50 +01001067 igt_display_fini(&data.display);
Paul Kocialkowski5d494bd2017-06-12 17:39:35 +03001068 close(data.drm_fd);
1069 }
Lyudec99f8b72016-10-18 14:12:09 -04001070}