tests/pm_rpm: add subtests for fences
[platform/upstream/intel-gpu-tools.git] / tests / pm_rpm.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
45 #include "drmtest.h"
46 #include "intel_batchbuffer.h"
47 #include "intel_io.h"
48 #include "intel_chipset.h"
49 #include "ioctl_wrappers.h"
50 #include "igt_aux.h"
51 #include "igt_kms.h"
52 #include "igt_debugfs.h"
53
54 /* One day, this will be on your libdrm. */
55 #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
56
57 #define MSR_PC8_RES     0x630
58 #define MSR_PC9_RES     0x631
59 #define MSR_PC10_RES    0x632
60
61 #define MAX_CONNECTORS  32
62 #define MAX_ENCODERS    32
63 #define MAX_CRTCS       16
64
65 #define POWER_DIR "/sys/devices/pci0000:00/0000:00:02.0/power"
66
67 enum pc8_status {
68         PC8_ENABLED,
69         PC8_DISABLED
70 };
71
72 enum screen_type {
73         SCREEN_TYPE_LPSP,
74         SCREEN_TYPE_NON_LPSP,
75         SCREEN_TYPE_ANY,
76 };
77
78 enum plane_type {
79         PLANE_OVERLAY,
80         PLANE_PRIMARY,
81         PLANE_CURSOR,
82 };
83
84 /* Wait flags */
85 #define DONT_WAIT       0
86 #define WAIT_STATUS     1
87 #define WAIT_PC8_RES    2
88 #define WAIT_EXTRA      4
89 #define USE_DPMS        8
90
91 int drm_fd, msr_fd, pm_status_fd, pc8_status_fd;
92 bool has_runtime_pm, has_pc8;
93 struct mode_set_data ms_data;
94 struct scanout_fb *fbs = NULL;
95
96 /* Stuff used when creating FBs and mode setting. */
97 struct mode_set_data {
98         drmModeResPtr res;
99         drmModeConnectorPtr connectors[MAX_CONNECTORS];
100         drmModePropertyBlobPtr edids[MAX_CONNECTORS];
101
102         uint32_t devid;
103 };
104
105 /* Stuff we query at different times so we can compare. */
106 struct compare_data {
107         drmModeResPtr res;
108         drmModeEncoderPtr encoders[MAX_ENCODERS];
109         drmModeConnectorPtr connectors[MAX_CONNECTORS];
110         drmModeCrtcPtr crtcs[MAX_CRTCS];
111         drmModePropertyBlobPtr edids[MAX_CONNECTORS];
112 };
113
114 /* During the stress tests we want to be as fast as possible, so use pre-created
115  * FBs instead of creating them again and again. */
116 struct scanout_fb {
117         uint32_t handle;
118         int width;
119         int height;
120         struct scanout_fb *next;
121 };
122
123 /* If the read fails, then the machine doesn't support PC8+ residencies. */
124 static bool supports_pc8_plus_residencies(void)
125 {
126         int rc;
127         uint64_t val;
128
129         rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC8_RES);
130         if (rc != sizeof(val))
131                 return false;
132         rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC9_RES);
133         if (rc != sizeof(val))
134                 return false;
135         rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC10_RES);
136         if (rc != sizeof(val))
137                 return false;
138
139         return true;
140 }
141
142 static uint64_t get_residency(uint32_t type)
143 {
144         int rc;
145         uint64_t ret;
146
147         rc = pread(msr_fd, &ret, sizeof(uint64_t), type);
148         igt_assert(rc == sizeof(ret));
149
150         return ret;
151 }
152
153 static bool pc8_plus_residency_changed(unsigned int timeout_sec)
154 {
155         unsigned int i;
156         uint64_t res_pc8, res_pc9, res_pc10;
157         int to_sleep = 100 * 1000;
158
159         res_pc8 = get_residency(MSR_PC8_RES);
160         res_pc9 = get_residency(MSR_PC9_RES);
161         res_pc10 = get_residency(MSR_PC10_RES);
162
163         for (i = 0; i < timeout_sec * 1000 * 1000; i += to_sleep) {
164                 if (res_pc8 != get_residency(MSR_PC8_RES) ||
165                     res_pc9 != get_residency(MSR_PC9_RES) ||
166                     res_pc10 != get_residency(MSR_PC10_RES)) {
167                         return true;
168                 }
169                 usleep(to_sleep);
170         }
171
172         return false;
173 }
174
175 static enum pc8_status get_pc8_status(void)
176 {
177         ssize_t n_read;
178         char buf[150]; /* The whole file has less than 100 chars. */
179
180         lseek(pc8_status_fd, 0, SEEK_SET);
181         n_read = read(pc8_status_fd, buf, ARRAY_SIZE(buf));
182         igt_assert(n_read >= 0);
183         buf[n_read] = '\0';
184
185         if (strstr(buf, "\nEnabled: yes\n"))
186                 return PC8_ENABLED;
187         else
188                 return PC8_DISABLED;
189 }
190
191 static bool wait_for_pc8_status(enum pc8_status status)
192 {
193         int i;
194         int hundred_ms = 100 * 1000, ten_s = 10 * 1000 * 1000;
195
196         for (i = 0; i < ten_s; i += hundred_ms) {
197                 if (get_pc8_status() == status)
198                         return true;
199
200                 usleep(hundred_ms);
201         }
202
203         return false;
204 }
205
206 static bool wait_for_suspended(void)
207 {
208         if (has_pc8 && !has_runtime_pm)
209                 return wait_for_pc8_status(PC8_ENABLED);
210         else
211                 return igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_SUSPENDED);
212 }
213
214 static bool wait_for_active(void)
215 {
216         if (has_pc8 && !has_runtime_pm)
217                 return wait_for_pc8_status(PC8_DISABLED);
218         else
219                 return igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_ACTIVE);
220 }
221
222 static void disable_all_screens_dpms(struct mode_set_data *data)
223 {
224         int i;
225
226         for (i = 0; i < data->res->count_connectors; i++) {
227                 drmModeConnectorPtr c = data->connectors[i];
228
229                 kmstest_set_connector_dpms(drm_fd, c, DRM_MODE_DPMS_OFF);
230         }
231 }
232
233 static void disable_all_screens(struct mode_set_data *data)
234 {
235         kmstest_unset_all_crtcs(drm_fd, data->res);
236 }
237
238 static struct scanout_fb *create_fb(struct mode_set_data *data, int width,
239                                     int height)
240 {
241         struct scanout_fb *fb_info;
242         struct igt_fb fb;
243         cairo_t *cr;
244
245         fb_info = malloc(sizeof(struct scanout_fb));
246         igt_assert(fb_info);
247
248         fb_info->handle = igt_create_fb(drm_fd, width, height,
249                                             DRM_FORMAT_XRGB8888,
250                                             false, &fb);
251         fb_info->width = width;
252         fb_info->height = height;
253         fb_info->next = NULL;
254
255         cr = igt_get_cairo_ctx(drm_fd, &fb);
256         igt_paint_test_pattern(cr, width, height);
257         cairo_destroy(cr);
258
259         return fb_info;
260 }
261
262 static uint32_t get_fb(struct mode_set_data *data, int width, int height)
263 {
264         struct scanout_fb *fb;
265
266         if (!fbs) {
267                 fbs = create_fb(data, width, height);
268                 return fbs->handle;
269         }
270
271         for (fb = fbs; fb != NULL; fb = fb->next) {
272                 if (fb->width == width && fb->height == height)
273                         return fb->handle;
274
275                 if (!fb->next) {
276                         fb->next = create_fb(data, width, height);
277                         return fb->next->handle;
278                 }
279         }
280         igt_assert(false);
281 }
282
283 static bool find_connector_for_modeset(struct mode_set_data *data,
284                                        enum screen_type type,
285                                        uint32_t *connector_id,
286                                        drmModeModeInfoPtr *mode)
287 {
288         int i;
289
290         *connector_id = 0;
291         *mode = NULL;
292         for (i = 0; i < data->res->count_connectors; i++) {
293                 drmModeConnectorPtr c = data->connectors[i];
294
295                 if (type == SCREEN_TYPE_LPSP &&
296                     c->connector_type != DRM_MODE_CONNECTOR_eDP)
297                         continue;
298
299                 if (type == SCREEN_TYPE_NON_LPSP &&
300                     c->connector_type == DRM_MODE_CONNECTOR_eDP)
301                         continue;
302
303                 if (c->connection == DRM_MODE_CONNECTED && c->count_modes) {
304                         *connector_id = c->connector_id;
305                         *mode = &c->modes[0];
306                         break;
307                 }
308         }
309
310         return (*connector_id != 0);
311 }
312
313 static bool enable_one_screen_with_type(struct mode_set_data *data,
314                                         enum screen_type type)
315 {
316         uint32_t crtc_id = 0, buffer_id = 0, connector_id;
317         drmModeModeInfoPtr mode;
318         int rc;
319
320         if (!find_connector_for_modeset(data, type, &connector_id, &mode))
321                 return false;
322
323         crtc_id = data->res->crtcs[0];
324         buffer_id = get_fb(data, mode->hdisplay, mode->vdisplay);
325
326         igt_assert(crtc_id);
327         igt_assert(buffer_id);
328
329         rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id,
330                             1, mode);
331         igt_assert(rc == 0);
332
333         return true;
334 }
335
336 static void enable_one_screen(struct mode_set_data *data)
337 {
338         /* SKIP if there are no connected screens. */
339         igt_require(enable_one_screen_with_type(data, SCREEN_TYPE_ANY));
340 }
341
342 static drmModePropertyBlobPtr get_connector_edid(drmModeConnectorPtr connector,
343                                                  int index)
344 {
345         bool found;
346         uint64_t prop_value;
347         drmModePropertyPtr prop;
348         drmModePropertyBlobPtr blob = NULL;
349
350         found = kmstest_get_property(drm_fd, connector->connector_id,
351                                      DRM_MODE_OBJECT_CONNECTOR, "EDID",
352                                      NULL, &prop_value, &prop);
353
354         if (found) {
355                 igt_assert(prop->flags & DRM_MODE_PROP_BLOB);
356                 igt_assert(prop->count_blobs == 0);
357
358                 blob = drmModeGetPropertyBlob(drm_fd, prop_value);
359
360                 drmModeFreeProperty(prop);
361         }
362
363         return blob;
364 }
365
366 static void init_mode_set_data(struct mode_set_data *data)
367 {
368         int i;
369
370         data->res = drmModeGetResources(drm_fd);
371         igt_assert(data->res);
372         igt_assert(data->res->count_connectors <= MAX_CONNECTORS);
373
374         for (i = 0; i < data->res->count_connectors; i++) {
375                 data->connectors[i] = drmModeGetConnector(drm_fd,
376                                                 data->res->connectors[i]);
377                 data->edids[i] = get_connector_edid(data->connectors[i], i);
378         }
379
380         data->devid = intel_get_drm_devid(drm_fd);
381
382         igt_set_vt_graphics_mode();
383 }
384
385 static void fini_mode_set_data(struct mode_set_data *data)
386 {
387         int i;
388
389         for (i = 0; i < data->res->count_connectors; i++) {
390                 drmModeFreeConnector(data->connectors[i]);
391                 drmModeFreePropertyBlob(data->edids[i]);
392         }
393         drmModeFreeResources(data->res);
394 }
395
396 static void get_drm_info(struct compare_data *data)
397 {
398         int i;
399
400         data->res = drmModeGetResources(drm_fd);
401         igt_assert(data->res);
402
403         igt_assert(data->res->count_connectors <= MAX_CONNECTORS);
404         igt_assert(data->res->count_encoders <= MAX_ENCODERS);
405         igt_assert(data->res->count_crtcs <= MAX_CRTCS);
406
407         for (i = 0; i < data->res->count_connectors; i++) {
408                 data->connectors[i] = drmModeGetConnector(drm_fd,
409                                                 data->res->connectors[i]);
410                 data->edids[i] = get_connector_edid(data->connectors[i], i);
411         }
412         for (i = 0; i < data->res->count_encoders; i++)
413                 data->encoders[i] = drmModeGetEncoder(drm_fd,
414                                                 data->res->encoders[i]);
415         for (i = 0; i < data->res->count_crtcs; i++)
416                 data->crtcs[i] = drmModeGetCrtc(drm_fd, data->res->crtcs[i]);
417 }
418
419 static void free_drm_info(struct compare_data *data)
420 {
421         int i;
422
423         for (i = 0; i < data->res->count_connectors; i++) {
424                 drmModeFreeConnector(data->connectors[i]);
425                 drmModeFreePropertyBlob(data->edids[i]);
426         }
427         for (i = 0; i < data->res->count_encoders; i++)
428                 drmModeFreeEncoder(data->encoders[i]);
429         for (i = 0; i < data->res->count_crtcs; i++)
430                 drmModeFreeCrtc(data->crtcs[i]);
431
432         drmModeFreeResources(data->res);
433 }
434
435 #define COMPARE(d1, d2, data) igt_assert(d1->data == d2->data)
436 #define COMPARE_ARRAY(d1, d2, size, data) do { \
437         for (i = 0; i < size; i++) \
438                 igt_assert(d1->data[i] == d2->data[i]); \
439 } while (0)
440
441 static void assert_drm_resources_equal(struct compare_data *d1,
442                                        struct compare_data *d2)
443 {
444         COMPARE(d1, d2, res->count_connectors);
445         COMPARE(d1, d2, res->count_encoders);
446         COMPARE(d1, d2, res->count_crtcs);
447         COMPARE(d1, d2, res->min_width);
448         COMPARE(d1, d2, res->max_width);
449         COMPARE(d1, d2, res->min_height);
450         COMPARE(d1, d2, res->max_height);
451 }
452
453 static void assert_modes_equal(drmModeModeInfoPtr m1, drmModeModeInfoPtr m2)
454 {
455         COMPARE(m1, m2, clock);
456         COMPARE(m1, m2, hdisplay);
457         COMPARE(m1, m2, hsync_start);
458         COMPARE(m1, m2, hsync_end);
459         COMPARE(m1, m2, htotal);
460         COMPARE(m1, m2, hskew);
461         COMPARE(m1, m2, vdisplay);
462         COMPARE(m1, m2, vsync_start);
463         COMPARE(m1, m2, vsync_end);
464         COMPARE(m1, m2, vtotal);
465         COMPARE(m1, m2, vscan);
466         COMPARE(m1, m2, vrefresh);
467         COMPARE(m1, m2, flags);
468         COMPARE(m1, m2, type);
469         igt_assert(strcmp(m1->name, m2->name) == 0);
470 }
471
472 static void assert_drm_connectors_equal(drmModeConnectorPtr c1,
473                                         drmModeConnectorPtr c2)
474 {
475         int i;
476
477         COMPARE(c1, c2, connector_id);
478         COMPARE(c1, c2, connector_type);
479         COMPARE(c1, c2, connector_type_id);
480         COMPARE(c1, c2, mmWidth);
481         COMPARE(c1, c2, mmHeight);
482         COMPARE(c1, c2, count_modes);
483         COMPARE(c1, c2, count_props);
484         COMPARE(c1, c2, count_encoders);
485         COMPARE_ARRAY(c1, c2, c1->count_props, props);
486         COMPARE_ARRAY(c1, c2, c1->count_encoders, encoders);
487
488         for (i = 0; i < c1->count_modes; i++)
489                 assert_modes_equal(&c1->modes[0], &c2->modes[0]);
490 }
491
492 static void assert_drm_encoders_equal(drmModeEncoderPtr e1,
493                                       drmModeEncoderPtr e2)
494 {
495         COMPARE(e1, e2, encoder_id);
496         COMPARE(e1, e2, encoder_type);
497         COMPARE(e1, e2, possible_crtcs);
498         COMPARE(e1, e2, possible_clones);
499 }
500
501 static void assert_drm_crtcs_equal(drmModeCrtcPtr c1, drmModeCrtcPtr c2)
502 {
503         COMPARE(c1, c2, crtc_id);
504 }
505
506 static void assert_drm_edids_equal(drmModePropertyBlobPtr e1,
507                                    drmModePropertyBlobPtr e2)
508 {
509         if (!e1 && !e2)
510                 return;
511         igt_assert(e1 && e2);
512
513         COMPARE(e1, e2, id);
514         COMPARE(e1, e2, length);
515
516         igt_assert(memcmp(e1->data, e2->data, e1->length) == 0);
517 }
518
519 static void assert_drm_infos_equal(struct compare_data *d1,
520                                    struct compare_data *d2)
521 {
522         int i;
523
524         assert_drm_resources_equal(d1, d2);
525
526         for (i = 0; i < d1->res->count_connectors; i++) {
527                 assert_drm_connectors_equal(d1->connectors[i],
528                                             d2->connectors[i]);
529                 assert_drm_edids_equal(d1->edids[i], d2->edids[i]);
530         }
531
532         for (i = 0; i < d1->res->count_encoders; i++)
533                 assert_drm_encoders_equal(d1->encoders[i], d2->encoders[i]);
534
535         for (i = 0; i < d1->res->count_crtcs; i++)
536                 assert_drm_crtcs_equal(d1->crtcs[i], d2->crtcs[i]);
537 }
538
539 /* We could check the checksum too, but just the header is probably enough. */
540 static bool edid_is_valid(const unsigned char *edid)
541 {
542         char edid_header[] = {
543                 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
544         };
545
546         return (memcmp(edid, edid_header, sizeof(edid_header)) == 0);
547 }
548
549 static int count_drm_valid_edids(struct mode_set_data *data)
550 {
551         int i, ret = 0;
552
553         for (i = 0; i < data->res->count_connectors; i++)
554                 if (data->edids[i] && edid_is_valid(data->edids[i]->data))
555                         ret++;
556         return ret;
557 }
558
559 static bool i2c_edid_is_valid(int fd)
560 {
561         int rc;
562         unsigned char edid[128] = {};
563         struct i2c_msg msgs[] = {
564                 { /* Start at 0. */
565                         .addr = 0x50,
566                         .flags = 0,
567                         .len = 1,
568                         .buf = edid,
569                 }, { /* Now read the EDID. */
570                         .addr = 0x50,
571                         .flags = I2C_M_RD,
572                         .len = 128,
573                         .buf = edid,
574                 }
575         };
576         struct i2c_rdwr_ioctl_data msgset = {
577                 .msgs = msgs,
578                 .nmsgs = 2,
579         };
580
581         rc = ioctl(fd, I2C_RDWR, &msgset);
582         return (rc >= 0) ? edid_is_valid(edid) : false;
583 }
584
585 static int count_i2c_valid_edids(void)
586 {
587         int fd, ret = 0;
588         DIR *dir;
589
590         struct dirent *dirent;
591         char full_name[32];
592
593         dir = opendir("/dev/");
594         igt_assert(dir);
595
596         while ((dirent = readdir(dir))) {
597                 if (strncmp(dirent->d_name, "i2c-", 4) == 0) {
598                         snprintf(full_name, 32, "/dev/%s", dirent->d_name);
599                         fd = open(full_name, O_RDWR);
600                         igt_assert(fd != -1);
601                         if (i2c_edid_is_valid(fd))
602                                 ret++;
603                         close(fd);
604                 }
605         }
606
607         closedir(dir);
608
609         return ret;
610 }
611
612 static void test_i2c(struct mode_set_data *data)
613 {
614         int i2c_edids = count_i2c_valid_edids();
615         int drm_edids = count_drm_valid_edids(data);
616
617         igt_assert_cmpint(i2c_edids, ==, drm_edids);
618 }
619
620 static void setup_pc8(void)
621 {
622         has_pc8 = false;
623
624         /* Only Haswell supports the PC8 feature. */
625         if (!IS_HASWELL(ms_data.devid) && !IS_BROADWELL(ms_data.devid))
626                 return;
627
628         /* Make sure our Kernel supports MSR and the module is loaded. */
629         igt_assert(system("modprobe -q msr > /dev/null 2>&1") != -1);
630
631         msr_fd = open("/dev/cpu/0/msr", O_RDONLY);
632         igt_assert_f(msr_fd >= 0,
633                      "Can't open /dev/cpu/0/msr.\n");
634
635         /* Non-ULT machines don't support PC8+. */
636         if (!supports_pc8_plus_residencies())
637                 return;
638
639         pc8_status_fd = open("/sys/kernel/debug/dri/0/i915_pc8_status",
640                              O_RDONLY);
641         igt_assert_f(pc8_status_fd >= 0,
642                      "Can't open /sys/kernel/debug/dri/0/i915_pc8_status");
643
644         has_pc8 = true;
645 }
646
647 /* If we want to actually reach PC8+ states, we need to properly configure all
648  * the devices on the system to allow this. This function will try to setup the
649  * things we know we need, but won't scream in case anything fails: we don't
650  * know which devices are present on your machine, so we can't really expect
651  * anything, just try to help with the more common problems. */
652 static void setup_non_graphics_runtime_pm(void)
653 {
654         int fd, i;
655         char *file_name;
656
657         /* Disk runtime PM policies. */
658         file_name = malloc(PATH_MAX);
659         for (i = 0; ; i++) {
660
661                 snprintf(file_name, PATH_MAX,
662                          "/sys/class/scsi_host/host%d/link_power_management_policy",
663                          i);
664
665                 fd = open(file_name, O_WRONLY);
666                 if (fd < 0)
667                         break;
668
669                 write(fd, "min_power\n", 10);
670                 close(fd);
671         }
672         free(file_name);
673
674         /* Audio runtime PM policies. */
675         fd = open("/sys/module/snd_hda_intel/parameters/power_save", O_WRONLY);
676         if (fd >= 0) {
677                 write(fd, "1\n", 2);
678                 close(fd);
679         }
680         fd = open("/sys/bus/pci/devices/0000:00:03.0/power/control", O_WRONLY);
681         if (fd >= 0) {
682                 write(fd, "auto\n", 5);
683                 close(fd);
684         }
685 }
686
687 static void setup_environment(void)
688 {
689         drm_fd = drm_open_any();
690         igt_assert(drm_fd >= 0);
691
692         igt_require_f(drmSetMaster(drm_fd) == 0, "Can't become DRM master, "
693                       "please check if no other DRM client is running.\n");
694
695         init_mode_set_data(&ms_data);
696
697         setup_non_graphics_runtime_pm();
698
699         has_runtime_pm = igt_setup_runtime_pm();
700         setup_pc8();
701
702         igt_info("Runtime PM support: %d\n", has_runtime_pm);
703         igt_info("PC8 residency support: %d\n", has_pc8);
704
705         igt_require(has_runtime_pm);
706 }
707
708 static void teardown_environment(void)
709 {
710         struct scanout_fb *fb, *fb_next;
711
712         fb = fbs;
713         while (fb) {
714                 fb_next = fb->next;
715                 free(fb);
716                 fb = fb_next;
717         }
718
719         fini_mode_set_data(&ms_data);
720         drmClose(drm_fd);
721         close(msr_fd);
722         if (has_pc8)
723                 close(pc8_status_fd);
724 }
725
726 static void basic_subtest(void)
727 {
728         disable_all_screens(&ms_data);
729         igt_assert(wait_for_suspended());
730
731         enable_one_screen(&ms_data);
732         igt_assert(wait_for_active());
733 }
734
735 static void pc8_residency_subtest(void)
736 {
737         igt_require(has_pc8);
738
739         /* Make sure PC8+ residencies move! */
740         disable_all_screens(&ms_data);
741         igt_assert_f(pc8_plus_residency_changed(120),
742                      "Machine is not reaching PC8+ states, please check its "
743                      "configuration.\n");
744
745         /* Make sure PC8+ residencies stop! */
746         enable_one_screen(&ms_data);
747         igt_assert_f(!pc8_plus_residency_changed(10),
748                      "PC8+ residency didn't stop with screen enabled.\n");
749 }
750
751 static void modeset_subtest(enum screen_type type, int rounds, int wait_flags)
752 {
753         int i;
754
755         if (wait_flags & WAIT_PC8_RES)
756                 igt_require(has_pc8);
757
758         for (i = 0; i < rounds; i++) {
759                 if (wait_flags & USE_DPMS)
760                         disable_all_screens_dpms(&ms_data);
761                 else
762                         disable_all_screens(&ms_data);
763
764                 if (wait_flags & WAIT_STATUS)
765                         igt_assert(wait_for_suspended());
766                 if (wait_flags & WAIT_PC8_RES)
767                         igt_assert(pc8_plus_residency_changed(120));
768                 if (wait_flags & WAIT_EXTRA)
769                         sleep(5);
770
771                 /* If we skip this line it's because the type of screen we want
772                  * is not connected. */
773                 igt_require(enable_one_screen_with_type(&ms_data, type));
774                 if (wait_flags & WAIT_STATUS)
775                         igt_assert(wait_for_active());
776                 if (wait_flags & WAIT_PC8_RES)
777                         igt_assert(!pc8_plus_residency_changed(5));
778                 if (wait_flags & WAIT_EXTRA)
779                         sleep(5);
780         }
781 }
782
783 /* Test of the DRM resources reported by the IOCTLs are still the same. This
784  * ensures we still see the monitors with the same eyes. We get the EDIDs and
785  * compare them, which ensures we use DP AUX or GMBUS depending on what's
786  * connected. */
787 static void drm_resources_equal_subtest(void)
788 {
789         struct compare_data pre_suspend, during_suspend, post_suspend;
790
791         enable_one_screen(&ms_data);
792         igt_assert(wait_for_active());
793         get_drm_info(&pre_suspend);
794         igt_assert(wait_for_active());
795
796         disable_all_screens(&ms_data);
797         igt_assert(wait_for_suspended());
798         get_drm_info(&during_suspend);
799         igt_assert(wait_for_suspended());
800
801         enable_one_screen(&ms_data);
802         igt_assert(wait_for_active());
803         get_drm_info(&post_suspend);
804         igt_assert(wait_for_active());
805
806         assert_drm_infos_equal(&pre_suspend, &during_suspend);
807         assert_drm_infos_equal(&pre_suspend, &post_suspend);
808
809         free_drm_info(&pre_suspend);
810         free_drm_info(&during_suspend);
811         free_drm_info(&post_suspend);
812 }
813
814 static void i2c_subtest_check_environment(void)
815 {
816         int i2c_dev_files = 0;
817         DIR *dev_dir;
818         struct dirent *dirent;
819
820         /* Make sure the /dev/i2c-* files exist. */
821         igt_assert(system("modprobe -q i2c-dev > /dev/null 2>&1") != -1);
822
823         dev_dir = opendir("/dev");
824         igt_assert(dev_dir);
825         while ((dirent = readdir(dev_dir))) {
826                 if (strncmp(dirent->d_name, "i2c-", 4) == 0)
827                         i2c_dev_files++;
828         }
829         closedir(dev_dir);
830         igt_require(i2c_dev_files);
831 }
832
833 /* Try to use raw I2C, which also needs interrupts. */
834 static void i2c_subtest(void)
835 {
836         i2c_subtest_check_environment();
837
838         enable_one_screen(&ms_data);
839         igt_assert(wait_for_active());
840
841         disable_all_screens(&ms_data);
842         igt_assert(wait_for_suspended());
843         test_i2c(&ms_data);
844         igt_assert(wait_for_suspended());
845
846         enable_one_screen(&ms_data);
847 }
848
849 static void read_full_file(const char *name)
850 {
851         int rc, fd;
852         char buf[128];
853
854         igt_assert_f(wait_for_suspended(), "File: %s\n", name);
855
856         fd = open(name, O_RDONLY);
857         if (fd < 0)
858                 return;
859
860         do {
861                 rc = read(fd, buf, ARRAY_SIZE(buf));
862         } while (rc == ARRAY_SIZE(buf));
863
864         rc = close(fd);
865         igt_assert(rc == 0);
866
867         igt_assert_f(wait_for_suspended(), "File: %s\n", name);
868 }
869
870 static void read_files_from_dir(const char *name, int level)
871 {
872         DIR *dir;
873         struct dirent *dirent;
874         char *full_name;
875         int rc;
876
877         dir = opendir(name);
878         igt_assert(dir);
879
880         full_name = malloc(PATH_MAX);
881
882         igt_assert(level < 128);
883
884         while ((dirent = readdir(dir))) {
885                 struct stat stat_buf;
886
887                 if (strcmp(dirent->d_name, ".") == 0)
888                         continue;
889                 if (strcmp(dirent->d_name, "..") == 0)
890                         continue;
891
892                 snprintf(full_name, PATH_MAX, "%s/%s", name, dirent->d_name);
893
894                 rc = lstat(full_name, &stat_buf);
895                 igt_assert(rc == 0);
896
897                 if (S_ISDIR(stat_buf.st_mode))
898                         read_files_from_dir(full_name, level + 1);
899
900                 if (S_ISREG(stat_buf.st_mode))
901                         read_full_file(full_name);
902         }
903
904         free(full_name);
905         closedir(dir);
906 }
907
908 /* This test will probably pass, with a small chance of hanging the machine in
909  * case of bugs. Many of the bugs exercised by this patch just result in dmesg
910  * errors, so a "pass" here should be confirmed by a check on dmesg. */
911 static void debugfs_read_subtest(void)
912 {
913         const char *path = "/sys/kernel/debug/dri/0";
914         DIR *dir;
915
916         dir = opendir(path);
917         igt_require_f(dir, "Can't open the debugfs directory\n");
918         closedir(dir);
919
920         disable_all_screens(&ms_data);
921         igt_assert(wait_for_suspended());
922
923         read_files_from_dir(path, 0);
924 }
925
926 /* Read the comment on debugfs_read_subtest(). */
927 static void sysfs_read_subtest(void)
928 {
929         const char *path = "/sys/devices/pci0000:00/0000:00:02.0";
930         DIR *dir;
931
932         dir = opendir(path);
933         igt_require_f(dir, "Can't open the sysfs directory\n");
934         closedir(dir);
935
936         disable_all_screens(&ms_data);
937         igt_assert(wait_for_suspended());
938
939         read_files_from_dir(path, 0);
940 }
941
942 /* Make sure we don't suspend when we have the i915_forcewake_user file open. */
943 static void debugfs_forcewake_user_subtest(void)
944 {
945         int fd, rc;
946
947         igt_require(intel_gen(ms_data.devid) >= 6);
948
949         disable_all_screens(&ms_data);
950         igt_assert(wait_for_suspended());
951
952         fd = igt_open_forcewake_handle();
953         igt_require(fd >= 0);
954
955         if (has_runtime_pm) {
956                 igt_assert(wait_for_active());
957                 sleep(10);
958                 igt_assert(wait_for_active());
959         } else {
960                 igt_assert(wait_for_suspended());
961         }
962
963         rc = close(fd);
964         igt_assert(rc == 0);
965
966         igt_assert(wait_for_suspended());
967 }
968
969 static void gem_mmap_subtest(bool gtt_mmap)
970 {
971         int i;
972         uint32_t handle;
973         int buf_size = 8192;
974         uint8_t *gem_buf;
975
976         /* Create, map and set data while the device is active. */
977         enable_one_screen(&ms_data);
978         igt_assert(wait_for_active());
979
980         handle = gem_create(drm_fd, buf_size);
981
982         if (gtt_mmap)
983                 gem_buf = gem_mmap__gtt(drm_fd, handle, buf_size,
984                                         PROT_READ | PROT_WRITE);
985         else
986                 gem_buf = gem_mmap__cpu(drm_fd, handle, buf_size, 0);
987
988
989         for (i = 0; i < buf_size; i++)
990                 gem_buf[i] = i & 0xFF;
991
992         for (i = 0; i < buf_size; i++)
993                 igt_assert(gem_buf[i] == (i & 0xFF));
994
995         /* Now suspend, read and modify. */
996         disable_all_screens(&ms_data);
997         igt_assert(wait_for_suspended());
998
999         for (i = 0; i < buf_size; i++)
1000                 igt_assert(gem_buf[i] == (i & 0xFF));
1001         igt_assert(wait_for_suspended());
1002
1003         for (i = 0; i < buf_size; i++)
1004                 gem_buf[i] = (~i & 0xFF);
1005         igt_assert(wait_for_suspended());
1006
1007         /* Now resume and see if it's still there. */
1008         enable_one_screen(&ms_data);
1009         igt_assert(wait_for_active());
1010         for (i = 0; i < buf_size; i++)
1011                 igt_assert(gem_buf[i] == (~i & 0xFF));
1012
1013         igt_assert(munmap(gem_buf, buf_size) == 0);
1014
1015         /* Now the opposite: suspend, and try to create the mmap while
1016          * suspended. */
1017         disable_all_screens(&ms_data);
1018         igt_assert(wait_for_suspended());
1019
1020         if (gtt_mmap)
1021                 gem_buf = gem_mmap__gtt(drm_fd, handle, buf_size,
1022                                         PROT_READ | PROT_WRITE);
1023         else
1024                 gem_buf = gem_mmap__cpu(drm_fd, handle, buf_size, 0);
1025
1026         igt_assert(wait_for_suspended());
1027
1028         for (i = 0; i < buf_size; i++)
1029                 gem_buf[i] = i & 0xFF;
1030
1031         for (i = 0; i < buf_size; i++)
1032                 igt_assert(gem_buf[i] == (i & 0xFF));
1033
1034         igt_assert(wait_for_suspended());
1035
1036         /* Resume and check if it's still there. */
1037         enable_one_screen(&ms_data);
1038         igt_assert(wait_for_active());
1039         for (i = 0; i < buf_size; i++)
1040                 igt_assert(gem_buf[i] == (i & 0xFF));
1041
1042         igt_assert(munmap(gem_buf, buf_size) == 0);
1043         gem_close(drm_fd, handle);
1044 }
1045
1046 static void gem_pread_subtest(void)
1047 {
1048         int i;
1049         uint32_t handle;
1050         int buf_size = 8192;
1051         uint8_t *cpu_buf, *read_buf;
1052
1053         cpu_buf = malloc(buf_size);
1054         read_buf = malloc(buf_size);
1055         igt_assert(cpu_buf);
1056         igt_assert(read_buf);
1057         memset(cpu_buf, 0, buf_size);
1058         memset(read_buf, 0, buf_size);
1059
1060         /* Create and set data while the device is active. */
1061         enable_one_screen(&ms_data);
1062         igt_assert(wait_for_active());
1063
1064         handle = gem_create(drm_fd, buf_size);
1065
1066         for (i = 0; i < buf_size; i++)
1067                 cpu_buf[i] = i & 0xFF;
1068
1069         gem_write(drm_fd, handle, 0, cpu_buf, buf_size);
1070
1071         gem_read(drm_fd, handle, 0, read_buf, buf_size);
1072
1073         for (i = 0; i < buf_size; i++)
1074                 igt_assert(cpu_buf[i] == read_buf[i]);
1075
1076         /* Now suspend, read and modify. */
1077         disable_all_screens(&ms_data);
1078         igt_assert(wait_for_suspended());
1079
1080         memset(read_buf, 0, buf_size);
1081         gem_read(drm_fd, handle, 0, read_buf, buf_size);
1082
1083         for (i = 0; i < buf_size; i++)
1084                 igt_assert(cpu_buf[i] == read_buf[i]);
1085         igt_assert(wait_for_suspended());
1086
1087         for (i = 0; i < buf_size; i++)
1088                 cpu_buf[i] = (~i & 0xFF);
1089         gem_write(drm_fd, handle, 0, cpu_buf, buf_size);
1090         igt_assert(wait_for_suspended());
1091
1092         /* Now resume and see if it's still there. */
1093         enable_one_screen(&ms_data);
1094         igt_assert(wait_for_active());
1095
1096         memset(read_buf, 0, buf_size);
1097         gem_read(drm_fd, handle, 0, read_buf, buf_size);
1098
1099         for (i = 0; i < buf_size; i++)
1100                 igt_assert(cpu_buf[i] == read_buf[i]);
1101
1102         gem_close(drm_fd, handle);
1103
1104         free(cpu_buf);
1105         free(read_buf);
1106 }
1107
1108 /* Paints a square of color $color, size $width x $height, at position $x x $y
1109  * of $dst_handle, which contains pitch $pitch. */
1110 static void submit_blt_cmd(uint32_t dst_handle, uint16_t x, uint16_t y,
1111                            uint16_t width, uint16_t height, uint32_t pitch,
1112                            uint32_t color, uint32_t *presumed_dst_offset)
1113 {
1114         int i, reloc_pos;
1115         uint32_t batch_handle;
1116         int batch_size = 8 * sizeof(uint32_t);
1117         uint32_t batch_buf[batch_size];
1118         struct drm_i915_gem_execbuffer2 execbuf = {};
1119         struct drm_i915_gem_exec_object2 objs[2] = {{}, {}};
1120         struct drm_i915_gem_relocation_entry relocs[1] = {{}};
1121         struct drm_i915_gem_wait gem_wait;
1122
1123         i = 0;
1124
1125         if (intel_gen(ms_data.devid) >= 8)
1126                 batch_buf[i++] = XY_COLOR_BLT_CMD_NOLEN |
1127                                  XY_COLOR_BLT_WRITE_ALPHA |
1128                                  XY_COLOR_BLT_WRITE_RGB | 0x5;
1129         else
1130                 batch_buf[i++] = XY_COLOR_BLT_CMD_NOLEN |
1131                                  XY_COLOR_BLT_WRITE_ALPHA |
1132                                  XY_COLOR_BLT_WRITE_RGB | 0x4;
1133         batch_buf[i++] = (3 << 24) | (0xF0 << 16) | (pitch);
1134         batch_buf[i++] = (y << 16) | x;
1135         batch_buf[i++] = ((y + height) << 16) | (x + width);
1136         reloc_pos = i;
1137         batch_buf[i++] = *presumed_dst_offset;
1138         if (intel_gen(ms_data.devid) >= 8)
1139                 batch_buf[i++] = 0;
1140         batch_buf[i++] = color;
1141
1142         batch_buf[i++] = MI_BATCH_BUFFER_END;
1143         if (intel_gen(ms_data.devid) < 8)
1144                 batch_buf[i++] = MI_NOOP;
1145
1146         igt_assert(i * sizeof(uint32_t) == batch_size);
1147
1148         batch_handle = gem_create(drm_fd, batch_size);
1149         gem_write(drm_fd, batch_handle, 0, batch_buf, batch_size);
1150
1151         relocs[0].target_handle = dst_handle;
1152         relocs[0].delta = 0;
1153         relocs[0].offset = reloc_pos * sizeof(uint32_t);
1154         relocs[0].presumed_offset = *presumed_dst_offset;
1155         relocs[0].read_domains = 0;
1156         relocs[0].write_domain = I915_GEM_DOMAIN_RENDER;
1157
1158         objs[0].handle = dst_handle;
1159         objs[0].alignment = 64;
1160
1161         objs[1].handle = batch_handle;
1162         objs[1].relocation_count = 1;
1163         objs[1].relocs_ptr = (uintptr_t)relocs;
1164
1165         execbuf.buffers_ptr = (uintptr_t)objs;
1166         execbuf.buffer_count = 2;
1167         execbuf.batch_len = batch_size;
1168         execbuf.flags = I915_EXEC_BLT;
1169         i915_execbuffer2_set_context_id(execbuf, 0);
1170
1171         do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
1172
1173         *presumed_dst_offset = relocs[0].presumed_offset;
1174
1175         gem_wait.flags = 0;
1176         gem_wait.timeout_ns = 10000000000LL; /* 10s */
1177
1178         gem_wait.bo_handle = batch_handle;
1179         do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_WAIT, &gem_wait);
1180
1181         gem_wait.bo_handle = dst_handle;
1182         do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_WAIT, &gem_wait);
1183
1184         gem_close(drm_fd, batch_handle);
1185 }
1186
1187 /* Make sure we can submit a batch buffer and verify its result. */
1188 static void gem_execbuf_subtest(void)
1189 {
1190         int x, y;
1191         uint32_t handle;
1192         int bpp = 4;
1193         int pitch = 128 * bpp;
1194         int dst_size = 128 * 128 * bpp; /* 128x128 square */
1195         uint32_t *cpu_buf;
1196         uint32_t presumed_offset = 0;
1197         int sq_x = 5, sq_y = 10, sq_w = 15, sq_h = 20;
1198         uint32_t color;
1199
1200         /* Create and set data while the device is active. */
1201         enable_one_screen(&ms_data);
1202         igt_assert(wait_for_active());
1203
1204         handle = gem_create(drm_fd, dst_size);
1205
1206         cpu_buf = malloc(dst_size);
1207         igt_assert(cpu_buf);
1208         memset(cpu_buf, 0, dst_size);
1209         gem_write(drm_fd, handle, 0, cpu_buf, dst_size);
1210
1211         /* Now suspend and try it. */
1212         disable_all_screens(&ms_data);
1213         igt_assert(wait_for_suspended());
1214
1215         color = 0x12345678;
1216         submit_blt_cmd(handle, sq_x, sq_y, sq_w, sq_h, pitch, color,
1217                        &presumed_offset);
1218         igt_assert(wait_for_suspended());
1219
1220         gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1221         igt_assert(wait_for_suspended());
1222         for (y = 0; y < 128; y++) {
1223                 for (x = 0; x < 128; x++) {
1224                         uint32_t px = cpu_buf[y * 128 + x];
1225
1226                         if (y >= sq_y && y < (sq_y + sq_h) &&
1227                             x >= sq_x && x < (sq_x + sq_w))
1228                                 igt_assert(px == color);
1229                         else
1230                                 igt_assert(px == 0);
1231                 }
1232         }
1233
1234         /* Now resume and check for it again. */
1235         enable_one_screen(&ms_data);
1236         igt_assert(wait_for_active());
1237
1238         memset(cpu_buf, 0, dst_size);
1239         gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1240         for (y = 0; y < 128; y++) {
1241                 for (x = 0; x < 128; x++) {
1242                         uint32_t px = cpu_buf[y * 128 + x];
1243
1244                         if (y >= sq_y && y < (sq_y + sq_h) &&
1245                             x >= sq_x && x < (sq_x + sq_w))
1246                                 igt_assert(px == color);
1247                         else
1248                                 igt_assert(px == 0);
1249                 }
1250         }
1251
1252         /* Now we'll do the opposite: do the blt while active, then read while
1253          * suspended. We use the same spot, but a different color. As a bonus,
1254          * we're testing the presumed_offset from the previous command. */
1255         color = 0x87654321;
1256         submit_blt_cmd(handle, sq_x, sq_y, sq_w, sq_h, pitch, color,
1257                        &presumed_offset);
1258
1259         disable_all_screens(&ms_data);
1260         igt_assert(wait_for_suspended());
1261
1262         memset(cpu_buf, 0, dst_size);
1263         gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1264         for (y = 0; y < 128; y++) {
1265                 for (x = 0; x < 128; x++) {
1266                         uint32_t px = cpu_buf[y * 128 + x];
1267
1268                         if (y >= sq_y && y < (sq_y + sq_h) &&
1269                             x >= sq_x && x < (sq_x + sq_w))
1270                                 igt_assert(px == color);
1271                         else
1272                                 igt_assert(px == 0);
1273                 }
1274         }
1275
1276         gem_close(drm_fd, handle);
1277
1278         free(cpu_buf);
1279 }
1280
1281 /* Assuming execbuf already works, let's see what happens when we force many
1282  * suspend/resume cycles with commands. */
1283 static void gem_execbuf_stress_subtest(int rounds, int wait_flags)
1284 {
1285         int i;
1286         int batch_size = 4 * sizeof(uint32_t);
1287         uint32_t batch_buf[batch_size];
1288         uint32_t handle;
1289         struct drm_i915_gem_execbuffer2 execbuf = {};
1290         struct drm_i915_gem_exec_object2 objs[1] = {{}};
1291
1292         if (wait_flags & WAIT_PC8_RES)
1293                 igt_require(has_pc8);
1294
1295         i = 0;
1296         batch_buf[i++] = MI_NOOP;
1297         batch_buf[i++] = MI_NOOP;
1298         batch_buf[i++] = MI_BATCH_BUFFER_END;
1299         batch_buf[i++] = MI_NOOP;
1300         igt_assert(i * sizeof(uint32_t) == batch_size);
1301
1302         disable_all_screens(&ms_data);
1303         igt_assert(wait_for_suspended());
1304
1305         handle = gem_create(drm_fd, batch_size);
1306         gem_write(drm_fd, handle, 0, batch_buf, batch_size);
1307
1308         objs[0].handle = handle;
1309
1310         execbuf.buffers_ptr = (uintptr_t)objs;
1311         execbuf.buffer_count = 1;
1312         execbuf.batch_len = batch_size;
1313         execbuf.flags = I915_EXEC_RENDER;
1314         i915_execbuffer2_set_context_id(execbuf, 0);
1315
1316         for (i = 0; i < rounds; i++) {
1317                 do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
1318
1319                 if (wait_flags & WAIT_STATUS)
1320                         igt_assert(wait_for_suspended());
1321                 if (wait_flags & WAIT_PC8_RES)
1322                         igt_assert(pc8_plus_residency_changed(120));
1323                 if (wait_flags & WAIT_EXTRA)
1324                         sleep(5);
1325         }
1326
1327         gem_close(drm_fd, handle);
1328 }
1329
1330 /* When this test was written, it triggered WARNs and DRM_ERRORs on dmesg. */
1331 static void gem_idle_subtest(void)
1332 {
1333         disable_all_screens(&ms_data);
1334         igt_assert(wait_for_suspended());
1335
1336         sleep(5);
1337
1338         gem_quiescent_gpu(drm_fd);
1339 }
1340
1341 /* This also triggered WARNs on dmesg at some point. */
1342 static void reg_read_ioctl_subtest(void)
1343 {
1344         struct drm_i915_reg_read rr = {
1345                 .offset = 0x2358, /* render ring timestamp */
1346         };
1347
1348         disable_all_screens(&ms_data);
1349         igt_assert(wait_for_suspended());
1350
1351         do_ioctl(drm_fd, DRM_IOCTL_I915_REG_READ, &rr);
1352
1353         igt_assert(wait_for_suspended());
1354 }
1355
1356 static bool device_in_pci_d3(void)
1357 {
1358         struct pci_device *pci_dev;
1359         int rc;
1360         uint16_t val;
1361
1362         pci_dev = intel_get_pci_device();
1363
1364         rc = pci_device_cfg_read_u16(pci_dev, &val, 0xd4);
1365         igt_assert(rc == 0);
1366
1367         return (val & 0x3) == 0x3;
1368 }
1369
1370 static void pci_d3_state_subtest(void)
1371 {
1372         igt_require(has_runtime_pm);
1373
1374         disable_all_screens(&ms_data);
1375         igt_assert(wait_for_suspended());
1376
1377         igt_assert(device_in_pci_d3());
1378
1379         enable_one_screen(&ms_data);
1380         igt_assert(wait_for_active());
1381
1382         igt_assert(!device_in_pci_d3());
1383 }
1384
1385 static void stay_subtest(void)
1386 {
1387         disable_all_screens(&ms_data);
1388         igt_assert(wait_for_suspended());
1389
1390         while (1)
1391                 sleep(600);
1392 }
1393
1394 static void system_suspend_subtest(void)
1395 {
1396         disable_all_screens(&ms_data);
1397         igt_assert(wait_for_suspended());
1398         igt_system_suspend_autoresume();
1399         igt_assert(wait_for_suspended());
1400 }
1401
1402 /* Enable a screen, activate DPMS, then do a modeset. At some point our driver
1403  * produced WARNs on this case. */
1404 static void dpms_mode_unset_subtest(enum screen_type type)
1405 {
1406         disable_all_screens(&ms_data);
1407         igt_assert(wait_for_suspended());
1408
1409         igt_require(enable_one_screen_with_type(&ms_data, type));
1410         igt_assert(wait_for_active());
1411
1412         disable_all_screens_dpms(&ms_data);
1413         igt_assert(wait_for_suspended());
1414
1415         disable_all_screens(&ms_data);
1416         igt_assert(wait_for_suspended());
1417 }
1418
1419 static void fill_igt_fb(struct igt_fb *fb, uint32_t color)
1420 {
1421         int i;
1422         uint32_t *ptr;
1423
1424         ptr = gem_mmap__gtt(drm_fd, fb->gem_handle, fb->size, PROT_WRITE);
1425         for (i = 0; i < fb->size/sizeof(uint32_t); i++)
1426                 ptr[i] = color;
1427         igt_assert(munmap(ptr, fb->size) == 0);
1428 }
1429
1430 /* At some point, this test triggered WARNs in the Kernel. */
1431 static void cursor_subtest(bool dpms)
1432 {
1433         uint32_t crtc_id = 0, connector_id;
1434         drmModeModeInfoPtr mode;
1435         int rc;
1436         struct igt_fb scanout_fb, cursor_fb1, cursor_fb2, cursor_fb3;
1437
1438         disable_all_screens(&ms_data);
1439         igt_assert(wait_for_suspended());
1440
1441         igt_require(find_connector_for_modeset(&ms_data, SCREEN_TYPE_ANY,
1442                                                &connector_id, &mode));
1443
1444         crtc_id = ms_data.res->crtcs[0];
1445         igt_assert(crtc_id);
1446
1447         igt_create_fb(drm_fd, mode->hdisplay, mode->vdisplay,
1448                       DRM_FORMAT_XRGB8888, false, &scanout_fb);
1449         igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_ARGB8888, false, &cursor_fb1);
1450         igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_ARGB8888, false, &cursor_fb2);
1451         igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_ARGB8888, true, &cursor_fb3);
1452
1453         fill_igt_fb(&scanout_fb, 0xFF);
1454         fill_igt_fb(&cursor_fb1, 0xFF00FFFF);
1455         fill_igt_fb(&cursor_fb2, 0xFF00FF00);
1456         fill_igt_fb(&cursor_fb3, 0xFFFF0000);
1457
1458         rc = drmModeSetCrtc(drm_fd, crtc_id, scanout_fb.fb_id, 0, 0,
1459                             &connector_id, 1, mode);
1460         igt_assert(rc == 0);
1461         igt_assert(wait_for_active());
1462
1463         rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb1.gem_handle,
1464                               cursor_fb1.width, cursor_fb1.height);
1465         igt_assert(rc == 0);
1466         rc = drmModeMoveCursor(drm_fd, crtc_id, 0, 0);
1467         igt_assert(rc == 0);
1468         igt_assert(wait_for_active());
1469
1470         if (dpms)
1471                 disable_all_screens_dpms(&ms_data);
1472         else
1473                 disable_all_screens(&ms_data);
1474         igt_assert(wait_for_suspended());
1475
1476         /* First, just move the cursor. */
1477         rc = drmModeMoveCursor(drm_fd, crtc_id, 1, 1);
1478         igt_assert(rc == 0);
1479         igt_assert(wait_for_suspended());
1480
1481         /* Then unset it, and set a new one. */
1482         rc = drmModeSetCursor(drm_fd, crtc_id, 0, 0, 0);
1483         igt_assert(rc == 0);
1484         igt_assert(wait_for_suspended());
1485
1486         rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb2.gem_handle,
1487                               cursor_fb1.width, cursor_fb2.height);
1488         igt_assert(rc == 0);
1489         igt_assert(wait_for_suspended());
1490
1491         /* Move the new cursor. */
1492         rc = drmModeMoveCursor(drm_fd, crtc_id, 2, 2);
1493         igt_assert(rc == 0);
1494         igt_assert(wait_for_suspended());
1495
1496         /* Now set a new one without unsetting the previous one. */
1497         rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb1.gem_handle,
1498                               cursor_fb1.width, cursor_fb1.height);
1499         igt_assert(rc == 0);
1500         igt_assert(wait_for_suspended());
1501
1502         /* Cursor 3 was created with tiling and painted with a GTT mmap, so
1503          * hopefully it has some fences around it. */
1504         rc = drmModeRmFB(drm_fd, cursor_fb3.fb_id);
1505         igt_assert(rc == 0);
1506         gem_set_tiling(drm_fd, cursor_fb3.gem_handle, false, cursor_fb3.stride);
1507         igt_assert(wait_for_suspended());
1508
1509         rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb3.gem_handle,
1510                               cursor_fb3.width, cursor_fb3.height);
1511         igt_assert(rc == 0);
1512         igt_assert(wait_for_suspended());
1513
1514         /* Make sure nothing remains for the other tests. */
1515         rc = drmModeSetCursor(drm_fd, crtc_id, 0, 0, 0);
1516         igt_assert(rc == 0);
1517         igt_assert(wait_for_suspended());
1518 }
1519
1520 static enum plane_type get_plane_type(uint32_t plane_id)
1521 {
1522         int i;
1523         bool found;
1524         uint64_t prop_value;
1525         drmModePropertyPtr prop;
1526         const char *enum_name = NULL;
1527         enum plane_type type;
1528
1529         found = kmstest_get_property(drm_fd, plane_id, DRM_MODE_OBJECT_PLANE,
1530                                      "type", NULL, &prop_value, &prop);
1531         igt_assert(found);
1532
1533         igt_assert(prop->flags & DRM_MODE_PROP_ENUM);
1534         igt_assert(prop_value < prop->count_enums);
1535
1536         for (i = 0; i < prop->count_enums; i++) {
1537                 if (prop->enums[i].value == prop_value) {
1538                         enum_name = prop->enums[i].name;
1539                         break;
1540                 }
1541         }
1542         igt_assert(enum_name);
1543
1544         if (strcmp(enum_name, "Overlay") == 0)
1545                 type = PLANE_OVERLAY;
1546         else if (strcmp(enum_name, "Primary") == 0)
1547                 type = PLANE_PRIMARY;
1548         else if (strcmp(enum_name, "Cursor") == 0)
1549                 type = PLANE_CURSOR;
1550         else
1551                 igt_assert(0);
1552
1553         drmModeFreeProperty(prop);
1554
1555         return type;
1556 }
1557
1558 static void test_one_plane(bool dpms, uint32_t plane_id,
1559                            enum plane_type plane_type)
1560 {
1561         int rc;
1562         uint32_t plane_format, plane_w, plane_h;
1563         uint32_t crtc_id, connector_id;
1564         struct igt_fb scanout_fb, plane_fb1, plane_fb2;
1565         drmModeModeInfoPtr mode;
1566         int32_t crtc_x = 0, crtc_y = 0;
1567         bool tiling;
1568
1569         disable_all_screens(&ms_data);
1570         igt_assert(wait_for_suspended());
1571
1572         igt_require(find_connector_for_modeset(&ms_data, SCREEN_TYPE_ANY,
1573                                                &connector_id, &mode));
1574
1575         crtc_id = ms_data.res->crtcs[0];
1576         igt_assert(crtc_id);
1577
1578         igt_create_fb(drm_fd, mode->hdisplay, mode->vdisplay,
1579                       DRM_FORMAT_XRGB8888, false, &scanout_fb);
1580
1581         fill_igt_fb(&scanout_fb, 0xFF);
1582
1583         switch (plane_type) {
1584         case PLANE_OVERLAY:
1585                 plane_format = DRM_FORMAT_XRGB8888;
1586                 plane_w = 64;
1587                 plane_h = 64;
1588                 tiling = true;
1589                 break;
1590         case PLANE_PRIMARY:
1591                 plane_format = DRM_FORMAT_XRGB8888;
1592                 plane_w = mode->hdisplay;
1593                 plane_h = mode->vdisplay;
1594                 tiling = true;
1595                 break;
1596         case PLANE_CURSOR:
1597                 plane_format = DRM_FORMAT_ARGB8888;
1598                 plane_w = 64;
1599                 plane_h = 64;
1600                 tiling = false;
1601                 break;
1602         default:
1603                 igt_assert(0);
1604                 break;
1605         }
1606
1607         igt_create_fb(drm_fd, plane_w, plane_h, plane_format, tiling,
1608                       &plane_fb1);
1609         igt_create_fb(drm_fd, plane_w, plane_h, plane_format, tiling,
1610                       &plane_fb2);
1611         fill_igt_fb(&plane_fb1, 0xFF00FFFF);
1612         fill_igt_fb(&plane_fb2, 0xFF00FF00);
1613
1614         rc = drmModeSetCrtc(drm_fd, crtc_id, scanout_fb.fb_id, 0, 0,
1615                             &connector_id, 1, mode);
1616         igt_assert(rc == 0);
1617         igt_assert(wait_for_active());
1618
1619         rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0,
1620                              0, 0, plane_fb1.width, plane_fb1.height,
1621                              0 << 16, 0 << 16, plane_fb1.width << 16,
1622                              plane_fb1.height << 16);
1623         igt_assert(rc == 0);
1624
1625         if (dpms)
1626                 disable_all_screens_dpms(&ms_data);
1627         else
1628                 disable_all_screens(&ms_data);
1629         igt_assert(wait_for_suspended());
1630
1631         /* Just move the plane around. */
1632         if (plane_type != PLANE_PRIMARY) {
1633                 crtc_x++;
1634                 crtc_y++;
1635         }
1636         rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0,
1637                              crtc_x, crtc_y, plane_fb1.width, plane_fb1.height,
1638                              0 << 16, 0 << 16, plane_fb1.width << 16,
1639                              plane_fb1.height << 16);
1640         igt_assert(rc == 0);
1641
1642         /* Unset, then change the plane. */
1643         rc = drmModeSetPlane(drm_fd, plane_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1644         igt_assert(rc == 0);
1645
1646         rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb2.fb_id, 0,
1647                              crtc_x, crtc_y, plane_fb2.width, plane_fb2.height,
1648                              0 << 16, 0 << 16, plane_fb2.width << 16,
1649                              plane_fb2.height << 16);
1650         igt_assert(rc == 0);
1651
1652         /* Now change the plane without unsetting first. */
1653         rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0,
1654                              crtc_x, crtc_y, plane_fb1.width, plane_fb1.height,
1655                              0 << 16, 0 << 16, plane_fb1.width << 16,
1656                              plane_fb1.height << 16);
1657         igt_assert(rc == 0);
1658
1659         /* Make sure nothing remains for the other tests. */
1660         rc = drmModeSetPlane(drm_fd, plane_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1661         igt_assert(rc == 0);
1662 }
1663
1664 /* This one also triggered WARNs on our driver at some point in time. */
1665 static void planes_subtest(bool universal, bool dpms)
1666 {
1667         int i, rc, planes_tested = 0;
1668         drmModePlaneResPtr planes;
1669
1670         if (universal) {
1671                 rc = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES,
1672                                      1);
1673                 igt_require(rc == 0);
1674         }
1675
1676         planes = drmModeGetPlaneResources(drm_fd);
1677         for (i = 0; i < planes->count_planes; i++) {
1678                 drmModePlanePtr plane;
1679
1680                 plane = drmModeGetPlane(drm_fd, planes->planes[i]);
1681                 igt_assert(plane);
1682
1683                 /* We just pick the first CRTC on the list, so we can test for
1684                  * 0x1 as the index. */
1685                 if (plane->possible_crtcs & 0x1) {
1686                         enum plane_type type;
1687
1688                         type = universal ? get_plane_type(plane->plane_id) :
1689                                            PLANE_OVERLAY;
1690                         test_one_plane(dpms, plane->plane_id, type);
1691                         planes_tested++;
1692                 }
1693                 drmModeFreePlane(plane);
1694         }
1695         drmModeFreePlaneResources(planes);
1696
1697         if (universal) {
1698                 rc = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0);
1699                 igt_assert(rc == 0);
1700
1701                 igt_assert(planes_tested >= 3);
1702         } else {
1703                 igt_assert(planes_tested >= 1);
1704         }
1705 }
1706
1707 static void fences_subtest(bool dpms)
1708 {
1709         uint32_t connector_id, crtc_id = 0;
1710         drmModeModeInfoPtr mode;
1711         struct igt_fb scanout_fb;
1712         int rc, i;
1713         uint32_t *buf_ptr;
1714         uint32_t tiling = false, swizzle;
1715
1716         disable_all_screens(&ms_data);
1717         igt_assert(wait_for_suspended());
1718
1719         igt_require(find_connector_for_modeset(&ms_data, SCREEN_TYPE_ANY,
1720                                                &connector_id, &mode));
1721
1722         crtc_id = ms_data.res->crtcs[0];
1723         igt_assert(crtc_id);
1724
1725         igt_create_fb(drm_fd, mode->hdisplay, mode->vdisplay,
1726                       DRM_FORMAT_XRGB8888, true, &scanout_fb);
1727
1728         /* Even though we passed "true" as the tiling argument, double-check
1729          * that the fb is really tiled. */
1730         gem_get_tiling(drm_fd, scanout_fb.gem_handle, &tiling, &swizzle);
1731         igt_assert(tiling);
1732
1733         buf_ptr = gem_mmap__gtt(drm_fd, scanout_fb.gem_handle,
1734                                 scanout_fb.size, PROT_WRITE | PROT_READ);
1735         for (i = 0; i < scanout_fb.size/sizeof(uint32_t); i++)
1736                 buf_ptr[i] = i;
1737
1738         rc = drmModeSetCrtc(drm_fd, crtc_id, scanout_fb.fb_id, 0, 0,
1739                             &connector_id, 1, mode);
1740         igt_assert(rc == 0);
1741         igt_assert(wait_for_active());
1742
1743         if (dpms)
1744                 disable_all_screens_dpms(&ms_data);
1745         else
1746                 disable_all_screens(&ms_data);
1747         igt_assert(wait_for_suspended());
1748
1749         for (i = 0; i < scanout_fb.size/sizeof(uint32_t); i++)
1750                 igt_assert_eq(buf_ptr[i], i);
1751         igt_assert(wait_for_suspended());
1752
1753         if (dpms) {
1754                 drmModeConnectorPtr c = NULL;
1755
1756                 for (i = 0; i < ms_data.res->count_connectors; i++)
1757                         if (ms_data.connectors[i]->connector_id == connector_id)
1758                                 c = ms_data.connectors[i];
1759                 igt_assert(c);
1760
1761                 kmstest_set_connector_dpms(drm_fd, c, DRM_MODE_DPMS_ON);
1762         } else {
1763                 rc = drmModeSetCrtc(drm_fd, crtc_id, scanout_fb.fb_id, 0, 0,
1764                                     &connector_id, 1, mode);
1765                 igt_assert(rc == 0);
1766         }
1767         igt_assert(wait_for_active());
1768
1769         for (i = 0; i < scanout_fb.size/sizeof(uint32_t); i++)
1770                 igt_assert_eq(buf_ptr[i], i);
1771
1772         igt_assert(munmap(buf_ptr, scanout_fb.size) == 0);
1773 }
1774
1775 int rounds = 50;
1776 bool stay = false;
1777
1778 static int opt_handler(int opt, int opt_index)
1779 {
1780         switch (opt) {
1781         case 'q':
1782                 rounds = 10;
1783                 break;
1784         case 's':
1785                 stay = true;
1786                 break;
1787         default:
1788                 igt_assert(0);
1789         }
1790
1791         return 0;
1792 }
1793
1794 int main(int argc, char *argv[])
1795 {
1796         const char *help_str =
1797                "  --quick\t\tMake the stress-tests not stressful, for quick regression testing.\n"
1798                "  --stay\t\tDisable all screen and try to go into runtime pm. Useful for debugging.";
1799         static struct option long_options[] = {
1800                 {"quick", 0, 0, 'q'},
1801                 {"stay", 0, 0, 's'},
1802                 { 0, 0, 0, 0 }
1803         };
1804
1805         igt_subtest_init_parse_opts(argc, argv, "", long_options,
1806                                     help_str, opt_handler);
1807
1808         /* Skip instead of failing in case the machine is not prepared to reach
1809          * PC8+. We don't want bug reports from cases where the machine is just
1810          * not properly configured. */
1811         igt_fixture
1812                 setup_environment();
1813
1814         if (stay)
1815                 igt_subtest("stay")
1816                         stay_subtest();
1817
1818         /* Essential things */
1819         igt_subtest("rte")
1820                 basic_subtest();
1821         igt_subtest("drm-resources-equal")
1822                 drm_resources_equal_subtest();
1823         igt_subtest("pci-d3-state")
1824                 pci_d3_state_subtest();
1825
1826         /* Basic modeset */
1827         igt_subtest("modeset-lpsp")
1828                 modeset_subtest(SCREEN_TYPE_LPSP, 1, WAIT_STATUS);
1829         igt_subtest("modeset-non-lpsp")
1830                 modeset_subtest(SCREEN_TYPE_NON_LPSP, 1, WAIT_STATUS);
1831         igt_subtest("dpms-lpsp")
1832                 modeset_subtest(SCREEN_TYPE_LPSP, 1, WAIT_STATUS | USE_DPMS);
1833         igt_subtest("dpms-non-lpsp")
1834                 modeset_subtest(SCREEN_TYPE_NON_LPSP, 1, WAIT_STATUS | USE_DPMS);
1835
1836         /* GEM */
1837         igt_subtest("gem-mmap-cpu")
1838                 gem_mmap_subtest(false);
1839         igt_subtest("gem-mmap-gtt")
1840                 gem_mmap_subtest(true);
1841         igt_subtest("gem-pread")
1842                 gem_pread_subtest();
1843         igt_subtest("gem-execbuf")
1844                 gem_execbuf_subtest();
1845         igt_subtest("gem-idle")
1846                 gem_idle_subtest();
1847
1848         /* Planes and cursors */
1849         igt_subtest("cursor")
1850                 cursor_subtest(false);
1851         igt_subtest("cursor-dpms")
1852                 cursor_subtest(true);
1853         igt_subtest("legacy-planes")
1854                 planes_subtest(false, false);
1855         igt_subtest("legacy-planes-dpms")
1856                 planes_subtest(false, true);
1857         igt_subtest("universal-planes")
1858                 planes_subtest(true, false);
1859         igt_subtest("universal-planes-dpms")
1860                 planes_subtest(true, true);
1861
1862         /* Misc */
1863         igt_subtest("reg-read-ioctl")
1864                 reg_read_ioctl_subtest();
1865         igt_subtest("i2c")
1866                 i2c_subtest();
1867         igt_subtest("pc8-residency")
1868                 pc8_residency_subtest();
1869         igt_subtest("debugfs-read")
1870                 debugfs_read_subtest();
1871         igt_subtest("debugfs-forcewake-user")
1872                 debugfs_forcewake_user_subtest();
1873         igt_subtest("sysfs-read")
1874                 sysfs_read_subtest();
1875         igt_subtest("dpms-mode-unset-lpsp")
1876                 dpms_mode_unset_subtest(SCREEN_TYPE_LPSP);
1877         igt_subtest("dpms-mode-unset-non-lpsp")
1878                 dpms_mode_unset_subtest(SCREEN_TYPE_NON_LPSP);
1879         igt_subtest("fences")
1880                 fences_subtest(false);
1881         igt_subtest("fences-dpms")
1882                 fences_subtest(true);
1883
1884         /* Modeset stress */
1885         igt_subtest("modeset-lpsp-stress")
1886                 modeset_subtest(SCREEN_TYPE_LPSP, rounds, WAIT_STATUS);
1887         igt_subtest("modeset-non-lpsp-stress")
1888                 modeset_subtest(SCREEN_TYPE_NON_LPSP, rounds, WAIT_STATUS);
1889         igt_subtest("modeset-lpsp-stress-no-wait")
1890                 modeset_subtest(SCREEN_TYPE_LPSP, rounds, DONT_WAIT);
1891         igt_subtest("modeset-non-lpsp-stress-no-wait")
1892                 modeset_subtest(SCREEN_TYPE_NON_LPSP, rounds, DONT_WAIT);
1893         igt_subtest("modeset-pc8-residency-stress")
1894                 modeset_subtest(SCREEN_TYPE_ANY, rounds, WAIT_PC8_RES);
1895         igt_subtest("modeset-stress-extra-wait")
1896                 modeset_subtest(SCREEN_TYPE_ANY, rounds,
1897                                 WAIT_STATUS | WAIT_EXTRA);
1898
1899         /* System suspend */
1900         igt_subtest("system-suspend")
1901                 system_suspend_subtest();
1902
1903         /* GEM stress */
1904         igt_subtest("gem-execbuf-stress")
1905                 gem_execbuf_stress_subtest(rounds, WAIT_STATUS);
1906         igt_subtest("gem-execbuf-stress-pc8")
1907                 gem_execbuf_stress_subtest(rounds, WAIT_PC8_RES);
1908         igt_subtest("gem-execbuf-stress-extra-wait")
1909                 gem_execbuf_stress_subtest(rounds, WAIT_STATUS | WAIT_EXTRA);
1910
1911         igt_fixture
1912                 teardown_environment();
1913
1914         igt_exit();
1915 }