tests/pm_pc8: add gem-idle subtest
[platform/upstream/intel-gpu-tools.git] / tests / pm_pc8.c
1 /*
2  * Copyright © 2013 Intel Corporation
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  *    Paulo Zanoni <paulo.r.zanoni@intel.com>
25  *
26  */
27
28 #include <stdio.h>
29 #include <stdint.h>
30 #include <stdbool.h>
31 #include <string.h>
32
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <dirent.h>
36 #include <sys/ioctl.h>
37 #include <sys/mman.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <linux/i2c.h>
41 #include <linux/i2c-dev.h>
42
43 #include "drm.h"
44 #include "drmtest.h"
45 #include "intel_batchbuffer.h"
46 #include "intel_gpu_tools.h"
47 #include "i915_drm.h"
48 #include "igt_kms.h"
49
50 #define MSR_PC8_RES     0x630
51 #define MSR_PC9_RES     0x631
52 #define MSR_PC10_RES    0x632
53
54 #define MAX_CONNECTORS  32
55 #define MAX_ENCODERS    32
56 #define MAX_CRTCS       16
57
58 #define POWER_DIR "/sys/devices/pci0000:00/0000:00:02.0/power"
59
60 enum runtime_pm_status {
61         RUNTIME_PM_STATUS_ACTIVE,
62         RUNTIME_PM_STATUS_SUSPENDED,
63         RUNTIME_PM_STATUS_SUSPENDING,
64         RUNTIME_PM_STATUS_RESUMING,
65         RUNTIME_PM_STATUS_UNKNOWN,
66 };
67
68 enum pc8_status {
69         PC8_ENABLED,
70         PC8_DISABLED
71 };
72
73 enum screen_type {
74         SCREEN_TYPE_LPSP,
75         SCREEN_TYPE_NON_LPSP,
76         SCREEN_TYPE_ANY,
77 };
78
79 /* Wait flags */
80 #define DONT_WAIT       0
81 #define WAIT_STATUS     1
82 #define WAIT_PC8_RES    2
83 #define WAIT_EXTRA      4
84
85 int drm_fd, msr_fd, pm_status_fd, pc8_status_fd;
86 bool has_runtime_pm, has_pc8;
87 struct mode_set_data ms_data;
88 struct scanout_fb *fbs = NULL;
89
90 /* Stuff used when creating FBs and mode setting. */
91 struct mode_set_data {
92         drmModeResPtr res;
93         drmModeConnectorPtr connectors[MAX_CONNECTORS];
94         drmModePropertyBlobPtr edids[MAX_CONNECTORS];
95
96         uint32_t devid;
97 };
98
99 /* Stuff we query at different times so we can compare. */
100 struct compare_data {
101         drmModeResPtr res;
102         drmModeEncoderPtr encoders[MAX_ENCODERS];
103         drmModeConnectorPtr connectors[MAX_CONNECTORS];
104         drmModeCrtcPtr crtcs[MAX_CRTCS];
105         drmModePropertyBlobPtr edids[MAX_CONNECTORS];
106 };
107
108 /* During the stress tests we want to be as fast as possible, so use pre-created
109  * FBs instead of creating them again and again. */
110 struct scanout_fb {
111         uint32_t handle;
112         int width;
113         int height;
114         struct scanout_fb *next;
115 };
116
117 /* If the read fails, then the machine doesn't support PC8+ residencies. */
118 static bool supports_pc8_plus_residencies(void)
119 {
120         int rc;
121         uint64_t val;
122
123         rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC8_RES);
124         if (rc != sizeof(val))
125                 return false;
126         rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC9_RES);
127         if (rc != sizeof(val))
128                 return false;
129         rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC10_RES);
130         if (rc != sizeof(val))
131                 return false;
132
133         return true;
134 }
135
136 static uint64_t get_residency(uint32_t type)
137 {
138         int rc;
139         uint64_t ret;
140
141         rc = pread(msr_fd, &ret, sizeof(uint64_t), type);
142         igt_assert(rc == sizeof(ret));
143
144         return ret;
145 }
146
147 static bool pc8_plus_residency_changed(unsigned int timeout_sec)
148 {
149         unsigned int i;
150         uint64_t res_pc8, res_pc9, res_pc10;
151         int to_sleep = 100 * 1000;
152
153         res_pc8 = get_residency(MSR_PC8_RES);
154         res_pc9 = get_residency(MSR_PC9_RES);
155         res_pc10 = get_residency(MSR_PC10_RES);
156
157         for (i = 0; i < timeout_sec * 1000 * 1000; i += to_sleep) {
158                 if (res_pc8 != get_residency(MSR_PC8_RES) ||
159                     res_pc9 != get_residency(MSR_PC9_RES) ||
160                     res_pc10 != get_residency(MSR_PC10_RES)) {
161                         return true;
162                 }
163                 usleep(to_sleep);
164         }
165
166         return false;
167 }
168
169 static enum pc8_status get_pc8_status(void)
170 {
171         ssize_t n_read;
172         char buf[150]; /* The whole file has less than 100 chars. */
173
174         lseek(pc8_status_fd, 0, SEEK_SET);
175         n_read = read(pc8_status_fd, buf, ARRAY_SIZE(buf));
176         igt_assert(n_read >= 0);
177         buf[n_read] = '\0';
178
179         if (strstr(buf, "\nEnabled: yes\n"))
180                 return PC8_ENABLED;
181         else
182                 return PC8_DISABLED;
183 }
184
185 static bool wait_for_pc8_status(enum pc8_status status)
186 {
187         int i;
188         int hundred_ms = 100 * 1000, ten_s = 10 * 1000 * 1000;
189
190         for (i = 0; i < ten_s; i += hundred_ms) {
191                 if (get_pc8_status() == status)
192                         return true;
193
194                 usleep(hundred_ms);
195         }
196
197         return false;
198 }
199
200 static enum runtime_pm_status get_runtime_pm_status(void)
201 {
202         ssize_t n_read;
203         char buf[32];
204
205         lseek(pm_status_fd, 0, SEEK_SET);
206         n_read = read(pm_status_fd, buf, ARRAY_SIZE(buf));
207         igt_assert(n_read >= 0);
208         buf[n_read] = '\0';
209
210         if (strncmp(buf, "suspended\n", n_read) == 0)
211                 return RUNTIME_PM_STATUS_SUSPENDED;
212         else if (strncmp(buf, "active\n", n_read) == 0)
213                 return RUNTIME_PM_STATUS_ACTIVE;
214         else if (strncmp(buf, "suspending\n", n_read) == 0)
215                 return RUNTIME_PM_STATUS_SUSPENDING;
216         else if (strncmp(buf, "resuming\n", n_read) == 0)
217                 return RUNTIME_PM_STATUS_RESUMING;
218
219         igt_assert_f(false, "Unknown status %s\n", buf);
220         return RUNTIME_PM_STATUS_UNKNOWN;
221 }
222
223 static bool wait_for_pm_status(enum runtime_pm_status status)
224 {
225         int i;
226         int hundred_ms = 100 * 1000, ten_s = 10 * 1000 * 1000;
227
228         for (i = 0; i < ten_s; i += hundred_ms) {
229                 if (get_runtime_pm_status() == status)
230                         return true;
231
232                 usleep(hundred_ms);
233         }
234
235         return false;
236 }
237
238 static bool wait_for_suspended(void)
239 {
240         if (has_pc8 && !has_runtime_pm)
241                 return wait_for_pc8_status(PC8_ENABLED);
242         else
243                 return wait_for_pm_status(RUNTIME_PM_STATUS_SUSPENDED);
244 }
245
246 static bool wait_for_active(void)
247 {
248         if (has_pc8 && !has_runtime_pm)
249                 return wait_for_pc8_status(PC8_DISABLED);
250         else
251                 return wait_for_pm_status(RUNTIME_PM_STATUS_ACTIVE);
252 }
253
254 static void disable_all_screens(struct mode_set_data *data)
255 {
256         int i, rc;
257
258         for (i = 0; i < data->res->count_crtcs; i++) {
259                 rc = drmModeSetCrtc(drm_fd, data->res->crtcs[i], -1, 0, 0,
260                                     NULL, 0, NULL);
261                 igt_assert(rc == 0);
262         }
263 }
264
265 static struct scanout_fb *create_fb(struct mode_set_data *data, int width,
266                                     int height)
267 {
268         struct scanout_fb *fb_info;
269         struct kmstest_fb fb;
270         cairo_t *cr;
271
272         fb_info = malloc(sizeof(struct scanout_fb));
273         igt_assert(fb_info);
274
275         fb_info->handle = kmstest_create_fb(drm_fd, width, height, 32, 24,
276                                             false, &fb);
277         fb_info->width = width;
278         fb_info->height = height;
279         fb_info->next = NULL;
280
281         cr = kmstest_get_cairo_ctx(drm_fd, &fb);
282         kmstest_paint_test_pattern(cr, width, height);
283         cairo_destroy(cr);
284
285         return fb_info;
286 }
287
288 static uint32_t get_fb(struct mode_set_data *data, int width, int height)
289 {
290         struct scanout_fb *fb;
291
292         if (!fbs) {
293                 fbs = create_fb(data, width, height);
294                 return fbs->handle;
295         }
296
297         for (fb = fbs; fb != NULL; fb = fb->next) {
298                 if (fb->width == width && fb->height == height)
299                         return fb->handle;
300
301                 if (!fb->next) {
302                         fb->next = create_fb(data, width, height);
303                         return fb->next->handle;
304                 }
305         }
306         igt_assert(false);
307 }
308
309 static bool enable_one_screen_with_type(struct mode_set_data *data,
310                                         enum screen_type type)
311 {
312         uint32_t crtc_id = 0, buffer_id = 0, connector_id = 0;
313         drmModeModeInfoPtr mode = NULL;
314         int i, rc;
315
316         for (i = 0; i < data->res->count_connectors; i++) {
317                 drmModeConnectorPtr c = data->connectors[i];
318
319                 if (type == SCREEN_TYPE_LPSP &&
320                     c->connector_type != DRM_MODE_CONNECTOR_eDP)
321                         continue;
322
323                 if (type == SCREEN_TYPE_NON_LPSP &&
324                     c->connector_type == DRM_MODE_CONNECTOR_eDP)
325                         continue;
326
327                 if (c->connection == DRM_MODE_CONNECTED && c->count_modes) {
328                         connector_id = c->connector_id;
329                         mode = &c->modes[0];
330                         break;
331                 }
332         }
333
334         if (connector_id == 0)
335                 return false;
336
337         crtc_id = data->res->crtcs[0];
338         buffer_id = get_fb(data, mode->hdisplay, mode->vdisplay);
339
340         igt_assert(crtc_id);
341         igt_assert(buffer_id);
342         igt_assert(connector_id);
343         igt_assert(mode);
344
345         rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id,
346                             1, mode);
347         igt_assert(rc == 0);
348
349         return true;
350 }
351
352 static void enable_one_screen(struct mode_set_data *data)
353 {
354         igt_assert(enable_one_screen_with_type(data, SCREEN_TYPE_ANY));
355 }
356
357 static drmModePropertyBlobPtr get_connector_edid(drmModeConnectorPtr connector,
358                                                  int index)
359 {
360         unsigned int i;
361         drmModeObjectPropertiesPtr props;
362         drmModePropertyBlobPtr ret = NULL;
363
364         props = drmModeObjectGetProperties(drm_fd, connector->connector_id,
365                                            DRM_MODE_OBJECT_CONNECTOR);
366
367         for (i = 0; i < props->count_props; i++) {
368                 drmModePropertyPtr prop = drmModeGetProperty(drm_fd,
369                                                              props->props[i]);
370
371                 if (strcmp(prop->name, "EDID") == 0) {
372                         igt_assert(prop->flags & DRM_MODE_PROP_BLOB);
373                         igt_assert(prop->count_blobs == 0);
374                         ret = drmModeGetPropertyBlob(drm_fd,
375                                                      props->prop_values[i]);
376                 }
377
378                 drmModeFreeProperty(prop);
379         }
380
381         drmModeFreeObjectProperties(props);
382         return ret;
383 }
384
385 static void init_mode_set_data(struct mode_set_data *data)
386 {
387         int i;
388
389         data->res = drmModeGetResources(drm_fd);
390         igt_assert(data->res);
391         igt_assert(data->res->count_connectors <= MAX_CONNECTORS);
392
393         for (i = 0; i < data->res->count_connectors; i++) {
394                 data->connectors[i] = drmModeGetConnector(drm_fd,
395                                                 data->res->connectors[i]);
396                 data->edids[i] = get_connector_edid(data->connectors[i], i);
397         }
398
399         data->devid = intel_get_drm_devid(drm_fd);
400
401         igt_set_vt_graphics_mode();
402 }
403
404 static void fini_mode_set_data(struct mode_set_data *data)
405 {
406         int i;
407
408         for (i = 0; i < data->res->count_connectors; i++) {
409                 drmModeFreeConnector(data->connectors[i]);
410                 drmModeFreePropertyBlob(data->edids[i]);
411         }
412         drmModeFreeResources(data->res);
413 }
414
415 static void get_drm_info(struct compare_data *data)
416 {
417         int i;
418
419         data->res = drmModeGetResources(drm_fd);
420         igt_assert(data->res);
421
422         igt_assert(data->res->count_connectors <= MAX_CONNECTORS);
423         igt_assert(data->res->count_encoders <= MAX_ENCODERS);
424         igt_assert(data->res->count_crtcs <= MAX_CRTCS);
425
426         for (i = 0; i < data->res->count_connectors; i++) {
427                 data->connectors[i] = drmModeGetConnector(drm_fd,
428                                                 data->res->connectors[i]);
429                 data->edids[i] = get_connector_edid(data->connectors[i], i);
430         }
431         for (i = 0; i < data->res->count_encoders; i++)
432                 data->encoders[i] = drmModeGetEncoder(drm_fd,
433                                                 data->res->encoders[i]);
434         for (i = 0; i < data->res->count_crtcs; i++)
435                 data->crtcs[i] = drmModeGetCrtc(drm_fd, data->res->crtcs[i]);
436 }
437
438 static void free_drm_info(struct compare_data *data)
439 {
440         int i;
441
442         for (i = 0; i < data->res->count_connectors; i++) {
443                 drmModeFreeConnector(data->connectors[i]);
444                 drmModeFreePropertyBlob(data->edids[i]);
445         }
446         for (i = 0; i < data->res->count_encoders; i++)
447                 drmModeFreeEncoder(data->encoders[i]);
448         for (i = 0; i < data->res->count_crtcs; i++)
449                 drmModeFreeCrtc(data->crtcs[i]);
450
451         drmModeFreeResources(data->res);
452 }
453
454 #define COMPARE(d1, d2, data) igt_assert(d1->data == d2->data)
455 #define COMPARE_ARRAY(d1, d2, size, data) do { \
456         for (i = 0; i < size; i++) \
457                 igt_assert(d1->data[i] == d2->data[i]); \
458 } while (0)
459
460 static void assert_drm_resources_equal(struct compare_data *d1,
461                                        struct compare_data *d2)
462 {
463         COMPARE(d1, d2, res->count_connectors);
464         COMPARE(d1, d2, res->count_encoders);
465         COMPARE(d1, d2, res->count_crtcs);
466         COMPARE(d1, d2, res->min_width);
467         COMPARE(d1, d2, res->max_width);
468         COMPARE(d1, d2, res->min_height);
469         COMPARE(d1, d2, res->max_height);
470 }
471
472 static void assert_modes_equal(drmModeModeInfoPtr m1, drmModeModeInfoPtr m2)
473 {
474         COMPARE(m1, m2, clock);
475         COMPARE(m1, m2, hdisplay);
476         COMPARE(m1, m2, hsync_start);
477         COMPARE(m1, m2, hsync_end);
478         COMPARE(m1, m2, htotal);
479         COMPARE(m1, m2, hskew);
480         COMPARE(m1, m2, vdisplay);
481         COMPARE(m1, m2, vsync_start);
482         COMPARE(m1, m2, vsync_end);
483         COMPARE(m1, m2, vtotal);
484         COMPARE(m1, m2, vscan);
485         COMPARE(m1, m2, vrefresh);
486         COMPARE(m1, m2, flags);
487         COMPARE(m1, m2, type);
488         igt_assert(strcmp(m1->name, m2->name) == 0);
489 }
490
491 static void assert_drm_connectors_equal(drmModeConnectorPtr c1,
492                                         drmModeConnectorPtr c2)
493 {
494         int i;
495
496         COMPARE(c1, c2, connector_id);
497         COMPARE(c1, c2, connector_type);
498         COMPARE(c1, c2, connector_type_id);
499         COMPARE(c1, c2, mmWidth);
500         COMPARE(c1, c2, mmHeight);
501         COMPARE(c1, c2, count_modes);
502         COMPARE(c1, c2, count_props);
503         COMPARE(c1, c2, count_encoders);
504         COMPARE_ARRAY(c1, c2, c1->count_props, props);
505         COMPARE_ARRAY(c1, c2, c1->count_encoders, encoders);
506
507         for (i = 0; i < c1->count_modes; i++)
508                 assert_modes_equal(&c1->modes[0], &c2->modes[0]);
509 }
510
511 static void assert_drm_encoders_equal(drmModeEncoderPtr e1,
512                                       drmModeEncoderPtr e2)
513 {
514         COMPARE(e1, e2, encoder_id);
515         COMPARE(e1, e2, encoder_type);
516         COMPARE(e1, e2, possible_crtcs);
517         COMPARE(e1, e2, possible_clones);
518 }
519
520 static void assert_drm_crtcs_equal(drmModeCrtcPtr c1, drmModeCrtcPtr c2)
521 {
522         COMPARE(c1, c2, crtc_id);
523 }
524
525 static void assert_drm_edids_equal(drmModePropertyBlobPtr e1,
526                                    drmModePropertyBlobPtr e2)
527 {
528         if (!e1 && !e2)
529                 return;
530         igt_assert(e1 && e2);
531
532         COMPARE(e1, e2, id);
533         COMPARE(e1, e2, length);
534
535         igt_assert(memcmp(e1->data, e2->data, e1->length) == 0);
536 }
537
538 static void assert_drm_infos_equal(struct compare_data *d1,
539                                    struct compare_data *d2)
540 {
541         int i;
542
543         assert_drm_resources_equal(d1, d2);
544
545         for (i = 0; i < d1->res->count_connectors; i++) {
546                 assert_drm_connectors_equal(d1->connectors[i],
547                                             d2->connectors[i]);
548                 assert_drm_edids_equal(d1->edids[i], d2->edids[i]);
549         }
550
551         for (i = 0; i < d1->res->count_encoders; i++)
552                 assert_drm_encoders_equal(d1->encoders[i], d2->encoders[i]);
553
554         for (i = 0; i < d1->res->count_crtcs; i++)
555                 assert_drm_crtcs_equal(d1->crtcs[i], d2->crtcs[i]);
556 }
557
558 /* We could check the checksum too, but just the header is probably enough. */
559 static bool edid_is_valid(const unsigned char *edid)
560 {
561         char edid_header[] = {
562                 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
563         };
564
565         return (memcmp(edid, edid_header, sizeof(edid_header)) == 0);
566 }
567
568 static int count_drm_valid_edids(struct mode_set_data *data)
569 {
570         int i, ret = 0;
571
572         for (i = 0; i < data->res->count_connectors; i++)
573                 if (data->edids[i] && edid_is_valid(data->edids[i]->data))
574                         ret++;
575         return ret;
576 }
577
578 static bool i2c_edid_is_valid(int fd)
579 {
580         int rc;
581         unsigned char edid[128] = {};
582         struct i2c_msg msgs[] = {
583                 { /* Start at 0. */
584                         .addr = 0x50,
585                         .flags = 0,
586                         .len = 1,
587                         .buf = edid,
588                 }, { /* Now read the EDID. */
589                         .addr = 0x50,
590                         .flags = I2C_M_RD,
591                         .len = 128,
592                         .buf = edid,
593                 }
594         };
595         struct i2c_rdwr_ioctl_data msgset = {
596                 .msgs = msgs,
597                 .nmsgs = 2,
598         };
599
600         rc = ioctl(fd, I2C_RDWR, &msgset);
601         return (rc >= 0) ? edid_is_valid(edid) : false;
602 }
603
604 static int count_i2c_valid_edids(void)
605 {
606         int fd, ret = 0;
607         DIR *dir;
608
609         struct dirent *dirent;
610         char full_name[32];
611
612         dir = opendir("/dev/");
613         igt_assert(dir);
614
615         while ((dirent = readdir(dir))) {
616                 if (strncmp(dirent->d_name, "i2c-", 4) == 0) {
617                         snprintf(full_name, 32, "/dev/%s", dirent->d_name);
618                         fd = open(full_name, O_RDWR);
619                         igt_assert(fd != -1);
620                         if (i2c_edid_is_valid(fd))
621                                 ret++;
622                         close(fd);
623                 }
624         }
625
626         closedir(dir);
627
628         return ret;
629 }
630
631 static void test_i2c(struct mode_set_data *data)
632 {
633         int i2c_edids = count_i2c_valid_edids();
634         int drm_edids = count_drm_valid_edids(data);
635
636         igt_assert(i2c_edids == drm_edids);
637 }
638
639 static void setup_runtime_pm(void)
640 {
641         int fd;
642         ssize_t size;
643         char buf[6];
644
645         /* Our implementation uses autosuspend. Try to set it to 0ms so the test
646          * suite goes faster and we have a higher probability of triggering race
647          * conditions. */
648         fd = open(POWER_DIR "/autosuspend_delay_ms", O_WRONLY);
649         igt_assert_f(fd >= 0,
650                      "Can't open " POWER_DIR "/autosuspend_delay_ms\n");
651
652         /* If we fail to write to the file, it means this system doesn't support
653          * runtime PM. */
654         size = write(fd, "0\n", 2);
655         has_runtime_pm = (size == 2);
656
657         close(fd);
658
659         if (!has_runtime_pm)
660                 return;
661
662         /* We know we support runtime PM, let's try to enable it now. */
663         fd = open(POWER_DIR "/control", O_RDWR);
664         igt_assert_f(fd >= 0, "Can't open " POWER_DIR "/control\n");
665
666         size = write(fd, "auto\n", 5);
667         igt_assert(size == 5);
668
669         lseek(fd, 0, SEEK_SET);
670         size = read(fd, buf, ARRAY_SIZE(buf));
671         igt_assert(size == 5);
672         igt_assert(strncmp(buf, "auto\n", 5) == 0);
673
674         close(fd);
675
676         pm_status_fd = open(POWER_DIR "/runtime_status", O_RDONLY);
677         igt_assert_f(pm_status_fd >= 0,
678                      "Can't open " POWER_DIR "/runtime_status\n");
679 }
680
681 static void setup_pc8(void)
682 {
683         has_pc8 = false;
684
685         /* Only Haswell supports the PC8 feature. */
686         if (!IS_HASWELL(ms_data.devid))
687                 return;
688
689         /* Make sure our Kernel supports MSR and the module is loaded. */
690         msr_fd = open("/dev/cpu/0/msr", O_RDONLY);
691         igt_assert_f(msr_fd >= 0,
692                      "Can't open /dev/cpu/0/msr.\n");
693
694         /* Non-ULT machines don't support PC8+. */
695         if (!supports_pc8_plus_residencies())
696                 return;
697
698         pc8_status_fd = open("/sys/kernel/debug/dri/0/i915_pc8_status",
699                              O_RDONLY);
700         igt_assert_f(pc8_status_fd >= 0,
701                      "Can't open /sys/kernel/debug/dri/0/i915_pc8_status");
702
703         has_pc8 = true;
704 }
705
706 /* If we want to actually reach PC8+ states, we need to properly configure all
707  * the devices on the system to allow this. This function will try to setup the
708  * things we know we need, but won't scream in case anything fails: we don't
709  * know which devices are present on your machine, so we can't really expect
710  * anything, just try to help with the more common problems. */
711 static void setup_non_graphics_runtime_pm(void)
712 {
713         int fd, i;
714         char *file_name;
715
716         /* Disk runtime PM policies. */
717         file_name = malloc(PATH_MAX);
718         for (i = 0; ; i++) {
719
720                 snprintf(file_name, PATH_MAX,
721                          "/sys/class/scsi_host/host%d/link_power_management_policy",
722                          i);
723
724                 fd = open(file_name, O_WRONLY);
725                 if (fd < 0)
726                         break;
727
728                 write(fd, "min_power\n", 10);
729                 close(fd);
730         }
731         free(file_name);
732
733         /* Audio runtime PM policies. */
734         fd = open("/sys/module/snd_hda_intel/parameters/power_save", O_WRONLY);
735         if (fd >= 0) {
736                 write(fd, "1\n", 2);
737                 close(fd);
738         }
739         fd = open("/sys/bus/pci/devices/0000:00:03.0/power/control", O_WRONLY);
740         if (fd >= 0) {
741                 write(fd, "auto\n", 5);
742                 close(fd);
743         }
744 }
745
746 static void setup_environment(void)
747 {
748         drm_fd = drm_open_any();
749         igt_assert(drm_fd >= 0);
750
751         igt_require_f(drmSetMaster(drm_fd) == 0, "Can't become DRM master, "
752                       "please check if no other DRM client is running.\n");
753
754         init_mode_set_data(&ms_data);
755
756         setup_non_graphics_runtime_pm();
757
758         setup_runtime_pm();
759         setup_pc8();
760
761         printf("Runtime PM support: %d\n", has_runtime_pm);
762         printf("PC8 residency support: %d\n", has_pc8);
763
764         igt_require(has_runtime_pm || has_pc8);
765 }
766
767 static void teardown_environment(void)
768 {
769         struct scanout_fb *fb, *fb_next;
770
771         fb = fbs;
772         while (fb) {
773                 fb_next = fb->next;
774                 free(fb);
775                 fb = fb_next;
776         }
777
778         fini_mode_set_data(&ms_data);
779         drmClose(drm_fd);
780         close(msr_fd);
781         if (has_runtime_pm)
782                 close(pm_status_fd);
783         if (has_pc8)
784                 close(pc8_status_fd);
785 }
786
787 static void basic_subtest(void)
788 {
789         disable_all_screens(&ms_data);
790         igt_assert(wait_for_suspended());
791
792         enable_one_screen(&ms_data);
793         igt_assert(wait_for_active());
794 }
795
796 static void pc8_residency_subtest(void)
797 {
798         igt_require(has_pc8);
799
800         /* Make sure PC8+ residencies move! */
801         disable_all_screens(&ms_data);
802         igt_assert_f(pc8_plus_residency_changed(120),
803                      "Machine is not reaching PC8+ states, please check its "
804                      "configuration.\n");
805
806         /* Make sure PC8+ residencies stop! */
807         enable_one_screen(&ms_data);
808         igt_assert_f(!pc8_plus_residency_changed(10),
809                      "PC8+ residency didn't stop with screen enabled.\n");
810 }
811
812 static void modeset_subtest(enum screen_type type, int rounds, int wait_flags)
813 {
814         int i;
815
816         if (wait_flags & WAIT_PC8_RES)
817                 igt_require(has_pc8);
818
819         for (i = 0; i < rounds; i++) {
820                 disable_all_screens(&ms_data);
821                 if (wait_flags & WAIT_STATUS)
822                         igt_assert(wait_for_suspended());
823                 if (wait_flags & WAIT_PC8_RES)
824                         igt_assert(pc8_plus_residency_changed(120));
825                 if (wait_flags & WAIT_EXTRA)
826                         sleep(5);
827
828                 /* If we skip this line it's because the type of screen we want
829                  * is not connected. */
830                 igt_require(enable_one_screen_with_type(&ms_data, type));
831                 if (wait_flags & WAIT_STATUS)
832                         igt_assert(wait_for_active());
833                 if (wait_flags & WAIT_PC8_RES)
834                         igt_assert(!pc8_plus_residency_changed(5));
835                 if (wait_flags & WAIT_EXTRA)
836                         sleep(5);
837         }
838 }
839
840 /* Test of the DRM resources reported by the IOCTLs are still the same. This
841  * ensures we still see the monitors with the same eyes. We get the EDIDs and
842  * compare them, which ensures we use DP AUX or GMBUS depending on what's
843  * connected. */
844 static void drm_resources_equal_subtest(void)
845 {
846         struct compare_data pre_suspend, during_suspend, post_suspend;
847
848         enable_one_screen(&ms_data);
849         igt_assert(wait_for_active());
850         get_drm_info(&pre_suspend);
851         igt_assert(wait_for_active());
852
853         disable_all_screens(&ms_data);
854         igt_assert(wait_for_suspended());
855         get_drm_info(&during_suspend);
856         igt_assert(wait_for_suspended());
857
858         enable_one_screen(&ms_data);
859         igt_assert(wait_for_active());
860         get_drm_info(&post_suspend);
861         igt_assert(wait_for_active());
862
863         assert_drm_infos_equal(&pre_suspend, &during_suspend);
864         assert_drm_infos_equal(&pre_suspend, &post_suspend);
865
866         free_drm_info(&pre_suspend);
867         free_drm_info(&during_suspend);
868         free_drm_info(&post_suspend);
869 }
870
871 static void i2c_subtest_check_environment(void)
872 {
873         int i2c_dev_files = 0;
874         DIR *dev_dir;
875         struct dirent *dirent;
876
877         /* Make sure the /dev/i2c-* files exist. */
878         dev_dir = opendir("/dev");
879         igt_assert(dev_dir);
880         while ((dirent = readdir(dev_dir))) {
881                 if (strncmp(dirent->d_name, "i2c-", 4) == 0)
882                         i2c_dev_files++;
883         }
884         closedir(dev_dir);
885         igt_require(i2c_dev_files);
886 }
887
888 /* Try to use raw I2C, which also needs interrupts. */
889 static void i2c_subtest(void)
890 {
891         i2c_subtest_check_environment();
892
893         enable_one_screen(&ms_data);
894         igt_assert(wait_for_active());
895
896         disable_all_screens(&ms_data);
897         igt_assert(wait_for_suspended());
898         test_i2c(&ms_data);
899         igt_assert(wait_for_suspended());
900
901         enable_one_screen(&ms_data);
902 }
903
904 static void read_full_file(const char *name)
905 {
906         int rc, fd;
907         char buf[128];
908
909         igt_assert_f(wait_for_suspended(), "File: %s\n", name);
910
911         fd = open(name, O_RDONLY);
912         if (fd < 0)
913                 return;
914
915         do {
916                 rc = read(fd, buf, ARRAY_SIZE(buf));
917         } while (rc == ARRAY_SIZE(buf));
918
919         rc = close(fd);
920         igt_assert(rc == 0);
921
922         igt_assert_f(wait_for_suspended(), "File: %s\n", name);
923 }
924
925 static void read_files_from_dir(const char *name, int level)
926 {
927         DIR *dir;
928         struct dirent *dirent;
929         char *full_name;
930         int rc;
931
932         dir = opendir(name);
933         igt_assert(dir);
934
935         full_name = malloc(PATH_MAX);
936
937         igt_assert(level < 128);
938
939         while ((dirent = readdir(dir))) {
940                 struct stat stat_buf;
941
942                 if (strcmp(dirent->d_name, ".") == 0)
943                         continue;
944                 if (strcmp(dirent->d_name, "..") == 0)
945                         continue;
946
947                 snprintf(full_name, PATH_MAX, "%s/%s", name, dirent->d_name);
948
949                 rc = lstat(full_name, &stat_buf);
950                 igt_assert(rc == 0);
951
952                 if (S_ISDIR(stat_buf.st_mode))
953                         read_files_from_dir(full_name, level + 1);
954
955                 if (S_ISREG(stat_buf.st_mode))
956                         read_full_file(full_name);
957         }
958
959         free(full_name);
960         closedir(dir);
961 }
962
963 /* This test will probably pass, with a small chance of hanging the machine in
964  * case of bugs. Many of the bugs exercised by this patch just result in dmesg
965  * errors, so a "pass" here should be confirmed by a check on dmesg. */
966 static void debugfs_read_subtest(void)
967 {
968         const char *path = "/sys/kernel/debug/dri/0";
969         DIR *dir;
970
971         dir = opendir(path);
972         igt_require_f(dir, "Can't open the debugfs directory\n");
973         closedir(dir);
974
975         disable_all_screens(&ms_data);
976         igt_assert(wait_for_suspended());
977
978         read_files_from_dir(path, 0);
979 }
980
981 /* Read the comment on debugfs_read_subtest(). */
982 static void sysfs_read_subtest(void)
983 {
984         const char *path = "/sys/devices/pci0000:00/0000:00:02.0";
985         DIR *dir;
986
987         dir = opendir(path);
988         igt_require_f(dir, "Can't open the sysfs directory\n");
989         closedir(dir);
990
991         disable_all_screens(&ms_data);
992         igt_assert(wait_for_suspended());
993
994         read_files_from_dir(path, 0);
995 }
996
997 /* Make sure we don't suspend when we have the i915_forcewake_user file open. */
998 static void debugfs_forcewake_user_subtest(void)
999 {
1000         int fd, rc;
1001
1002         igt_require(!(IS_GEN2(ms_data.devid) || IS_GEN3(ms_data.devid) ||
1003                       IS_GEN4(ms_data.devid) || IS_GEN5(ms_data.devid)));
1004
1005         disable_all_screens(&ms_data);
1006         igt_assert(wait_for_suspended());
1007
1008         fd = open("/sys/kernel/debug/dri/0/i915_forcewake_user", O_RDONLY);
1009         igt_require(fd);
1010
1011         if (has_runtime_pm) {
1012                 igt_assert(wait_for_active());
1013                 sleep(10);
1014                 igt_assert(wait_for_active());
1015         } else {
1016                 igt_assert(wait_for_suspended());
1017         }
1018
1019         rc = close(fd);
1020         igt_assert(rc == 0);
1021
1022         igt_assert(wait_for_suspended());
1023 }
1024
1025 static void gem_mmap_subtest(bool gtt_mmap)
1026 {
1027         int i;
1028         uint32_t handle;
1029         int buf_size = 8192;
1030         uint8_t *gem_buf;
1031
1032         /* Create, map and set data while the device is active. */
1033         enable_one_screen(&ms_data);
1034         igt_assert(wait_for_active());
1035
1036         handle = gem_create(drm_fd, buf_size);
1037
1038         if (gtt_mmap)
1039                 gem_buf = gem_mmap__gtt(drm_fd, handle, buf_size,
1040                                         PROT_READ | PROT_WRITE);
1041         else
1042                 gem_buf = gem_mmap__cpu(drm_fd, handle, buf_size, 0);
1043
1044
1045         for (i = 0; i < buf_size; i++)
1046                 gem_buf[i] = i & 0xFF;
1047
1048         for (i = 0; i < buf_size; i++)
1049                 igt_assert(gem_buf[i] == (i & 0xFF));
1050
1051         /* Now suspend, read and modify. */
1052         disable_all_screens(&ms_data);
1053         igt_assert(wait_for_suspended());
1054
1055         for (i = 0; i < buf_size; i++)
1056                 igt_assert(gem_buf[i] == (i & 0xFF));
1057         igt_assert(wait_for_suspended());
1058
1059         for (i = 0; i < buf_size; i++)
1060                 gem_buf[i] = (~i & 0xFF);
1061         igt_assert(wait_for_suspended());
1062
1063         /* Now resume and see if it's still there. */
1064         enable_one_screen(&ms_data);
1065         igt_assert(wait_for_active());
1066         for (i = 0; i < buf_size; i++)
1067                 igt_assert(gem_buf[i] == (~i & 0xFF));
1068
1069         igt_assert(munmap(gem_buf, buf_size) == 0);
1070
1071         /* Now the opposite: suspend, and try to create the mmap while
1072          * suspended. */
1073         disable_all_screens(&ms_data);
1074         igt_assert(wait_for_suspended());
1075
1076         if (gtt_mmap)
1077                 gem_buf = gem_mmap__gtt(drm_fd, handle, buf_size,
1078                                         PROT_READ | PROT_WRITE);
1079         else
1080                 gem_buf = gem_mmap__cpu(drm_fd, handle, buf_size, 0);
1081
1082         igt_assert(wait_for_suspended());
1083
1084         for (i = 0; i < buf_size; i++)
1085                 gem_buf[i] = i & 0xFF;
1086
1087         for (i = 0; i < buf_size; i++)
1088                 igt_assert(gem_buf[i] == (i & 0xFF));
1089
1090         igt_assert(wait_for_suspended());
1091
1092         /* Resume and check if it's still there. */
1093         enable_one_screen(&ms_data);
1094         igt_assert(wait_for_active());
1095         for (i = 0; i < buf_size; i++)
1096                 igt_assert(gem_buf[i] == (i & 0xFF));
1097
1098         igt_assert(munmap(gem_buf, buf_size) == 0);
1099         gem_close(drm_fd, handle);
1100 }
1101
1102 static void gem_pread_subtest(void)
1103 {
1104         int i;
1105         uint32_t handle;
1106         int buf_size = 8192;
1107         uint8_t *cpu_buf, *read_buf;
1108
1109         cpu_buf = malloc(buf_size);
1110         read_buf = malloc(buf_size);
1111         igt_assert(cpu_buf);
1112         igt_assert(read_buf);
1113         memset(cpu_buf, 0, buf_size);
1114         memset(read_buf, 0, buf_size);
1115
1116         /* Create and set data while the device is active. */
1117         enable_one_screen(&ms_data);
1118         igt_assert(wait_for_active());
1119
1120         handle = gem_create(drm_fd, buf_size);
1121
1122         for (i = 0; i < buf_size; i++)
1123                 cpu_buf[i] = i & 0xFF;
1124
1125         gem_write(drm_fd, handle, 0, cpu_buf, buf_size);
1126
1127         gem_read(drm_fd, handle, 0, read_buf, buf_size);
1128
1129         for (i = 0; i < buf_size; i++)
1130                 igt_assert(cpu_buf[i] == read_buf[i]);
1131
1132         /* Now suspend, read and modify. */
1133         disable_all_screens(&ms_data);
1134         igt_assert(wait_for_suspended());
1135
1136         memset(read_buf, 0, buf_size);
1137         gem_read(drm_fd, handle, 0, read_buf, buf_size);
1138
1139         for (i = 0; i < buf_size; i++)
1140                 igt_assert(cpu_buf[i] == read_buf[i]);
1141         igt_assert(wait_for_suspended());
1142
1143         for (i = 0; i < buf_size; i++)
1144                 cpu_buf[i] = (~i & 0xFF);
1145         gem_write(drm_fd, handle, 0, cpu_buf, buf_size);
1146         igt_assert(wait_for_suspended());
1147
1148         /* Now resume and see if it's still there. */
1149         enable_one_screen(&ms_data);
1150         igt_assert(wait_for_active());
1151
1152         memset(read_buf, 0, buf_size);
1153         gem_read(drm_fd, handle, 0, read_buf, buf_size);
1154
1155         for (i = 0; i < buf_size; i++)
1156                 igt_assert(cpu_buf[i] == read_buf[i]);
1157
1158         gem_close(drm_fd, handle);
1159
1160         free(cpu_buf);
1161         free(read_buf);
1162 }
1163
1164 /* Paints a square of color $color, size $width x $height, at position $x x $y
1165  * of $dst_handle, which contains pitch $pitch. */
1166 static void submit_blt_cmd(uint32_t dst_handle, uint32_t x, uint32_t y,
1167                            uint32_t width, uint32_t height, uint32_t pitch,
1168                            uint32_t color, uint32_t *presumed_dst_offset)
1169 {
1170         int i, reloc_pos;
1171         int bpp = 4;
1172         uint32_t batch_handle;
1173         int batch_size = 8 * sizeof(uint32_t);
1174         uint32_t batch_buf[batch_size];
1175         uint32_t offset_in_dst = (pitch * y) + (x * bpp);
1176         struct drm_i915_gem_execbuffer2 execbuf = {};
1177         struct drm_i915_gem_exec_object2 objs[2] = {{}, {}};
1178         struct drm_i915_gem_relocation_entry relocs[1] = {{}};
1179         struct drm_i915_gem_wait gem_wait;
1180
1181         i = 0;
1182
1183         batch_buf[i++] = COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA |
1184                          COLOR_BLT_WRITE_RGB;
1185         batch_buf[i++] = (3 << 24) | (0xF0 << 16) | pitch;
1186         batch_buf[i++] = (height << 16) | width * bpp;
1187         reloc_pos = i;
1188         batch_buf[i++] = *presumed_dst_offset + offset_in_dst;
1189         batch_buf[i++] = color;
1190
1191         batch_buf[i++] = MI_NOOP;
1192         batch_buf[i++] = MI_BATCH_BUFFER_END;
1193         batch_buf[i++] = MI_NOOP;
1194
1195         igt_assert(i * sizeof(uint32_t) == batch_size);
1196
1197         batch_handle = gem_create(drm_fd, batch_size);
1198         gem_write(drm_fd, batch_handle, 0, batch_buf, batch_size);
1199
1200         relocs[0].target_handle = dst_handle;
1201         relocs[0].delta = offset_in_dst;
1202         relocs[0].offset = reloc_pos * sizeof(uint32_t);
1203         relocs[0].presumed_offset = *presumed_dst_offset;
1204         relocs[0].read_domains = 0;
1205         relocs[0].write_domain = I915_GEM_DOMAIN_RENDER;
1206
1207         objs[0].handle = dst_handle;
1208         objs[0].alignment = 64;
1209
1210         objs[1].handle = batch_handle;
1211         objs[1].relocation_count = 1;
1212         objs[1].relocs_ptr = (uintptr_t)relocs;
1213
1214         execbuf.buffers_ptr = (uintptr_t)objs;
1215         execbuf.buffer_count = 2;
1216         execbuf.batch_len = batch_size;
1217         execbuf.flags = I915_EXEC_BLT;
1218         i915_execbuffer2_set_context_id(execbuf, 0);
1219
1220         do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
1221
1222         *presumed_dst_offset = relocs[0].presumed_offset;
1223
1224         gem_wait.flags = 0;
1225         gem_wait.timeout_ns = 10000000000LL; /* 10s */
1226
1227         gem_wait.bo_handle = batch_handle;
1228         do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_WAIT, &gem_wait);
1229
1230         gem_wait.bo_handle = dst_handle;
1231         do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_WAIT, &gem_wait);
1232
1233         gem_close(drm_fd, batch_handle);
1234 }
1235
1236 /* Make sure we can submit a batch buffer and verify its result. */
1237 static void gem_execbuf_subtest(void)
1238 {
1239         int x, y;
1240         uint32_t handle;
1241         int bpp = 4;
1242         int pitch = 128 * bpp;
1243         int dst_size = 128 * 128 * bpp; /* 128x128 square */
1244         uint32_t *cpu_buf;
1245         uint32_t presumed_offset = 0;
1246         int sq_x = 5, sq_y = 10, sq_w = 15, sq_h = 20;
1247         uint32_t color;
1248
1249         /* Create and set data while the device is active. */
1250         enable_one_screen(&ms_data);
1251         igt_assert(wait_for_active());
1252
1253         handle = gem_create(drm_fd, dst_size);
1254
1255         cpu_buf = malloc(dst_size);
1256         igt_assert(cpu_buf);
1257         memset(cpu_buf, 0, dst_size);
1258         gem_write(drm_fd, handle, 0, cpu_buf, dst_size);
1259
1260         /* Now suspend and try it. */
1261         disable_all_screens(&ms_data);
1262         igt_assert(wait_for_suspended());
1263
1264         color = 0x12345678;
1265         submit_blt_cmd(handle, sq_x, sq_y, sq_w, sq_h, pitch, color,
1266                        &presumed_offset);
1267         igt_assert(wait_for_suspended());
1268
1269         gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1270         igt_assert(wait_for_suspended());
1271         for (y = 0; y < 128; y++) {
1272                 for (x = 0; x < 128; x++) {
1273                         uint32_t px = cpu_buf[y * 128 + x];
1274
1275                         if (y >= sq_y && y < (sq_y + sq_h) &&
1276                             x >= sq_x && x < (sq_x + sq_w))
1277                                 igt_assert(px == color);
1278                         else
1279                                 igt_assert(px == 0);
1280                 }
1281         }
1282
1283         /* Now resume and check for it again. */
1284         enable_one_screen(&ms_data);
1285         igt_assert(wait_for_active());
1286
1287         memset(cpu_buf, 0, dst_size);
1288         gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1289         for (y = 0; y < 128; y++) {
1290                 for (x = 0; x < 128; x++) {
1291                         uint32_t px = cpu_buf[y * 128 + x];
1292
1293                         if (y >= sq_y && y < (sq_y + sq_h) &&
1294                             x >= sq_x && x < (sq_x + sq_w))
1295                                 igt_assert(px == color);
1296                         else
1297                                 igt_assert(px == 0);
1298                 }
1299         }
1300
1301         /* Now we'll do the opposite: do the blt while active, then read while
1302          * suspended. We use the same spot, but a different color. As a bonus,
1303          * we're testing the presumed_offset from the previous command. */
1304         color = 0x87654321;
1305         submit_blt_cmd(handle, sq_x, sq_y, sq_w, sq_h, pitch, color,
1306                        &presumed_offset);
1307
1308         disable_all_screens(&ms_data);
1309         igt_assert(wait_for_suspended());
1310
1311         memset(cpu_buf, 0, dst_size);
1312         gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1313         for (y = 0; y < 128; y++) {
1314                 for (x = 0; x < 128; x++) {
1315                         uint32_t px = cpu_buf[y * 128 + x];
1316
1317                         if (y >= sq_y && y < (sq_y + sq_h) &&
1318                             x >= sq_x && x < (sq_x + sq_w))
1319                                 igt_assert(px == color);
1320                         else
1321                                 igt_assert(px == 0);
1322                 }
1323         }
1324
1325         gem_close(drm_fd, handle);
1326
1327         free(cpu_buf);
1328 }
1329
1330 /* Assuming execbuf already works, let's see what happens when we force many
1331  * suspend/resume cycles with commands. */
1332 static void gem_execbuf_stress_subtest(int rounds, int wait_flags)
1333 {
1334         int i;
1335         int batch_size = 4 * sizeof(uint32_t);
1336         uint32_t batch_buf[batch_size];
1337         uint32_t handle;
1338         struct drm_i915_gem_execbuffer2 execbuf = {};
1339         struct drm_i915_gem_exec_object2 objs[1] = {{}};
1340
1341         if (wait_flags & WAIT_PC8_RES)
1342                 igt_require(has_pc8);
1343
1344         i = 0;
1345         batch_buf[i++] = MI_NOOP;
1346         batch_buf[i++] = MI_NOOP;
1347         batch_buf[i++] = MI_BATCH_BUFFER_END;
1348         batch_buf[i++] = MI_NOOP;
1349         igt_assert(i * sizeof(uint32_t) == batch_size);
1350
1351         disable_all_screens(&ms_data);
1352         igt_assert(wait_for_suspended());
1353
1354         handle = gem_create(drm_fd, batch_size);
1355         gem_write(drm_fd, handle, 0, batch_buf, batch_size);
1356
1357         objs[0].handle = handle;
1358
1359         execbuf.buffers_ptr = (uintptr_t)objs;
1360         execbuf.buffer_count = 1;
1361         execbuf.batch_len = batch_size;
1362         execbuf.flags = I915_EXEC_RENDER;
1363         i915_execbuffer2_set_context_id(execbuf, 0);
1364
1365         for (i = 0; i < rounds; i++) {
1366                 do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
1367
1368                 if (wait_flags & WAIT_STATUS)
1369                         igt_assert(wait_for_suspended());
1370                 if (wait_flags & WAIT_PC8_RES)
1371                         igt_assert(pc8_plus_residency_changed(120));
1372                 if (wait_flags & WAIT_EXTRA)
1373                         sleep(5);
1374         }
1375
1376         gem_close(drm_fd, handle);
1377 }
1378
1379 /* When this test was written, it triggered WARNs and DRM_ERRORs on dmesg. */
1380 static void gem_idle_subtest(void)
1381 {
1382         disable_all_screens(&ms_data);
1383         igt_assert(wait_for_suspended());
1384
1385         sleep(5);
1386
1387         gem_quiescent_gpu(drm_fd);
1388 }
1389
1390 int main(int argc, char *argv[])
1391 {
1392         int rounds = 50;
1393
1394         igt_subtest_init(argc, argv);
1395
1396         /* The --quick option makes the stress tests not so stressful. Useful
1397          * when you're developing and just want to make a quick test to make
1398          * sure you didn't break everything. */
1399         if (argc > 1 && strcmp(argv[1], "--quick") == 0)
1400                 rounds = 10;
1401
1402         /* Skip instead of failing in case the machine is not prepared to reach
1403          * PC8+. We don't want bug reports from cases where the machine is just
1404          * not properly configured. */
1405         igt_fixture
1406                 setup_environment();
1407
1408         /* Essential things */
1409         igt_subtest("rte")
1410                 basic_subtest();
1411         igt_subtest("drm-resources-equal")
1412                 drm_resources_equal_subtest();
1413
1414         /* Basic modeset */
1415         igt_subtest("modeset-lpsp")
1416                 modeset_subtest(SCREEN_TYPE_LPSP, 1, WAIT_STATUS);
1417         igt_subtest("modeset-non-lpsp")
1418                 modeset_subtest(SCREEN_TYPE_NON_LPSP, 1, WAIT_STATUS);
1419
1420         /* GEM */
1421         igt_subtest("gem-mmap-cpu")
1422                 gem_mmap_subtest(false);
1423         igt_subtest("gem-mmap-gtt")
1424                 gem_mmap_subtest(true);
1425         igt_subtest("gem-pread")
1426                 gem_pread_subtest();
1427         igt_subtest("gem-execbuf")
1428                 gem_execbuf_subtest();
1429         igt_subtest("gem-idle")
1430                 gem_idle_subtest();
1431
1432         /* Misc */
1433         igt_subtest("i2c")
1434                 i2c_subtest();
1435         igt_subtest("pc8-residency")
1436                 pc8_residency_subtest();
1437         igt_subtest("debugfs-read")
1438                 debugfs_read_subtest();
1439         igt_subtest("debugfs-forcewake-user")
1440                 debugfs_forcewake_user_subtest();
1441         igt_subtest("sysfs-read")
1442                 sysfs_read_subtest();
1443
1444         /* Modeset stress */
1445         igt_subtest("modeset-lpsp-stress")
1446                 modeset_subtest(SCREEN_TYPE_LPSP, rounds, WAIT_STATUS);
1447         igt_subtest("modeset-non-lpsp-stress")
1448                 modeset_subtest(SCREEN_TYPE_NON_LPSP, rounds, WAIT_STATUS);
1449         igt_subtest("modeset-lpsp-stress-no-wait")
1450                 modeset_subtest(SCREEN_TYPE_LPSP, rounds, DONT_WAIT);
1451         igt_subtest("modeset-non-lpsp-stress-no-wait")
1452                 modeset_subtest(SCREEN_TYPE_NON_LPSP, rounds, DONT_WAIT);
1453         igt_subtest("modeset-pc8-residency-stress")
1454                 modeset_subtest(SCREEN_TYPE_ANY, rounds, WAIT_PC8_RES);
1455         igt_subtest("modeset-stress-extra-wait")
1456                 modeset_subtest(SCREEN_TYPE_ANY, rounds,
1457                                 WAIT_STATUS | WAIT_EXTRA);
1458
1459         /* GEM stress */
1460         igt_subtest("gem-execbuf-stress")
1461                 gem_execbuf_stress_subtest(rounds, WAIT_STATUS);
1462         igt_subtest("gem-execbuf-stress-pc8")
1463                 gem_execbuf_stress_subtest(rounds, WAIT_PC8_RES);
1464         igt_subtest("gem-execbuf-stress-extra-wait")
1465                 gem_execbuf_stress_subtest(rounds, WAIT_STATUS | WAIT_EXTRA);
1466
1467         igt_fixture
1468                 teardown_environment();
1469
1470         igt_exit();
1471 }