1 /*
2 * Copyright © 2013, 2015 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 <[email protected]>
25 *
26 */
27
28 #include "config.h"
29
30 #include <stdio.h>
31 #include <stdint.h>
32 #include <stdbool.h>
33 #include <string.h>
34 #include <ftw.h>
35
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include <dirent.h>
39 #include <sys/ioctl.h>
40 #include <sys/mman.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <linux/i2c.h>
44 #include <linux/i2c-dev.h>
45
46 #include <drm.h>
47
48 #include "igt.h"
49 #include "igt_kmod.h"
50 #include "igt_sysfs.h"
51 #include "igt_debugfs.h"
52 #include "igt_device.h"
53 #include "igt_edid.h"
54
55 #define MSR_PKG_CST_CONFIG_CONTROL 0xE2
56 /* HSW/BDW: */
57 #define PKG_CST_LIMIT_MASK 0xF
58 #define PKG_CST_LIMIT_C8 0x6
59
60 #define MSR_PC8_RES 0x630
61 #define MSR_PC9_RES 0x631
62 #define MSR_PC10_RES 0x632
63
64 #define MAX_CONNECTORS 32
65 #define MAX_ENCODERS 32
66 #define MAX_CRTCS 16
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 enum plane_type {
80 PLANE_OVERLAY,
81 PLANE_PRIMARY,
82 PLANE_CURSOR,
83 };
84
85 /* Wait flags */
86 #define DONT_WAIT 0
87 #define WAIT_STATUS 1
88 #define WAIT_PC8_RES 2
89 #define WAIT_EXTRA 4
90 #define USE_DPMS 8
91
92 int drm_fd, msr_fd, pc8_status_fd;
93 int debugfs;
94 bool has_runtime_pm, has_pc8;
95 struct mode_set_data ms_data;
96
97 /* Stuff used when creating FBs and mode setting. */
98 struct mode_set_data {
99 drmModeResPtr res;
100 drmModeConnectorPtr connectors[MAX_CONNECTORS];
101 drmModePropertyBlobPtr edids[MAX_CONNECTORS];
102
103 uint32_t devid;
104 };
105
106 /* Stuff we query at different times so we can compare. */
107 struct compare_data {
108 drmModeResPtr res;
109 drmModeEncoderPtr encoders[MAX_ENCODERS];
110 drmModeConnectorPtr connectors[MAX_CONNECTORS];
111 drmModeCrtcPtr crtcs[MAX_CRTCS];
112 drmModePropertyBlobPtr edids[MAX_CONNECTORS];
113 };
114
115 struct modeset_params {
116 uint32_t crtc_id;
117 uint32_t connector_id;
118 struct igt_fb fb;
119 drmModeModeInfoPtr mode;
120 };
121
122 struct modeset_params lpsp_mode_params;
123 struct modeset_params non_lpsp_mode_params;
124 struct modeset_params *default_mode_params;
125
126 static int8_t *pm_data = NULL;
127
modprobe(const char * driver)128 static int modprobe(const char *driver)
129 {
130 return igt_kmod_load(driver, NULL);
131 }
132
133 /* If the read fails, then the machine doesn't support PC8+ residencies. */
supports_pc8_plus_residencies(void)134 static bool supports_pc8_plus_residencies(void)
135 {
136 int rc;
137 uint64_t val;
138
139 rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC8_RES);
140 if (rc != sizeof(val))
141 return false;
142 rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC9_RES);
143 if (rc != sizeof(val))
144 return false;
145 rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC10_RES);
146 if (rc != sizeof(val))
147 return false;
148
149 rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PKG_CST_CONFIG_CONTROL);
150 if (rc != sizeof(val))
151 return false;
152 if ((val & PKG_CST_LIMIT_MASK) < PKG_CST_LIMIT_C8) {
153 igt_info("PKG C-states limited below PC8 by the BIOS\n");
154 return false;
155 }
156
157 return true;
158 }
159
get_residency(uint32_t type)160 static uint64_t get_residency(uint32_t type)
161 {
162 int rc;
163 uint64_t ret;
164
165 rc = pread(msr_fd, &ret, sizeof(uint64_t), type);
166 igt_assert(rc == sizeof(ret));
167
168 return ret;
169 }
170
pc8_plus_residency_changed(unsigned int timeout_sec)171 static bool pc8_plus_residency_changed(unsigned int timeout_sec)
172 {
173 uint64_t res_pc8, res_pc9, res_pc10;
174
175 res_pc8 = get_residency(MSR_PC8_RES);
176 res_pc9 = get_residency(MSR_PC9_RES);
177 res_pc10 = get_residency(MSR_PC10_RES);
178
179 return igt_wait(res_pc8 != get_residency(MSR_PC8_RES) ||
180 res_pc9 != get_residency(MSR_PC9_RES) ||
181 res_pc10 != get_residency(MSR_PC10_RES),
182 timeout_sec * 1000, 100);
183 }
184
get_pc8_status(void)185 static enum pc8_status get_pc8_status(void)
186 {
187 ssize_t n_read;
188 char buf[150]; /* The whole file has less than 100 chars. */
189
190 lseek(pc8_status_fd, 0, SEEK_SET);
191 n_read = read(pc8_status_fd, buf, ARRAY_SIZE(buf));
192 igt_assert(n_read >= 0);
193 buf[n_read] = '\0';
194
195 if (strstr(buf, "\nEnabled: yes\n"))
196 return PC8_ENABLED;
197 else
198 return PC8_DISABLED;
199 }
200
wait_for_pc8_status(enum pc8_status status)201 static bool wait_for_pc8_status(enum pc8_status status)
202 {
203 return igt_wait(get_pc8_status() == status, 10000, 100);
204 }
205
wait_for_suspended(void)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
wait_for_active(void)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
disable_all_screens_dpms(struct mode_set_data * data)222 static void disable_all_screens_dpms(struct mode_set_data *data)
223 {
224 if (!data->res)
225 return;
226
227 for (int i = 0; i < data->res->count_connectors; i++) {
228 drmModeConnectorPtr c = data->connectors[i];
229
230 kmstest_set_connector_dpms(drm_fd, c, DRM_MODE_DPMS_OFF);
231 }
232 }
233
disable_all_screens(struct mode_set_data * data)234 static void disable_all_screens(struct mode_set_data *data)
235 {
236 if (data->res)
237 kmstest_unset_all_crtcs(drm_fd, data->res);
238 }
239
240 #define disable_all_screens_and_wait(data) do { \
241 disable_all_screens(data); \
242 igt_assert(wait_for_suspended()); \
243 } while (0)
244
disable_or_dpms_all_screens(struct mode_set_data * data,bool dpms)245 static void disable_or_dpms_all_screens(struct mode_set_data *data, bool dpms)
246 {
247 if (dpms)
248 disable_all_screens_dpms(&ms_data);
249 else
250 disable_all_screens(&ms_data);
251 }
252
253 #define disable_or_dpms_all_screens_and_wait(data, dpms) do { \
254 disable_or_dpms_all_screens((data), (dpms)); \
255 igt_assert(wait_for_suspended()); \
256 } while (0)
257
init_modeset_params_for_type(struct mode_set_data * data,struct modeset_params * params,enum screen_type type)258 static bool init_modeset_params_for_type(struct mode_set_data *data,
259 struct modeset_params *params,
260 enum screen_type type)
261 {
262 drmModeConnectorPtr connector = NULL;
263 drmModeModeInfoPtr mode = NULL;
264
265 if (!data->res)
266 return false;
267
268 for (int i = 0; i < data->res->count_connectors; i++) {
269 drmModeConnectorPtr c = data->connectors[i];
270
271 if (type == SCREEN_TYPE_LPSP &&
272 c->connector_type != DRM_MODE_CONNECTOR_eDP)
273 continue;
274
275 if (type == SCREEN_TYPE_NON_LPSP &&
276 c->connector_type == DRM_MODE_CONNECTOR_eDP)
277 continue;
278
279 if (c->connection == DRM_MODE_CONNECTED && c->count_modes) {
280 connector = c;
281 mode = &c->modes[0];
282 break;
283 }
284 }
285
286 if (!connector)
287 return false;
288
289 igt_create_pattern_fb(drm_fd, mode->hdisplay, mode->vdisplay,
290 DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
291 ¶ms->fb);
292
293 params->crtc_id = kmstest_find_crtc_for_connector(drm_fd, data->res,
294 connector, 0);
295 params->connector_id = connector->connector_id;
296 params->mode = mode;
297
298 return true;
299 }
300
init_modeset_cached_params(struct mode_set_data * data)301 static void init_modeset_cached_params(struct mode_set_data *data)
302 {
303 bool lpsp, non_lpsp;
304
305 lpsp = init_modeset_params_for_type(data, &lpsp_mode_params,
306 SCREEN_TYPE_LPSP);
307 non_lpsp = init_modeset_params_for_type(data, &non_lpsp_mode_params,
308 SCREEN_TYPE_NON_LPSP);
309
310 if (lpsp)
311 default_mode_params = &lpsp_mode_params;
312 else if (non_lpsp)
313 default_mode_params = &non_lpsp_mode_params;
314 else
315 default_mode_params = NULL;
316 }
317
set_mode_for_params(struct modeset_params * params)318 static bool set_mode_for_params(struct modeset_params *params)
319 {
320 int rc;
321
322 rc = drmModeSetCrtc(drm_fd, params->crtc_id, params->fb.fb_id, 0, 0,
323 ¶ms->connector_id, 1, params->mode);
324 return (rc == 0);
325 }
326
327 #define set_mode_for_params_and_wait(params) do { \
328 igt_assert(set_mode_for_params(params)); \
329 igt_assert(wait_for_active()); \
330 } while (0)
331
enable_one_screen_with_type(struct mode_set_data * data,enum screen_type type)332 static bool enable_one_screen_with_type(struct mode_set_data *data,
333 enum screen_type type)
334 {
335 struct modeset_params *params = NULL;
336
337 switch (type) {
338 case SCREEN_TYPE_ANY:
339 params = default_mode_params;
340 break;
341 case SCREEN_TYPE_LPSP:
342 params = &lpsp_mode_params;
343 break;
344 case SCREEN_TYPE_NON_LPSP:
345 params = &non_lpsp_mode_params;
346 break;
347 default:
348 igt_assert(0);
349 }
350
351 if (!params)
352 return false;
353
354 return set_mode_for_params(params);
355 }
356
enable_one_screen(struct mode_set_data * data)357 static void enable_one_screen(struct mode_set_data *data)
358 {
359 /* SKIP if there are no connected screens. */
360 igt_require(enable_one_screen_with_type(data, SCREEN_TYPE_ANY));
361 }
362
363 #define enable_one_screen_and_wait(data) do { \
364 enable_one_screen(data); \
365 igt_assert(wait_for_active()); \
366 } while (0)
367
get_connector_edid(drmModeConnectorPtr connector,int index)368 static drmModePropertyBlobPtr get_connector_edid(drmModeConnectorPtr connector,
369 int index)
370 {
371 bool found;
372 uint64_t prop_value;
373 drmModePropertyPtr prop;
374 drmModePropertyBlobPtr blob = NULL;
375
376 found = kmstest_get_property(drm_fd, connector->connector_id,
377 DRM_MODE_OBJECT_CONNECTOR, "EDID",
378 NULL, &prop_value, &prop);
379
380 if (found) {
381 igt_assert(prop->flags & DRM_MODE_PROP_BLOB);
382 igt_assert(prop->count_blobs == 0);
383
384 blob = drmModeGetPropertyBlob(drm_fd, prop_value);
385
386 drmModeFreeProperty(prop);
387 }
388
389 return blob;
390 }
391
init_mode_set_data(struct mode_set_data * data)392 static void init_mode_set_data(struct mode_set_data *data)
393 {
394 data->res = drmModeGetResources(drm_fd);
395 if (data->res) {
396 igt_assert(data->res->count_connectors <= MAX_CONNECTORS);
397 for (int i = 0; i < data->res->count_connectors; i++) {
398 data->connectors[i] =
399 drmModeGetConnector(drm_fd,
400 data->res->connectors[i]);
401 data->edids[i] = get_connector_edid(data->connectors[i], i);
402 }
403
404 kmstest_set_vt_graphics_mode();
405 }
406
407 data->devid = intel_get_drm_devid(drm_fd);
408 init_modeset_cached_params(&ms_data);
409 }
410
fini_mode_set_data(struct mode_set_data * data)411 static void fini_mode_set_data(struct mode_set_data *data)
412 {
413 if (data->res) {
414 for (int i = 0; i < data->res->count_connectors; i++) {
415 drmModeFreeConnector(data->connectors[i]);
416 drmModeFreePropertyBlob(data->edids[i]);
417 }
418 drmModeFreeResources(data->res);
419 }
420 }
421
get_drm_info(struct compare_data * data)422 static void get_drm_info(struct compare_data *data)
423 {
424 int i;
425
426 data->res = drmModeGetResources(drm_fd);
427 if (!data->res)
428 return;
429
430 igt_assert(data->res->count_connectors <= MAX_CONNECTORS);
431 igt_assert(data->res->count_encoders <= MAX_ENCODERS);
432 igt_assert(data->res->count_crtcs <= MAX_CRTCS);
433
434 for (i = 0; i < data->res->count_connectors; i++) {
435 /* Don't use GetConnectorCurrent, we want to force a reprobe
436 * here. */
437 data->connectors[i] = drmModeGetConnector(drm_fd,
438 data->res->connectors[i]);
439 data->edids[i] = get_connector_edid(data->connectors[i], i);
440 }
441 for (i = 0; i < data->res->count_encoders; i++)
442 data->encoders[i] = drmModeGetEncoder(drm_fd,
443 data->res->encoders[i]);
444 for (i = 0; i < data->res->count_crtcs; i++)
445 data->crtcs[i] = drmModeGetCrtc(drm_fd, data->res->crtcs[i]);
446 }
447
free_drm_info(struct compare_data * data)448 static void free_drm_info(struct compare_data *data)
449 {
450 int i;
451
452 if (!data->res)
453 return;
454
455 for (i = 0; i < data->res->count_connectors; i++) {
456 drmModeFreeConnector(data->connectors[i]);
457 drmModeFreePropertyBlob(data->edids[i]);
458 }
459 for (i = 0; i < data->res->count_encoders; i++)
460 drmModeFreeEncoder(data->encoders[i]);
461 for (i = 0; i < data->res->count_crtcs; i++)
462 drmModeFreeCrtc(data->crtcs[i]);
463
464 drmModeFreeResources(data->res);
465 }
466
467 #define COMPARE(d1, d2, data) igt_assert_eq(d1->data, d2->data)
468 #define COMPARE_ARRAY(d1, d2, size, data) do { \
469 for (i = 0; i < size; i++) \
470 igt_assert(d1->data[i] == d2->data[i]); \
471 } while (0)
472
assert_drm_resources_equal(struct compare_data * d1,struct compare_data * d2)473 static void assert_drm_resources_equal(struct compare_data *d1,
474 struct compare_data *d2)
475 {
476 COMPARE(d1, d2, res->count_connectors);
477 COMPARE(d1, d2, res->count_encoders);
478 COMPARE(d1, d2, res->count_crtcs);
479 COMPARE(d1, d2, res->min_width);
480 COMPARE(d1, d2, res->max_width);
481 COMPARE(d1, d2, res->min_height);
482 COMPARE(d1, d2, res->max_height);
483 }
484
assert_modes_equal(drmModeModeInfoPtr m1,drmModeModeInfoPtr m2)485 static void assert_modes_equal(drmModeModeInfoPtr m1, drmModeModeInfoPtr m2)
486 {
487 COMPARE(m1, m2, clock);
488 COMPARE(m1, m2, hdisplay);
489 COMPARE(m1, m2, hsync_start);
490 COMPARE(m1, m2, hsync_end);
491 COMPARE(m1, m2, htotal);
492 COMPARE(m1, m2, hskew);
493 COMPARE(m1, m2, vdisplay);
494 COMPARE(m1, m2, vsync_start);
495 COMPARE(m1, m2, vsync_end);
496 COMPARE(m1, m2, vtotal);
497 COMPARE(m1, m2, vscan);
498 COMPARE(m1, m2, vrefresh);
499 COMPARE(m1, m2, flags);
500 COMPARE(m1, m2, type);
501 igt_assert(strcmp(m1->name, m2->name) == 0);
502 }
503
assert_drm_connectors_equal(drmModeConnectorPtr c1,drmModeConnectorPtr c2)504 static void assert_drm_connectors_equal(drmModeConnectorPtr c1,
505 drmModeConnectorPtr c2)
506 {
507 int i;
508
509 COMPARE(c1, c2, connector_id);
510 COMPARE(c1, c2, connector_type);
511 COMPARE(c1, c2, connector_type_id);
512 COMPARE(c1, c2, mmWidth);
513 COMPARE(c1, c2, mmHeight);
514 COMPARE(c1, c2, count_modes);
515 COMPARE(c1, c2, count_props);
516 COMPARE(c1, c2, count_encoders);
517 COMPARE_ARRAY(c1, c2, c1->count_props, props);
518 COMPARE_ARRAY(c1, c2, c1->count_encoders, encoders);
519
520 for (i = 0; i < c1->count_modes; i++)
521 assert_modes_equal(&c1->modes[0], &c2->modes[0]);
522 }
523
assert_drm_encoders_equal(drmModeEncoderPtr e1,drmModeEncoderPtr e2)524 static void assert_drm_encoders_equal(drmModeEncoderPtr e1,
525 drmModeEncoderPtr e2)
526 {
527 COMPARE(e1, e2, encoder_id);
528 COMPARE(e1, e2, encoder_type);
529 COMPARE(e1, e2, possible_crtcs);
530 COMPARE(e1, e2, possible_clones);
531 }
532
assert_drm_crtcs_equal(drmModeCrtcPtr c1,drmModeCrtcPtr c2)533 static void assert_drm_crtcs_equal(drmModeCrtcPtr c1, drmModeCrtcPtr c2)
534 {
535 COMPARE(c1, c2, crtc_id);
536 }
537
assert_drm_edids_equal(drmModePropertyBlobPtr e1,drmModePropertyBlobPtr e2)538 static void assert_drm_edids_equal(drmModePropertyBlobPtr e1,
539 drmModePropertyBlobPtr e2)
540 {
541 if (!e1 && !e2)
542 return;
543 igt_assert(e1 && e2);
544
545 COMPARE(e1, e2, length);
546
547 igt_assert(memcmp(e1->data, e2->data, e1->length) == 0);
548 }
549
assert_drm_infos_equal(struct compare_data * d1,struct compare_data * d2)550 static void assert_drm_infos_equal(struct compare_data *d1,
551 struct compare_data *d2)
552 {
553 int i;
554
555 if (d1->res == d2->res)
556 return;
557
558 igt_assert(d1->res);
559 igt_assert(d2->res);
560
561 assert_drm_resources_equal(d1, d2);
562
563 for (i = 0; i < d1->res->count_connectors; i++) {
564 assert_drm_connectors_equal(d1->connectors[i],
565 d2->connectors[i]);
566 assert_drm_edids_equal(d1->edids[i], d2->edids[i]);
567 }
568
569 for (i = 0; i < d1->res->count_encoders; i++)
570 assert_drm_encoders_equal(d1->encoders[i], d2->encoders[i]);
571
572 for (i = 0; i < d1->res->count_crtcs; i++)
573 assert_drm_crtcs_equal(d1->crtcs[i], d2->crtcs[i]);
574 }
575
find_i2c_path(const char * connector_name,char * i2c_path)576 static bool find_i2c_path(const char *connector_name, char *i2c_path)
577 {
578 struct dirent *dirent;
579 DIR *dir;
580 int sysfs_card_fd = igt_sysfs_open(drm_fd);
581 int connector_fd = -1;
582 bool found_i2c_file = false;
583
584 dir = fdopendir(sysfs_card_fd);
585 igt_assert(dir);
586
587 while ((dirent = readdir(dir))) {
588 /* Skip "cardx-" prefix */
589 char *dirname = strchr(dirent->d_name, '-');
590 if (dirname==NULL)
591 continue;
592 ++dirname;
593
594 if (strcmp(dirname, connector_name) == 0) {
595 connector_fd = openat(sysfs_card_fd, dirent->d_name, O_RDONLY);
596 break;
597 }
598 }
599 closedir(dir);
600
601 if (connector_fd < 0)
602 return false;
603
604 dir = fdopendir(connector_fd);
605 igt_assert(dir);
606
607 while ((dirent = readdir(dir))) {
608 if (strncmp(dirent->d_name, "i2c-", 4) == 0) {
609 sprintf(i2c_path, "/dev/%s", dirent->d_name);
610 found_i2c_file = true;
611 }
612 }
613 closedir(dir);
614 return found_i2c_file;
615 }
616
617
i2c_read_edid(const char * connector_name,unsigned char * edid)618 static bool i2c_read_edid(const char *connector_name, unsigned char *edid)
619 {
620 char i2c_path[PATH_MAX];
621 bool result;
622 int rc, fd;
623 struct i2c_msg msgs[] = {
624 { /* Start at 0. */
625 .addr = 0x50,
626 .flags = 0,
627 .len = 1,
628 .buf = edid,
629 }, { /* Now read the EDID. */
630 .addr = 0x50,
631 .flags = I2C_M_RD,
632 .len = 128,
633 .buf = edid,
634 }
635 };
636 struct i2c_rdwr_ioctl_data msgset = {
637 .msgs = msgs,
638 .nmsgs = 2,
639 };
640
641 result = find_i2c_path(connector_name, i2c_path);
642 if (!result)
643 return false;
644
645 fd = open(i2c_path, O_RDWR);
646 igt_assert_neq(fd, -1);
647
648 rc = ioctl(fd, I2C_RDWR, &msgset);
649 if (rc==-1) {
650 igt_debug("I2C access failed with errno %d, %s\n",
651 errno, strerror(errno));
652 errno = 0;
653 }
654
655 close(fd);
656 return rc >= 0;
657 }
658
format_hex_string(const unsigned char edid[static EDID_BLOCK_SIZE],char buf[static EDID_BLOCK_SIZE * 5+1])659 static void format_hex_string(const unsigned char edid[static EDID_BLOCK_SIZE],
660 char buf[static EDID_BLOCK_SIZE * 5 + 1])
661 {
662 for (int i = 0; i < EDID_BLOCK_SIZE; ++i)
663 sprintf(buf+i*5, "0x%02x ", edid[i]);
664 }
665
test_i2c(struct mode_set_data * data)666 static void test_i2c(struct mode_set_data *data)
667 {
668 bool edid_mistmach_i2c_vs_drm = false;
669 igt_display_t display;
670 igt_display_require(&display, drm_fd);
671
672 for (int i = 0; i < data->res->count_connectors; i++) {
673 unsigned char *drm_edid = data->edids[i] ? data->edids[i]->data : NULL;
674 unsigned char i2c_edid[EDID_BLOCK_SIZE] = {};
675
676 igt_output_t *output = igt_output_from_connector(&display,
677 data->connectors[i]);
678 char *connector_name = (char *) igt_output_name(output);
679
680 bool got_i2c_edid = i2c_read_edid(connector_name, i2c_edid);
681 bool got_drm_edid = drm_edid != NULL;
682 bool is_vga = data->connectors[i]->connector_type == DRM_MODE_CONNECTOR_VGA;
683
684 bool edids_equal;
685
686 /* We fail to detect some VGA monitors using our i2c method. If you look
687 * at the dmesg of these cases, you'll see the Kernel complaining about
688 * the EDID reading mostly FFs and then disabling bit-banging. Since we
689 * don't want to reimplement everything the Kernel does, let's just
690 * accept the fact that some VGA outputs won't be properly detected. */
691 if (is_vga)
692 continue;
693
694 if (!got_i2c_edid && !got_drm_edid)
695 continue;
696
697 if (got_i2c_edid && got_drm_edid)
698 edids_equal = (0 == memcmp(drm_edid, i2c_edid, EDID_BLOCK_SIZE));
699 else
700 edids_equal = false;
701
702
703 if (!edids_equal) {
704 char buf[5 * EDID_BLOCK_SIZE + 1];
705 igt_critical("Detected EDID mismatch on connector %s\n",
706 connector_name);
707
708 if(got_i2c_edid)
709 format_hex_string(i2c_edid, buf);
710 else
711 sprintf(buf, "NULL");
712
713 igt_critical("i2c: %s\n", buf);
714
715 if(got_drm_edid)
716 format_hex_string(drm_edid, buf);
717 else
718 sprintf(buf, "NULL");
719
720 igt_critical("drm: %s\n", buf);
721
722 edid_mistmach_i2c_vs_drm = true;
723 }
724 }
725 igt_fail_on_f(edid_mistmach_i2c_vs_drm,
726 "There is an EDID mismatch between i2c and DRM!\n");
727 }
728
setup_pc8(void)729 static void setup_pc8(void)
730 {
731 has_pc8 = false;
732
733 /* Only Haswell supports the PC8 feature. */
734 if (!IS_HASWELL(ms_data.devid) && !IS_BROADWELL(ms_data.devid))
735 return;
736
737 /* Make sure our Kernel supports MSR and the module is loaded. */
738 igt_require(modprobe("msr") == 0);
739
740 msr_fd = open("/dev/cpu/0/msr", O_RDONLY);
741 igt_assert_f(msr_fd >= 0,
742 "Can't open /dev/cpu/0/msr.\n");
743
744 /* Non-ULT machines don't support PC8+. */
745 if (!supports_pc8_plus_residencies())
746 return;
747
748 pc8_status_fd = openat(debugfs, "i915_pc8_status", O_RDONLY);
749 if (pc8_status_fd == -1)
750 pc8_status_fd = openat(debugfs,
751 "i915_runtime_pm_status", O_RDONLY);
752 igt_assert_f(pc8_status_fd >= 0,
753 "Can't open /sys/kernel/debug/dri/0/i915_runtime_pm_status");
754
755 has_pc8 = true;
756 }
757
dmc_loaded(void)758 static bool dmc_loaded(void)
759 {
760 char buf[15];
761 int len;
762
763 len = igt_sysfs_read(debugfs, "i915_dmc_info", buf, sizeof(buf) - 1);
764 if (len < 0)
765 return true; /* no CSR support, no DMC requirement */
766
767 buf[len] = '\0';
768
769 igt_info("DMC: %s\n", buf);
770 return strstr(buf, "fw loaded: yes");
771 }
772
dump_file(int dir,const char * filename)773 static void dump_file(int dir, const char *filename)
774 {
775 char *contents;
776
777 contents = igt_sysfs_get(dir, filename);
778 if (!contents)
779 return;
780
781 igt_info("%s:\n%s\n", filename, contents);
782 free(contents);
783 }
784
setup_environment(void)785 static bool setup_environment(void)
786 {
787 if (has_runtime_pm)
788 goto out;
789
790 drm_fd = __drm_open_driver(DRIVER_INTEL);
791 igt_require(drm_fd != -1);
792 igt_device_set_master(drm_fd);
793
794 debugfs = igt_debugfs_dir(drm_fd);
795 igt_require(debugfs != -1);
796
797 init_mode_set_data(&ms_data);
798
799 pm_data = igt_pm_enable_sata_link_power_management();
800
801 has_runtime_pm = igt_setup_runtime_pm();
802 setup_pc8();
803
804 igt_info("Runtime PM support: %d\n", has_runtime_pm);
805 igt_info("PC8 residency support: %d\n", has_pc8);
806 igt_require(has_runtime_pm);
807 igt_require(dmc_loaded());
808
809 out:
810 disable_all_screens(&ms_data);
811 dump_file(debugfs, "i915_runtime_pm_status");
812
813 return wait_for_suspended();
814 }
815
teardown_environment(void)816 static void teardown_environment(void)
817 {
818 close(msr_fd);
819 if (has_pc8)
820 close(pc8_status_fd);
821
822 igt_restore_runtime_pm();
823
824 igt_pm_restore_sata_link_power_management(pm_data);
825 free(pm_data);
826
827 fini_mode_set_data(&ms_data);
828
829 close(debugfs);
830 close(drm_fd);
831
832 has_runtime_pm = false;
833 }
834
basic_subtest(void)835 static void basic_subtest(void)
836 {
837 disable_all_screens_and_wait(&ms_data);
838
839 if (ms_data.res)
840 enable_one_screen_and_wait(&ms_data);
841
842 /* XXX Also we can test wake up via exec nop */
843 }
844
pc8_residency_subtest(void)845 static void pc8_residency_subtest(void)
846 {
847 igt_require(has_pc8);
848
849 /* Make sure PC8+ residencies move! */
850 disable_all_screens(&ms_data);
851 igt_assert_f(pc8_plus_residency_changed(30),
852 "Machine is not reaching PC8+ states, please check its "
853 "configuration.\n");
854
855 /* Make sure PC8+ residencies stop! */
856 enable_one_screen(&ms_data);
857 igt_assert_f(!pc8_plus_residency_changed(10),
858 "PC8+ residency didn't stop with screen enabled.\n");
859 }
860
modeset_subtest(enum screen_type type,int rounds,int wait_flags)861 static void modeset_subtest(enum screen_type type, int rounds, int wait_flags)
862 {
863 int i;
864
865 if (wait_flags & WAIT_PC8_RES)
866 igt_require(has_pc8);
867
868 if (wait_flags & WAIT_EXTRA)
869 rounds /= 2;
870
871 for (i = 0; i < rounds; i++) {
872 if (wait_flags & USE_DPMS)
873 disable_all_screens_dpms(&ms_data);
874 else
875 disable_all_screens(&ms_data);
876
877 if (wait_flags & WAIT_STATUS)
878 igt_assert(wait_for_suspended());
879 if (wait_flags & WAIT_PC8_RES)
880 igt_assert(pc8_plus_residency_changed(30));
881 if (wait_flags & WAIT_EXTRA)
882 sleep(5);
883
884 /* If we skip this line it's because the type of screen we want
885 * is not connected. */
886 igt_require(enable_one_screen_with_type(&ms_data, type));
887 if (wait_flags & WAIT_STATUS)
888 igt_assert(wait_for_active());
889 if (wait_flags & WAIT_PC8_RES)
890 igt_assert(!pc8_plus_residency_changed(5));
891 if (wait_flags & WAIT_EXTRA)
892 sleep(5);
893 }
894 }
895
896 /* Test of the DRM resources reported by the IOCTLs are still the same. This
897 * ensures we still see the monitors with the same eyes. We get the EDIDs and
898 * compare them, which ensures we use DP AUX or GMBUS depending on what's
899 * connected. */
drm_resources_equal_subtest(void)900 static void drm_resources_equal_subtest(void)
901 {
902 struct compare_data pre_suspend, during_suspend, post_suspend;
903
904 enable_one_screen_and_wait(&ms_data);
905 get_drm_info(&pre_suspend);
906 igt_assert(wait_for_active());
907
908 disable_all_screens_and_wait(&ms_data);
909 get_drm_info(&during_suspend);
910 igt_assert(wait_for_suspended());
911
912 enable_one_screen_and_wait(&ms_data);
913 get_drm_info(&post_suspend);
914 igt_assert(wait_for_active());
915
916 assert_drm_infos_equal(&pre_suspend, &during_suspend);
917 assert_drm_infos_equal(&pre_suspend, &post_suspend);
918
919 free_drm_info(&pre_suspend);
920 free_drm_info(&during_suspend);
921 free_drm_info(&post_suspend);
922 }
923
i2c_subtest_check_environment(void)924 static void i2c_subtest_check_environment(void)
925 {
926 int i2c_dev_files = 0;
927 DIR *dev_dir;
928 struct dirent *dirent;
929
930 /* Make sure the /dev/i2c-* files exist. */
931 igt_require(modprobe("i2c-dev") == 0);
932
933 dev_dir = opendir("/dev");
934 igt_assert(dev_dir);
935 while ((dirent = readdir(dev_dir))) {
936 if (strncmp(dirent->d_name, "i2c-", 4) == 0)
937 i2c_dev_files++;
938 }
939 closedir(dev_dir);
940 igt_require(i2c_dev_files);
941 }
942
943 /* Try to use raw I2C, which also needs interrupts. */
i2c_subtest(void)944 static void i2c_subtest(void)
945 {
946 i2c_subtest_check_environment();
947
948 enable_one_screen_and_wait(&ms_data);
949
950 disable_all_screens_and_wait(&ms_data);
951 test_i2c(&ms_data);
952 igt_assert(wait_for_suspended());
953
954 enable_one_screen(&ms_data);
955 }
956
read_entry(const char * filepath,const struct stat * info,const int typeflag,struct FTW * pathinfo)957 static int read_entry(const char *filepath,
958 const struct stat *info,
959 const int typeflag,
960 struct FTW *pathinfo)
961 {
962 char buf[4096];
963 int fd;
964 int rc;
965
966 igt_assert_f(wait_for_suspended(), "Before opening: %s (%s)\n",
967 filepath + pathinfo->base, filepath);
968
969 fd = open(filepath, O_RDONLY | O_NONBLOCK);
970 if (fd < 0) {
971 igt_debug("Failed to open '%s': %m\n", filepath);
972 return 0;
973 }
974
975 do {
976 rc = read(fd, buf, sizeof(buf));
977 } while (rc == sizeof(buf));
978
979 close(fd);
980
981 igt_assert_f(wait_for_suspended(), "After closing: %s (%s)\n",
982 filepath + pathinfo->base, filepath);
983
984 return 0;
985 }
986
walk_fs(char * path)987 static void walk_fs(char *path)
988 {
989 disable_all_screens_and_wait(&ms_data);
990 nftw(path, read_entry, 20, FTW_PHYS | FTW_MOUNT);
991 }
992
993 /* This test will probably pass, with a small chance of hanging the machine in
994 * case of bugs. Many of the bugs exercised by this patch just result in dmesg
995 * errors, so a "pass" here should be confirmed by a check on dmesg. */
debugfs_read_subtest(void)996 static void debugfs_read_subtest(void)
997 {
998 char path[256];
999
1000 igt_require_f(igt_debugfs_path(drm_fd, path, sizeof(path)),
1001 "Can't find the debugfs directory\n");
1002 walk_fs(path);
1003 }
1004
1005 /* Read the comment on debugfs_read_subtest(). */
sysfs_read_subtest(void)1006 static void sysfs_read_subtest(void)
1007 {
1008 char path[80];
1009
1010 igt_require_f(igt_sysfs_path(drm_fd, path, sizeof(path)),
1011 "Can't find the sysfs directory\n");
1012 walk_fs(path);
1013 }
1014
1015 /* Make sure we don't suspend when we have the i915_forcewake_user file open. */
debugfs_forcewake_user_subtest(void)1016 static void debugfs_forcewake_user_subtest(void)
1017 {
1018 int fd, rc;
1019
1020 igt_require(intel_gen(ms_data.devid) >= 6);
1021
1022 disable_all_screens_and_wait(&ms_data);
1023
1024 fd = igt_open_forcewake_handle(drm_fd);
1025 igt_require(fd >= 0);
1026
1027 if (has_runtime_pm) {
1028 igt_assert(wait_for_active());
1029 sleep(10);
1030 igt_assert(wait_for_active());
1031 } else {
1032 igt_assert(wait_for_suspended());
1033 }
1034
1035 rc = close(fd);
1036 igt_assert_eq(rc, 0);
1037
1038 igt_assert(wait_for_suspended());
1039 }
1040
gem_mmap_subtest(bool gtt_mmap)1041 static void gem_mmap_subtest(bool gtt_mmap)
1042 {
1043 int i;
1044 uint32_t handle;
1045 int buf_size = 8192;
1046 uint8_t *gem_buf;
1047
1048 /* Create, map and set data while the device is active. */
1049 enable_one_screen_and_wait(&ms_data);
1050
1051 handle = gem_create(drm_fd, buf_size);
1052
1053 if (gtt_mmap) {
1054 gem_buf = gem_mmap__gtt(drm_fd, handle, buf_size,
1055 PROT_READ | PROT_WRITE);
1056 }
1057 else {
1058 gem_buf = gem_mmap__cpu(drm_fd, handle, 0, buf_size, 0);
1059 }
1060
1061
1062 for (i = 0; i < buf_size; i++)
1063 gem_buf[i] = i & 0xFF;
1064
1065 for (i = 0; i < buf_size; i++)
1066 igt_assert(gem_buf[i] == (i & 0xFF));
1067
1068 /* Now suspend, read and modify. */
1069 disable_all_screens_and_wait(&ms_data);
1070
1071 for (i = 0; i < buf_size; i++)
1072 igt_assert(gem_buf[i] == (i & 0xFF));
1073 igt_assert(wait_for_suspended());
1074
1075 for (i = 0; i < buf_size; i++)
1076 gem_buf[i] = (~i & 0xFF);
1077 igt_assert(wait_for_suspended());
1078
1079 /* Now resume and see if it's still there. */
1080 enable_one_screen_and_wait(&ms_data);
1081 for (i = 0; i < buf_size; i++)
1082 igt_assert(gem_buf[i] == (~i & 0xFF));
1083
1084 igt_assert(munmap(gem_buf, buf_size) == 0);
1085
1086 /* Now the opposite: suspend, and try to create the mmap while
1087 * suspended. */
1088 disable_all_screens_and_wait(&ms_data);
1089
1090 if (gtt_mmap) {
1091 gem_buf = gem_mmap__gtt(drm_fd, handle, buf_size,
1092 PROT_READ | PROT_WRITE);
1093 }
1094 else {
1095 gem_buf = gem_mmap__cpu(drm_fd, handle, 0, buf_size, 0);
1096 }
1097
1098 igt_assert(wait_for_suspended());
1099
1100 for (i = 0; i < buf_size; i++)
1101 gem_buf[i] = i & 0xFF;
1102
1103 for (i = 0; i < buf_size; i++)
1104 igt_assert(gem_buf[i] == (i & 0xFF));
1105
1106 igt_assert(wait_for_suspended());
1107
1108 /* Resume and check if it's still there. */
1109 enable_one_screen_and_wait(&ms_data);
1110 for (i = 0; i < buf_size; i++)
1111 igt_assert(gem_buf[i] == (i & 0xFF));
1112
1113 igt_assert(munmap(gem_buf, buf_size) == 0);
1114 gem_close(drm_fd, handle);
1115 }
1116
gem_pread_subtest(void)1117 static void gem_pread_subtest(void)
1118 {
1119 int i;
1120 uint32_t handle;
1121 int buf_size = 8192;
1122 uint8_t *cpu_buf, *read_buf;
1123
1124 cpu_buf = malloc(buf_size);
1125 read_buf = malloc(buf_size);
1126 igt_assert(cpu_buf);
1127 igt_assert(read_buf);
1128 memset(cpu_buf, 0, buf_size);
1129 memset(read_buf, 0, buf_size);
1130
1131 /* Create and set data while the device is active. */
1132 enable_one_screen_and_wait(&ms_data);
1133
1134 handle = gem_create(drm_fd, buf_size);
1135
1136 for (i = 0; i < buf_size; i++)
1137 cpu_buf[i] = i & 0xFF;
1138
1139 gem_write(drm_fd, handle, 0, cpu_buf, buf_size);
1140
1141 gem_read(drm_fd, handle, 0, read_buf, buf_size);
1142
1143 for (i = 0; i < buf_size; i++)
1144 igt_assert(cpu_buf[i] == read_buf[i]);
1145
1146 /* Now suspend, read and modify. */
1147 disable_all_screens_and_wait(&ms_data);
1148
1149 memset(read_buf, 0, buf_size);
1150 gem_read(drm_fd, handle, 0, read_buf, buf_size);
1151
1152 for (i = 0; i < buf_size; i++)
1153 igt_assert(cpu_buf[i] == read_buf[i]);
1154 igt_assert(wait_for_suspended());
1155
1156 for (i = 0; i < buf_size; i++)
1157 cpu_buf[i] = (~i & 0xFF);
1158 gem_write(drm_fd, handle, 0, cpu_buf, buf_size);
1159 igt_assert(wait_for_suspended());
1160
1161 /* Now resume and see if it's still there. */
1162 enable_one_screen_and_wait(&ms_data);
1163
1164 memset(read_buf, 0, buf_size);
1165 gem_read(drm_fd, handle, 0, read_buf, buf_size);
1166
1167 for (i = 0; i < buf_size; i++)
1168 igt_assert(cpu_buf[i] == read_buf[i]);
1169
1170 gem_close(drm_fd, handle);
1171
1172 free(cpu_buf);
1173 free(read_buf);
1174 }
1175
1176 /* Paints a square of color $color, size $width x $height, at position $x x $y
1177 * of $dst_handle, which contains pitch $pitch. */
submit_blt_cmd(uint32_t dst_handle,uint16_t x,uint16_t y,uint16_t width,uint16_t height,uint32_t pitch,uint32_t color,uint32_t * presumed_dst_offset)1178 static void submit_blt_cmd(uint32_t dst_handle, uint16_t x, uint16_t y,
1179 uint16_t width, uint16_t height, uint32_t pitch,
1180 uint32_t color, uint32_t *presumed_dst_offset)
1181 {
1182 int i, reloc_pos;
1183 uint32_t batch_handle;
1184 int batch_size = 8 * sizeof(uint32_t);
1185 uint32_t batch_buf[batch_size];
1186 struct drm_i915_gem_execbuffer2 execbuf = {};
1187 struct drm_i915_gem_exec_object2 objs[2] = {{}, {}};
1188 struct drm_i915_gem_relocation_entry relocs[1] = {{}};
1189 struct drm_i915_gem_wait gem_wait;
1190
1191 i = 0;
1192
1193 if (intel_gen(ms_data.devid) >= 8)
1194 batch_buf[i++] = XY_COLOR_BLT_CMD_NOLEN |
1195 XY_COLOR_BLT_WRITE_ALPHA |
1196 XY_COLOR_BLT_WRITE_RGB | 0x5;
1197 else
1198 batch_buf[i++] = XY_COLOR_BLT_CMD_NOLEN |
1199 XY_COLOR_BLT_WRITE_ALPHA |
1200 XY_COLOR_BLT_WRITE_RGB | 0x4;
1201 batch_buf[i++] = (3 << 24) | (0xF0 << 16) | (pitch);
1202 batch_buf[i++] = (y << 16) | x;
1203 batch_buf[i++] = ((y + height) << 16) | (x + width);
1204 reloc_pos = i;
1205 batch_buf[i++] = *presumed_dst_offset;
1206 if (intel_gen(ms_data.devid) >= 8)
1207 batch_buf[i++] = 0;
1208 batch_buf[i++] = color;
1209
1210 batch_buf[i++] = MI_BATCH_BUFFER_END;
1211 if (intel_gen(ms_data.devid) < 8)
1212 batch_buf[i++] = MI_NOOP;
1213
1214 igt_assert(i * sizeof(uint32_t) == batch_size);
1215
1216 batch_handle = gem_create(drm_fd, batch_size);
1217 gem_write(drm_fd, batch_handle, 0, batch_buf, batch_size);
1218
1219 relocs[0].target_handle = dst_handle;
1220 relocs[0].delta = 0;
1221 relocs[0].offset = reloc_pos * sizeof(uint32_t);
1222 relocs[0].presumed_offset = *presumed_dst_offset;
1223 relocs[0].read_domains = 0;
1224 relocs[0].write_domain = I915_GEM_DOMAIN_RENDER;
1225
1226 objs[0].handle = dst_handle;
1227 objs[0].alignment = 64;
1228
1229 objs[1].handle = batch_handle;
1230 objs[1].relocation_count = 1;
1231 objs[1].relocs_ptr = (uintptr_t)relocs;
1232
1233 execbuf.buffers_ptr = (uintptr_t)objs;
1234 execbuf.buffer_count = 2;
1235 execbuf.batch_len = batch_size;
1236 execbuf.flags = I915_EXEC_BLT;
1237 i915_execbuffer2_set_context_id(execbuf, 0);
1238
1239 gem_execbuf(drm_fd, &execbuf);
1240
1241 *presumed_dst_offset = relocs[0].presumed_offset;
1242
1243 gem_wait.flags = 0;
1244 gem_wait.timeout_ns = 10000000000LL; /* 10s */
1245
1246 gem_wait.bo_handle = batch_handle;
1247 do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_WAIT, &gem_wait);
1248
1249 gem_wait.bo_handle = dst_handle;
1250 do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_WAIT, &gem_wait);
1251
1252 gem_close(drm_fd, batch_handle);
1253 }
1254
1255 /* Make sure we can submit a batch buffer and verify its result. */
gem_execbuf_subtest(void)1256 static void gem_execbuf_subtest(void)
1257 {
1258 int x, y;
1259 uint32_t handle;
1260 int bpp = 4;
1261 int pitch = 128 * bpp;
1262 int dst_size = 128 * 128 * bpp; /* 128x128 square */
1263 uint32_t *cpu_buf;
1264 uint32_t presumed_offset = 0;
1265 int sq_x = 5, sq_y = 10, sq_w = 15, sq_h = 20;
1266 uint32_t color;
1267
1268 igt_require_gem(drm_fd);
1269
1270 /* Create and set data while the device is active. */
1271 enable_one_screen_and_wait(&ms_data);
1272
1273 handle = gem_create(drm_fd, dst_size);
1274
1275 cpu_buf = malloc(dst_size);
1276 igt_assert(cpu_buf);
1277 memset(cpu_buf, 0, dst_size);
1278 gem_write(drm_fd, handle, 0, cpu_buf, dst_size);
1279
1280 /* Now suspend and try it. */
1281 disable_all_screens_and_wait(&ms_data);
1282
1283 color = 0x12345678;
1284 submit_blt_cmd(handle, sq_x, sq_y, sq_w, sq_h, pitch, color,
1285 &presumed_offset);
1286 igt_assert(wait_for_suspended());
1287
1288 gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1289 igt_assert(wait_for_suspended());
1290 for (y = 0; y < 128; y++) {
1291 for (x = 0; x < 128; x++) {
1292 uint32_t px = cpu_buf[y * 128 + x];
1293
1294 if (y >= sq_y && y < (sq_y + sq_h) &&
1295 x >= sq_x && x < (sq_x + sq_w))
1296 igt_assert_eq_u32(px, color);
1297 else
1298 igt_assert(px == 0);
1299 }
1300 }
1301
1302 /* Now resume and check for it again. */
1303 enable_one_screen_and_wait(&ms_data);
1304
1305 memset(cpu_buf, 0, dst_size);
1306 gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1307 for (y = 0; y < 128; y++) {
1308 for (x = 0; x < 128; x++) {
1309 uint32_t px = cpu_buf[y * 128 + x];
1310
1311 if (y >= sq_y && y < (sq_y + sq_h) &&
1312 x >= sq_x && x < (sq_x + sq_w))
1313 igt_assert_eq_u32(px, color);
1314 else
1315 igt_assert(px == 0);
1316 }
1317 }
1318
1319 /* Now we'll do the opposite: do the blt while active, then read while
1320 * suspended. We use the same spot, but a different color. As a bonus,
1321 * we're testing the presumed_offset from the previous command. */
1322 color = 0x87654321;
1323 submit_blt_cmd(handle, sq_x, sq_y, sq_w, sq_h, pitch, color,
1324 &presumed_offset);
1325
1326 disable_all_screens_and_wait(&ms_data);
1327
1328 memset(cpu_buf, 0, dst_size);
1329 gem_read(drm_fd, handle, 0, cpu_buf, dst_size);
1330 for (y = 0; y < 128; y++) {
1331 for (x = 0; x < 128; x++) {
1332 uint32_t px = cpu_buf[y * 128 + x];
1333
1334 if (y >= sq_y && y < (sq_y + sq_h) &&
1335 x >= sq_x && x < (sq_x + sq_w))
1336 igt_assert_eq_u32(px, color);
1337 else
1338 igt_assert(px == 0);
1339 }
1340 }
1341
1342 gem_close(drm_fd, handle);
1343
1344 free(cpu_buf);
1345 }
1346
1347 /* Assuming execbuf already works, let's see what happens when we force many
1348 * suspend/resume cycles with commands. */
gem_execbuf_stress_subtest(int rounds,int wait_flags)1349 static void gem_execbuf_stress_subtest(int rounds, int wait_flags)
1350 {
1351 int i;
1352 int batch_size = 4 * sizeof(uint32_t);
1353 uint32_t batch_buf[batch_size];
1354 uint32_t handle;
1355 struct drm_i915_gem_execbuffer2 execbuf = {};
1356 struct drm_i915_gem_exec_object2 objs[1] = {{}};
1357
1358 igt_require_gem(drm_fd);
1359
1360 if (wait_flags & WAIT_PC8_RES)
1361 igt_require(has_pc8);
1362
1363 i = 0;
1364 batch_buf[i++] = MI_NOOP;
1365 batch_buf[i++] = MI_NOOP;
1366 batch_buf[i++] = MI_BATCH_BUFFER_END;
1367 batch_buf[i++] = MI_NOOP;
1368 igt_assert(i * sizeof(uint32_t) == batch_size);
1369
1370 disable_all_screens_and_wait(&ms_data);
1371
1372 handle = gem_create(drm_fd, batch_size);
1373 gem_write(drm_fd, handle, 0, batch_buf, batch_size);
1374
1375 objs[0].handle = handle;
1376
1377 execbuf.buffers_ptr = (uintptr_t)objs;
1378 execbuf.buffer_count = 1;
1379 execbuf.batch_len = batch_size;
1380 execbuf.flags = I915_EXEC_RENDER;
1381 i915_execbuffer2_set_context_id(execbuf, 0);
1382
1383 for (i = 0; i < rounds; i++) {
1384 gem_execbuf(drm_fd, &execbuf);
1385
1386 if (wait_flags & WAIT_STATUS) {
1387 /* clean up idle work */
1388 igt_drop_caches_set(drm_fd, DROP_IDLE);
1389 igt_assert(wait_for_suspended());
1390 }
1391 if (wait_flags & WAIT_PC8_RES)
1392 igt_assert(pc8_plus_residency_changed(30));
1393 if (wait_flags & WAIT_EXTRA)
1394 sleep(5);
1395 }
1396
1397 gem_close(drm_fd, handle);
1398 }
1399
1400 /* When this test was written, it triggered WARNs and DRM_ERRORs on dmesg. */
gem_idle_subtest(void)1401 static void gem_idle_subtest(void)
1402 {
1403 disable_all_screens_and_wait(&ms_data);
1404
1405 sleep(5);
1406
1407 gem_test_engine(drm_fd, -1);
1408 }
1409
gem_evict_pwrite_subtest(void)1410 static void gem_evict_pwrite_subtest(void)
1411 {
1412 struct {
1413 uint32_t handle;
1414 uint32_t *ptr;
1415 } *trash_bos;
1416 unsigned int num_trash_bos, n;
1417 uint32_t buf;
1418
1419 num_trash_bos = gem_mappable_aperture_size() / (1024*1024) + 1;
1420 trash_bos = malloc(num_trash_bos * sizeof(*trash_bos));
1421 igt_assert(trash_bos);
1422
1423 for (n = 0; n < num_trash_bos; n++) {
1424 trash_bos[n].handle = gem_create(drm_fd, 1024*1024);
1425 trash_bos[n].ptr = gem_mmap__gtt(drm_fd, trash_bos[n].handle,
1426 1024*1024, PROT_WRITE);
1427 *trash_bos[n].ptr = 0;
1428 }
1429
1430 disable_or_dpms_all_screens_and_wait(&ms_data, true);
1431 igt_assert(wait_for_suspended());
1432
1433 buf = 0;
1434 for (n = 0; n < num_trash_bos; n++)
1435 gem_write(drm_fd, trash_bos[n].handle, 0, &buf, sizeof(buf));
1436
1437 for (n = 0; n < num_trash_bos; n++) {
1438 munmap(trash_bos[n].ptr, 1024*1024);
1439 gem_close(drm_fd, trash_bos[n].handle);
1440 }
1441 free(trash_bos);
1442 }
1443
1444 /* This also triggered WARNs on dmesg at some point. */
reg_read_ioctl_subtest(void)1445 static void reg_read_ioctl_subtest(void)
1446 {
1447 struct drm_i915_reg_read rr = {
1448 .offset = 0x2358, /* render ring timestamp */
1449 };
1450
1451 disable_all_screens_and_wait(&ms_data);
1452
1453 do_ioctl(drm_fd, DRM_IOCTL_I915_REG_READ, &rr);
1454
1455 igt_assert(wait_for_suspended());
1456 }
1457
device_in_pci_d3(void)1458 static bool device_in_pci_d3(void)
1459 {
1460 uint16_t val;
1461 int rc;
1462
1463 rc = pci_device_cfg_read_u16(intel_get_pci_device(), &val, 0xd4);
1464 igt_assert_eq(rc, 0);
1465
1466 igt_debug("%s: PCI D3 state=%d\n", __func__, val & 0x3);
1467 return (val & 0x3) == 0x3;
1468 }
1469
pci_d3_state_subtest(void)1470 static void pci_d3_state_subtest(void)
1471 {
1472 igt_require(has_runtime_pm);
1473
1474 disable_all_screens_and_wait(&ms_data);
1475 igt_assert(igt_wait(device_in_pci_d3(), 2000, 100));
1476
1477 if (ms_data.res) {
1478 enable_one_screen_and_wait(&ms_data);
1479 igt_assert(!device_in_pci_d3());
1480 }
1481 }
1482
stay_subtest(void)1483 static void __attribute__((noreturn)) stay_subtest(void)
1484 {
1485 disable_all_screens_and_wait(&ms_data);
1486
1487 while (1)
1488 sleep(600);
1489 }
1490
system_suspend_subtest(int state,int debug)1491 static void system_suspend_subtest(int state, int debug)
1492 {
1493 disable_all_screens_and_wait(&ms_data);
1494
1495 igt_system_suspend_autoresume(state, debug);
1496 igt_assert(wait_for_suspended());
1497 }
1498
system_suspend_execbuf_subtest(void)1499 static void system_suspend_execbuf_subtest(void)
1500 {
1501 int i;
1502 int batch_size = 4 * sizeof(uint32_t);
1503 uint32_t batch_buf[batch_size];
1504 uint32_t handle;
1505 struct drm_i915_gem_execbuffer2 execbuf = {};
1506 struct drm_i915_gem_exec_object2 objs[1] = {{}};
1507
1508 i = 0;
1509 batch_buf[i++] = MI_NOOP;
1510 batch_buf[i++] = MI_NOOP;
1511 batch_buf[i++] = MI_BATCH_BUFFER_END;
1512 batch_buf[i++] = MI_NOOP;
1513 igt_assert(i * sizeof(uint32_t) == batch_size);
1514
1515 handle = gem_create(drm_fd, batch_size);
1516 gem_write(drm_fd, handle, 0, batch_buf, batch_size);
1517
1518 objs[0].handle = handle;
1519
1520 execbuf.buffers_ptr = (uintptr_t)objs;
1521 execbuf.buffer_count = 1;
1522 execbuf.batch_len = batch_size;
1523 execbuf.flags = I915_EXEC_RENDER;
1524 i915_execbuffer2_set_context_id(execbuf, 0);
1525
1526 disable_all_screens_and_wait(&ms_data);
1527 igt_system_suspend_autoresume(SUSPEND_STATE_MEM, SUSPEND_TEST_NONE);
1528 igt_assert(wait_for_suspended());
1529
1530 for (i = 0; i < 20; i++) {
1531 gem_execbuf(drm_fd, &execbuf);
1532 igt_assert(wait_for_suspended());
1533 }
1534
1535 gem_close(drm_fd, handle);
1536 }
1537
system_suspend_modeset_subtest(void)1538 static void system_suspend_modeset_subtest(void)
1539 {
1540 disable_all_screens_and_wait(&ms_data);
1541 igt_system_suspend_autoresume(SUSPEND_STATE_MEM, SUSPEND_TEST_NONE);
1542 igt_assert(wait_for_suspended());
1543
1544 enable_one_screen_and_wait(&ms_data);
1545 disable_all_screens_and_wait(&ms_data);
1546 }
1547
1548 /* Enable a screen, activate DPMS, then do a modeset. At some point our driver
1549 * produced WARNs on this case. */
dpms_mode_unset_subtest(enum screen_type type)1550 static void dpms_mode_unset_subtest(enum screen_type type)
1551 {
1552 disable_all_screens_and_wait(&ms_data);
1553
1554 igt_require(enable_one_screen_with_type(&ms_data, type));
1555 igt_assert(wait_for_active());
1556
1557 disable_all_screens_dpms(&ms_data);
1558 igt_assert(wait_for_suspended());
1559
1560 disable_all_screens_and_wait(&ms_data);
1561 }
1562
fill_igt_fb(struct igt_fb * fb,uint32_t color)1563 static void fill_igt_fb(struct igt_fb *fb, uint32_t color)
1564 {
1565 int i;
1566 uint32_t *ptr;
1567
1568 ptr = gem_mmap__gtt(drm_fd, fb->gem_handle, fb->size, PROT_WRITE);
1569 for (i = 0; i < fb->size/sizeof(uint32_t); i++)
1570 ptr[i] = color;
1571 igt_assert(munmap(ptr, fb->size) == 0);
1572 }
1573
1574 /* At some point, this test triggered WARNs in the Kernel. */
cursor_subtest(bool dpms)1575 static void cursor_subtest(bool dpms)
1576 {
1577 int rc;
1578 struct igt_fb cursor_fb1, cursor_fb2, cursor_fb3;
1579 uint32_t crtc_id;
1580
1581 disable_all_screens_and_wait(&ms_data);
1582
1583 igt_require(default_mode_params);
1584 crtc_id = default_mode_params->crtc_id;
1585
1586 igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_ARGB8888,
1587 LOCAL_DRM_FORMAT_MOD_NONE, &cursor_fb1);
1588 igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_ARGB8888,
1589 LOCAL_DRM_FORMAT_MOD_NONE, &cursor_fb2);
1590 igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_XRGB8888,
1591 LOCAL_I915_FORMAT_MOD_X_TILED, &cursor_fb3);
1592
1593 fill_igt_fb(&cursor_fb1, 0xFF00FFFF);
1594 fill_igt_fb(&cursor_fb2, 0xFF00FF00);
1595 fill_igt_fb(&cursor_fb3, 0xFFFF0000);
1596
1597 set_mode_for_params_and_wait(default_mode_params);
1598
1599 rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb1.gem_handle,
1600 cursor_fb1.width, cursor_fb1.height);
1601 igt_assert_eq(rc, 0);
1602 rc = drmModeMoveCursor(drm_fd, crtc_id, 0, 0);
1603 igt_assert_eq(rc, 0);
1604 igt_assert(wait_for_active());
1605
1606 disable_or_dpms_all_screens_and_wait(&ms_data, dpms);
1607
1608 /* First, just move the cursor. */
1609 rc = drmModeMoveCursor(drm_fd, crtc_id, 1, 1);
1610 igt_assert_eq(rc, 0);
1611 igt_assert(wait_for_suspended());
1612
1613 /* Then unset it, and set a new one. */
1614 rc = drmModeSetCursor(drm_fd, crtc_id, 0, 0, 0);
1615 igt_assert_eq(rc, 0);
1616 igt_assert(wait_for_suspended());
1617
1618 rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb2.gem_handle,
1619 cursor_fb1.width, cursor_fb2.height);
1620 igt_assert_eq(rc, 0);
1621 igt_assert(wait_for_suspended());
1622
1623 /* Move the new cursor. */
1624 rc = drmModeMoveCursor(drm_fd, crtc_id, 2, 2);
1625 igt_assert_eq(rc, 0);
1626 igt_assert(wait_for_suspended());
1627
1628 /* Now set a new one without unsetting the previous one. */
1629 rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb1.gem_handle,
1630 cursor_fb1.width, cursor_fb1.height);
1631 igt_assert_eq(rc, 0);
1632 igt_assert(wait_for_suspended());
1633
1634 /* Cursor 3 was created with tiling and painted with a GTT mmap, so
1635 * hopefully it has some fences around it. */
1636 rc = drmModeRmFB(drm_fd, cursor_fb3.fb_id);
1637 igt_assert_eq(rc, 0);
1638 gem_set_tiling(drm_fd, cursor_fb3.gem_handle, false, cursor_fb3.strides[0]);
1639 igt_assert(wait_for_suspended());
1640
1641 rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb3.gem_handle,
1642 cursor_fb3.width, cursor_fb3.height);
1643 igt_assert_eq(rc, 0);
1644 igt_assert(wait_for_suspended());
1645
1646 /* Make sure nothing remains for the other tests. */
1647 rc = drmModeSetCursor(drm_fd, crtc_id, 0, 0, 0);
1648 igt_assert_eq(rc, 0);
1649 igt_assert(wait_for_suspended());
1650 }
1651
get_plane_type(uint32_t plane_id)1652 static enum plane_type get_plane_type(uint32_t plane_id)
1653 {
1654 int i;
1655 bool found;
1656 uint64_t prop_value;
1657 drmModePropertyPtr prop;
1658 const char *enum_name = NULL;
1659 enum plane_type type;
1660
1661 found = kmstest_get_property(drm_fd, plane_id, DRM_MODE_OBJECT_PLANE,
1662 "type", NULL, &prop_value, &prop);
1663 igt_assert(found);
1664
1665 igt_assert(prop->flags & DRM_MODE_PROP_ENUM);
1666 igt_assert(prop_value < prop->count_enums);
1667
1668 for (i = 0; i < prop->count_enums; i++) {
1669 if (prop->enums[i].value == prop_value) {
1670 enum_name = prop->enums[i].name;
1671 break;
1672 }
1673 }
1674 igt_assert(enum_name);
1675
1676 if (strcmp(enum_name, "Overlay") == 0)
1677 type = PLANE_OVERLAY;
1678 else if (strcmp(enum_name, "Primary") == 0)
1679 type = PLANE_PRIMARY;
1680 else if (strcmp(enum_name, "Cursor") == 0)
1681 type = PLANE_CURSOR;
1682 else
1683 igt_assert(0);
1684
1685 drmModeFreeProperty(prop);
1686
1687 return type;
1688 }
1689
test_one_plane(bool dpms,uint32_t plane_id,enum plane_type plane_type)1690 static void test_one_plane(bool dpms, uint32_t plane_id,
1691 enum plane_type plane_type)
1692 {
1693 int rc;
1694 uint32_t plane_format, plane_w, plane_h;
1695 uint32_t crtc_id;
1696 struct igt_fb plane_fb1, plane_fb2;
1697 int32_t crtc_x = 0, crtc_y = 0;
1698 uint64_t tiling;
1699
1700 disable_all_screens_and_wait(&ms_data);
1701
1702 crtc_id = default_mode_params->crtc_id;
1703
1704 switch (plane_type) {
1705 case PLANE_OVERLAY:
1706 plane_format = DRM_FORMAT_XRGB8888;
1707 plane_w = 64;
1708 plane_h = 64;
1709 tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
1710 break;
1711 case PLANE_PRIMARY:
1712 plane_format = DRM_FORMAT_XRGB8888;
1713 plane_w = default_mode_params->mode->hdisplay;
1714 plane_h = default_mode_params->mode->vdisplay;
1715 tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
1716 break;
1717 case PLANE_CURSOR:
1718 plane_format = DRM_FORMAT_ARGB8888;
1719 plane_w = 64;
1720 plane_h = 64;
1721 tiling = LOCAL_DRM_FORMAT_MOD_NONE;
1722 break;
1723 default:
1724 igt_assert(0);
1725 break;
1726 }
1727
1728 igt_create_fb(drm_fd, plane_w, plane_h, plane_format, tiling,
1729 &plane_fb1);
1730 igt_create_fb(drm_fd, plane_w, plane_h, plane_format, tiling,
1731 &plane_fb2);
1732 fill_igt_fb(&plane_fb1, 0xFF00FFFF);
1733 fill_igt_fb(&plane_fb2, 0xFF00FF00);
1734
1735 set_mode_for_params_and_wait(default_mode_params);
1736
1737 rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0,
1738 0, 0, plane_fb1.width, plane_fb1.height,
1739 0 << 16, 0 << 16, plane_fb1.width << 16,
1740 plane_fb1.height << 16);
1741 igt_assert_eq(rc, 0);
1742
1743 disable_or_dpms_all_screens_and_wait(&ms_data, dpms);
1744
1745 /* Just move the plane around. */
1746 if (plane_type != PLANE_PRIMARY) {
1747 crtc_x++;
1748 crtc_y++;
1749 }
1750 rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0,
1751 crtc_x, crtc_y, plane_fb1.width, plane_fb1.height,
1752 0 << 16, 0 << 16, plane_fb1.width << 16,
1753 plane_fb1.height << 16);
1754 igt_assert_eq(rc, 0);
1755 igt_assert(wait_for_suspended());
1756
1757 /* Unset, then change the plane. */
1758 rc = drmModeSetPlane(drm_fd, plane_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1759 igt_assert_eq(rc, 0);
1760 igt_assert(wait_for_suspended());
1761
1762 rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb2.fb_id, 0,
1763 crtc_x, crtc_y, plane_fb2.width, plane_fb2.height,
1764 0 << 16, 0 << 16, plane_fb2.width << 16,
1765 plane_fb2.height << 16);
1766 igt_assert_eq(rc, 0);
1767 igt_assert(wait_for_suspended());
1768
1769 /* Now change the plane without unsetting first. */
1770 rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0,
1771 crtc_x, crtc_y, plane_fb1.width, plane_fb1.height,
1772 0 << 16, 0 << 16, plane_fb1.width << 16,
1773 plane_fb1.height << 16);
1774 igt_assert_eq(rc, 0);
1775 igt_assert(wait_for_suspended());
1776
1777 /* Make sure nothing remains for the other tests. */
1778 rc = drmModeSetPlane(drm_fd, plane_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1779 igt_assert_eq(rc, 0);
1780 igt_assert(wait_for_suspended());
1781 }
1782
1783 /* This one also triggered WARNs on our driver at some point in time. */
planes_subtest(bool universal,bool dpms)1784 static void planes_subtest(bool universal, bool dpms)
1785 {
1786 int i, rc, planes_tested = 0, crtc_idx;
1787 drmModePlaneResPtr planes;
1788
1789 igt_require(default_mode_params);
1790 crtc_idx = kmstest_get_crtc_idx(ms_data.res,
1791 default_mode_params->crtc_id);
1792
1793 if (universal) {
1794 rc = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES,
1795 1);
1796 igt_require(rc == 0);
1797 }
1798
1799 planes = drmModeGetPlaneResources(drm_fd);
1800 for (i = 0; i < planes->count_planes; i++) {
1801 drmModePlanePtr plane;
1802
1803 plane = drmModeGetPlane(drm_fd, planes->planes[i]);
1804 igt_assert(plane);
1805
1806 if (plane->possible_crtcs & (1 << crtc_idx)) {
1807 enum plane_type type;
1808
1809 type = universal ? get_plane_type(plane->plane_id) :
1810 PLANE_OVERLAY;
1811 test_one_plane(dpms, plane->plane_id, type);
1812 planes_tested++;
1813 }
1814 drmModeFreePlane(plane);
1815 }
1816 drmModeFreePlaneResources(planes);
1817
1818 if (universal) {
1819 rc = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0);
1820 igt_assert_eq(rc, 0);
1821
1822 igt_assert_lte(3, planes_tested);
1823 } else {
1824 igt_assert_lte(1, planes_tested);
1825 }
1826 }
1827
pm_test_tiling(void)1828 static void pm_test_tiling(void)
1829 {
1830 uint32_t *handles;
1831 uint8_t **gem_bufs;
1832
1833 int max_gem_objs = 0;
1834 uint8_t off_bit = 14;
1835 uint32_t gtt_obj_max_size = (256 * 1024);
1836
1837 uint32_t i, j, k, tiling_modes[3] = {
1838 I915_TILING_NONE,
1839 I915_TILING_X,
1840 I915_TILING_Y,
1841 };
1842 uint32_t ti, sw;
1843
1844 /* default stride value */
1845 uint32_t stride = 512;
1846
1847 /* calculate how many objects we can map */
1848 for (i = 1 << off_bit; i <= gtt_obj_max_size; i <<= 1, max_gem_objs++)
1849 ;
1850
1851 gem_bufs = calloc(max_gem_objs, sizeof(*gem_bufs));
1852 handles = calloc(max_gem_objs, sizeof(*handles));
1853
1854 /* try to set different tiling for each handle */
1855 for (i = 0; i < ARRAY_SIZE(tiling_modes); i++) {
1856
1857 for (j = 0, k = 1 << off_bit;
1858 k <= gtt_obj_max_size; k <<= 1, j++) {
1859 handles[j] = gem_create(drm_fd, k);
1860 gem_bufs[j] = gem_mmap__gtt(drm_fd, handles[j],
1861 k, PROT_WRITE);
1862 memset(gem_bufs[j], 0x0, k);
1863 }
1864
1865 disable_all_screens_and_wait(&ms_data);
1866
1867 for (j = 0; j < max_gem_objs; j++) {
1868 gem_set_tiling(drm_fd, handles[j],
1869 tiling_modes[i], stride);
1870 gem_get_tiling(drm_fd, handles[j], &ti, &sw);
1871 igt_assert(tiling_modes[i] == ti);
1872 }
1873
1874 enable_one_screen_and_wait(&ms_data);
1875
1876 for (j = 0, k = 1 << off_bit;
1877 k <= gtt_obj_max_size; k <<= 1, j++) {
1878 igt_assert(munmap(gem_bufs[j], k) == 0);
1879 gem_close(drm_fd, handles[j]);
1880 }
1881 }
1882
1883 free(gem_bufs);
1884 free(handles);
1885 }
1886
pm_test_caching(void)1887 static void pm_test_caching(void)
1888 {
1889 uint32_t handle;
1890 uint8_t *gem_buf;
1891
1892 uint32_t i;
1893 uint32_t default_cache_level;
1894 uint32_t gtt_obj_max_size = (16 * 1024);
1895 uint32_t cache_levels[3] = {
1896 I915_CACHING_NONE,
1897 I915_CACHING_CACHED, /* LLC caching */
1898 I915_CACHING_DISPLAY, /* eDRAM caching */
1899 };
1900
1901 disable_all_screens(&ms_data);
1902
1903 handle = gem_create(drm_fd, gtt_obj_max_size);
1904 default_cache_level = gem_get_caching(drm_fd, handle);
1905 gem_buf = gem_mmap__gtt(drm_fd, handle, gtt_obj_max_size, PROT_WRITE);
1906
1907 for (i = 0; i < ARRAY_SIZE(cache_levels); i++) {
1908 igt_assert(wait_for_suspended());
1909 gem_set_caching(drm_fd, handle, default_cache_level);
1910
1911 /* Ensure we bind the vma into the GGTT */
1912 memset(gem_buf, 16 << i, gtt_obj_max_size);
1913
1914 /* Now try changing the cache-level on the bound object.
1915 * This will either unlikely unbind the object from the GGTT,
1916 * or more likely just change the PTEs inside the GGTT. Either
1917 * way the driver must take the rpm wakelock around the GSM
1918 * access.
1919 */
1920 igt_debug("Setting cache level %u\n", cache_levels[i]);
1921 igt_assert(wait_for_suspended());
1922 gem_set_caching(drm_fd, handle, cache_levels[i]);
1923 }
1924
1925 igt_assert(munmap(gem_buf, gtt_obj_max_size) == 0);
1926 gem_close(drm_fd, handle);
1927 }
1928
fences_subtest(bool dpms)1929 static void fences_subtest(bool dpms)
1930 {
1931 int i;
1932 uint32_t *buf_ptr;
1933 uint32_t tiling = false, swizzle;
1934 struct modeset_params params;
1935
1936 disable_all_screens_and_wait(&ms_data);
1937
1938 igt_require(default_mode_params);
1939 params.crtc_id = default_mode_params->crtc_id;
1940 params.connector_id = default_mode_params->connector_id;
1941 params.mode = default_mode_params->mode;
1942 igt_create_fb(drm_fd, params.mode->hdisplay, params.mode->vdisplay,
1943 DRM_FORMAT_XRGB8888, LOCAL_I915_FORMAT_MOD_X_TILED,
1944 ¶ms.fb);
1945
1946 /* Even though we passed "true" as the tiling argument, double-check
1947 * that the fb is really tiled. */
1948 gem_get_tiling(drm_fd, params.fb.gem_handle, &tiling, &swizzle);
1949 igt_assert(tiling);
1950
1951 buf_ptr = gem_mmap__gtt(drm_fd, params.fb.gem_handle, params.fb.size,
1952 PROT_WRITE | PROT_READ);
1953 for (i = 0; i < params.fb.size/sizeof(uint32_t); i++)
1954 buf_ptr[i] = i;
1955
1956 set_mode_for_params_and_wait(¶ms);
1957
1958 disable_or_dpms_all_screens_and_wait(&ms_data, dpms);
1959
1960 for (i = 0; i < params.fb.size/sizeof(uint32_t); i++)
1961 igt_assert_eq(buf_ptr[i], i);
1962 igt_assert(wait_for_suspended());
1963
1964 if (dpms) {
1965 drmModeConnectorPtr c = NULL;
1966
1967 for (i = 0; i < ms_data.res->count_connectors; i++)
1968 if (ms_data.connectors[i]->connector_id ==
1969 params.connector_id)
1970 c = ms_data.connectors[i];
1971 igt_assert(c);
1972
1973 kmstest_set_connector_dpms(drm_fd, c, DRM_MODE_DPMS_ON);
1974 } else {
1975 set_mode_for_params(¶ms);
1976 }
1977 igt_assert(wait_for_active());
1978
1979 for (i = 0; i < params.fb.size/sizeof(uint32_t); i++)
1980 igt_assert_eq(buf_ptr[i], i);
1981
1982 igt_assert(munmap(buf_ptr, params.fb.size) == 0);
1983 }
1984
1985 int rounds = 10;
1986 bool stay = false;
1987
opt_handler(int opt,int opt_index,void * data)1988 static int opt_handler(int opt, int opt_index, void *data)
1989 {
1990 switch (opt) {
1991 case 'l':
1992 rounds = 50;
1993 break;
1994 case 's':
1995 stay = true;
1996 break;
1997 default:
1998 return IGT_OPT_HANDLER_ERROR;
1999 }
2000
2001 return IGT_OPT_HANDLER_SUCCESS;
2002 }
2003
2004 const char *help_str =
2005 " --stress\t\tMake the stress-tests more stressful.\n"
2006 " --stay\t\tDisable all screen and try to go into runtime pm. Useful for debugging.";
2007 static struct option long_options[] = {
2008 {"stress", 0, 0, 'l'},
2009 {"stay", 0, 0, 's'},
2010 { 0, 0, 0, 0 }
2011 };
2012
2013 igt_main_args("", long_options, help_str, opt_handler, NULL)
2014 {
2015 igt_subtest("basic-rte") {
2016 igt_assert(setup_environment());
2017 basic_subtest();
2018 }
2019
2020 /* Skip instead of failing in case the machine is not prepared to reach
2021 * PC8+. We don't want bug reports from cases where the machine is just
2022 * not properly configured. */
2023 igt_fixture
2024 igt_require(setup_environment());
2025
2026 if (stay)
2027 igt_subtest("stay")
2028 stay_subtest();
2029
2030 /* Essential things */
2031 igt_subtest("drm-resources-equal")
2032 drm_resources_equal_subtest();
2033 igt_subtest("basic-pci-d3-state")
2034 pci_d3_state_subtest();
2035
2036 /* Basic modeset */
2037 igt_subtest("modeset-lpsp")
2038 modeset_subtest(SCREEN_TYPE_LPSP, 1, WAIT_STATUS);
2039 igt_subtest("modeset-non-lpsp")
2040 modeset_subtest(SCREEN_TYPE_NON_LPSP, 1, WAIT_STATUS);
2041 igt_subtest("dpms-lpsp")
2042 modeset_subtest(SCREEN_TYPE_LPSP, 1, WAIT_STATUS | USE_DPMS);
2043 igt_subtest("dpms-non-lpsp")
2044 modeset_subtest(SCREEN_TYPE_NON_LPSP, 1, WAIT_STATUS | USE_DPMS);
2045
2046 /* GEM */
2047 igt_subtest("gem-mmap-cpu")
2048 gem_mmap_subtest(false);
2049 igt_subtest("gem-mmap-gtt")
2050 gem_mmap_subtest(true);
2051 igt_subtest("gem-pread")
2052 gem_pread_subtest();
2053 igt_subtest("gem-execbuf")
2054 gem_execbuf_subtest();
2055 igt_subtest("gem-idle")
2056 gem_idle_subtest();
2057 igt_subtest("gem-evict-pwrite")
2058 gem_evict_pwrite_subtest();
2059
2060 /* Planes and cursors */
2061 igt_subtest("cursor")
2062 cursor_subtest(false);
2063 igt_subtest("cursor-dpms")
2064 cursor_subtest(true);
2065 igt_subtest("legacy-planes")
2066 planes_subtest(false, false);
2067 igt_subtest("legacy-planes-dpms")
2068 planes_subtest(false, true);
2069 igt_subtest("universal-planes")
2070 planes_subtest(true, false);
2071 igt_subtest("universal-planes-dpms")
2072 planes_subtest(true, true);
2073
2074 /* Misc */
2075 igt_subtest("reg-read-ioctl")
2076 reg_read_ioctl_subtest();
2077 igt_subtest("i2c")
2078 i2c_subtest();
2079 igt_subtest("pc8-residency")
2080 pc8_residency_subtest();
2081 igt_subtest("debugfs-read")
2082 debugfs_read_subtest();
2083 igt_subtest("debugfs-forcewake-user")
2084 debugfs_forcewake_user_subtest();
2085 igt_subtest("sysfs-read")
2086 sysfs_read_subtest();
2087 igt_subtest("dpms-mode-unset-lpsp")
2088 dpms_mode_unset_subtest(SCREEN_TYPE_LPSP);
2089 igt_subtest("dpms-mode-unset-non-lpsp")
2090 dpms_mode_unset_subtest(SCREEN_TYPE_NON_LPSP);
2091 igt_subtest("fences")
2092 fences_subtest(false);
2093 igt_subtest("fences-dpms")
2094 fences_subtest(true);
2095
2096 /* Modeset stress */
2097 igt_subtest("modeset-lpsp-stress")
2098 modeset_subtest(SCREEN_TYPE_LPSP, rounds, WAIT_STATUS);
2099 igt_subtest("modeset-non-lpsp-stress")
2100 modeset_subtest(SCREEN_TYPE_NON_LPSP, rounds, WAIT_STATUS);
2101 igt_subtest("modeset-lpsp-stress-no-wait")
2102 modeset_subtest(SCREEN_TYPE_LPSP, rounds, DONT_WAIT);
2103 igt_subtest("modeset-non-lpsp-stress-no-wait")
2104 modeset_subtest(SCREEN_TYPE_NON_LPSP, rounds, DONT_WAIT);
2105 igt_subtest("modeset-pc8-residency-stress")
2106 modeset_subtest(SCREEN_TYPE_ANY, rounds, WAIT_PC8_RES);
2107 igt_subtest("modeset-stress-extra-wait")
2108 modeset_subtest(SCREEN_TYPE_ANY, rounds,
2109 WAIT_STATUS | WAIT_EXTRA);
2110
2111 /* System suspend */
2112 igt_subtest("system-suspend-devices")
2113 system_suspend_subtest(SUSPEND_STATE_MEM, SUSPEND_TEST_DEVICES);
2114 igt_subtest("system-suspend")
2115 system_suspend_subtest(SUSPEND_STATE_MEM, SUSPEND_TEST_NONE);
2116 igt_subtest("system-suspend-execbuf")
2117 system_suspend_execbuf_subtest();
2118 igt_subtest("system-suspend-modeset")
2119 system_suspend_modeset_subtest();
2120 igt_subtest("system-hibernate-devices")
2121 system_suspend_subtest(SUSPEND_STATE_DISK,
2122 SUSPEND_TEST_DEVICES);
2123 igt_subtest("system-hibernate")
2124 system_suspend_subtest(SUSPEND_STATE_DISK, SUSPEND_TEST_NONE);
2125
2126 /* GEM stress */
2127 igt_subtest("gem-execbuf-stress")
2128 gem_execbuf_stress_subtest(rounds, WAIT_STATUS);
2129 igt_subtest("gem-execbuf-stress-pc8")
2130 gem_execbuf_stress_subtest(rounds, WAIT_PC8_RES);
2131 igt_subtest("gem-execbuf-stress-extra-wait")
2132 gem_execbuf_stress_subtest(rounds, WAIT_STATUS | WAIT_EXTRA);
2133
2134 /* power-wake reference tests */
2135 igt_subtest("pm-tiling")
2136 pm_test_tiling();
2137 igt_subtest("pm-caching")
2138 pm_test_caching();
2139
2140 igt_fixture
2141 teardown_environment();
2142
2143 igt_subtest("module-reload") {
2144 igt_debug("Reload w/o display\n");
2145 igt_i915_driver_unload();
2146 igt_assert_eq(igt_i915_driver_load("disable_display=1 mmio_debug=-1"), 0);
2147
2148 igt_assert(setup_environment());
2149 igt_assert(igt_wait(device_in_pci_d3(), 2000, 100));
2150 teardown_environment();
2151
2152 igt_debug("Reload as normal\n");
2153 igt_i915_driver_unload();
2154 igt_assert_eq(igt_i915_driver_load("mmio_debug=-1"), 0);
2155
2156 igt_assert(setup_environment());
2157 igt_assert(igt_wait(device_in_pci_d3(), 2000, 100));
2158 if (enable_one_screen_with_type(&ms_data, SCREEN_TYPE_ANY))
2159 drm_resources_equal_subtest();
2160 teardown_environment();
2161
2162 /* Remove our mmio_debugging module */
2163 igt_i915_driver_unload();
2164 }
2165 }
2166