xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/i915_pm_rpm.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
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 			      &params->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 			    &params->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 		      &params.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(&params);
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(&params);
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