xref: /aosp_15_r20/external/igt-gpu-tools/tests/kms_busy.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2016 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  */
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
25*d83cc019SAndroid Build Coastguard Worker 
26*d83cc019SAndroid Build Coastguard Worker #include <sys/poll.h>
27*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
28*d83cc019SAndroid Build Coastguard Worker #include <time.h>
29*d83cc019SAndroid Build Coastguard Worker 
30*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Basic check of KMS ABI with busy framebuffers.");
31*d83cc019SAndroid Build Coastguard Worker 
32*d83cc019SAndroid Build Coastguard Worker static igt_output_t *
set_fb_on_crtc(igt_display_t * dpy,int pipe,struct igt_fb * fb)33*d83cc019SAndroid Build Coastguard Worker set_fb_on_crtc(igt_display_t *dpy, int pipe, struct igt_fb *fb)
34*d83cc019SAndroid Build Coastguard Worker {
35*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfoPtr mode;
36*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
37*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
38*d83cc019SAndroid Build Coastguard Worker 
39*d83cc019SAndroid Build Coastguard Worker 	output = igt_get_single_output_for_pipe(dpy, pipe);
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_pipe(output, pipe);
42*d83cc019SAndroid Build Coastguard Worker 	mode = igt_output_get_mode(output);
43*d83cc019SAndroid Build Coastguard Worker 
44*d83cc019SAndroid Build Coastguard Worker 	igt_create_pattern_fb(dpy->drm_fd, mode->hdisplay, mode->vdisplay,
45*d83cc019SAndroid Build Coastguard Worker 			      DRM_FORMAT_XRGB8888,
46*d83cc019SAndroid Build Coastguard Worker 			      LOCAL_I915_FORMAT_MOD_X_TILED, fb);
47*d83cc019SAndroid Build Coastguard Worker 
48*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
49*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, fb);
50*d83cc019SAndroid Build Coastguard Worker 
51*d83cc019SAndroid Build Coastguard Worker 	return output;
52*d83cc019SAndroid Build Coastguard Worker }
53*d83cc019SAndroid Build Coastguard Worker 
do_cleanup_display(igt_display_t * dpy)54*d83cc019SAndroid Build Coastguard Worker static void do_cleanup_display(igt_display_t *dpy)
55*d83cc019SAndroid Build Coastguard Worker {
56*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
57*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
58*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *plane;
59*d83cc019SAndroid Build Coastguard Worker 
60*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe(dpy, pipe)
61*d83cc019SAndroid Build Coastguard Worker 		for_each_plane_on_pipe(dpy, pipe, plane)
62*d83cc019SAndroid Build Coastguard Worker 			igt_plane_set_fb(plane, NULL);
63*d83cc019SAndroid Build Coastguard Worker 
64*d83cc019SAndroid Build Coastguard Worker 	for_each_connected_output(dpy, output)
65*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, PIPE_NONE);
66*d83cc019SAndroid Build Coastguard Worker 
67*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(dpy, dpy->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
68*d83cc019SAndroid Build Coastguard Worker }
69*d83cc019SAndroid Build Coastguard Worker 
flip_to_fb(igt_display_t * dpy,int pipe,igt_output_t * output,struct igt_fb * fb,unsigned ring,const char * name,bool modeset)70*d83cc019SAndroid Build Coastguard Worker static void flip_to_fb(igt_display_t *dpy, int pipe,
71*d83cc019SAndroid Build Coastguard Worker 		       igt_output_t *output,
72*d83cc019SAndroid Build Coastguard Worker 		       struct igt_fb *fb, unsigned ring,
73*d83cc019SAndroid Build Coastguard Worker 		       const char *name, bool modeset)
74*d83cc019SAndroid Build Coastguard Worker {
75*d83cc019SAndroid Build Coastguard Worker 	struct pollfd pfd = { .fd = dpy->drm_fd, .events = POLLIN };
76*d83cc019SAndroid Build Coastguard Worker 	const int timeout = modeset ? 8500 : 100;
77*d83cc019SAndroid Build Coastguard Worker 	struct drm_event_vblank ev;
78*d83cc019SAndroid Build Coastguard Worker 
79*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *t = igt_spin_new(dpy->drm_fd,
80*d83cc019SAndroid Build Coastguard Worker 				     .engine = ring,
81*d83cc019SAndroid Build Coastguard Worker 				     .dependency = fb->gem_handle);
82*d83cc019SAndroid Build Coastguard Worker 
83*d83cc019SAndroid Build Coastguard Worker 	if (modeset) {
84*d83cc019SAndroid Build Coastguard Worker 		/*
85*d83cc019SAndroid Build Coastguard Worker 		 * We want to check that a modeset actually waits for the
86*d83cc019SAndroid Build Coastguard Worker 		 * spin batch to complete, but we keep a bigger timeout for
87*d83cc019SAndroid Build Coastguard Worker 		 * disable than required for flipping.
88*d83cc019SAndroid Build Coastguard Worker 		 *
89*d83cc019SAndroid Build Coastguard Worker 		 * As a result, the GPU reset code may kick in, which we neuter
90*d83cc019SAndroid Build Coastguard Worker 		 * here to be sure there's no premature completion.
91*d83cc019SAndroid Build Coastguard Worker 		 */
92*d83cc019SAndroid Build Coastguard Worker 		igt_set_module_param_int("enable_hangcheck", 0);
93*d83cc019SAndroid Build Coastguard Worker 	}
94*d83cc019SAndroid Build Coastguard Worker 
95*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
96*d83cc019SAndroid Build Coastguard Worker 		igt_assert(gem_bo_busy(dpy->drm_fd, fb->gem_handle));
97*d83cc019SAndroid Build Coastguard Worker 		if (!modeset)
98*d83cc019SAndroid Build Coastguard Worker 			do_or_die(drmModePageFlip(dpy->drm_fd,
99*d83cc019SAndroid Build Coastguard Worker 						  dpy->pipes[pipe].crtc_id, fb->fb_id,
100*d83cc019SAndroid Build Coastguard Worker 						  DRM_MODE_PAGE_FLIP_EVENT, fb));
101*d83cc019SAndroid Build Coastguard Worker 		else {
102*d83cc019SAndroid Build Coastguard Worker 			igt_plane_set_fb(igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY), fb);
103*d83cc019SAndroid Build Coastguard Worker 			igt_output_set_pipe(output, PIPE_NONE);
104*d83cc019SAndroid Build Coastguard Worker 			igt_display_commit_atomic(dpy,
105*d83cc019SAndroid Build Coastguard Worker 						  DRM_MODE_ATOMIC_NONBLOCK |
106*d83cc019SAndroid Build Coastguard Worker 						  DRM_MODE_PAGE_FLIP_EVENT |
107*d83cc019SAndroid Build Coastguard Worker 						  DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
108*d83cc019SAndroid Build Coastguard Worker 		}
109*d83cc019SAndroid Build Coastguard Worker 
110*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(poll(&pfd, 1, timeout) == 0,
111*d83cc019SAndroid Build Coastguard Worker 			     "flip completed whilst %s was busy [%d]\n",
112*d83cc019SAndroid Build Coastguard Worker 			     name, gem_bo_busy(dpy->drm_fd, fb->gem_handle));
113*d83cc019SAndroid Build Coastguard Worker 		igt_assert(gem_bo_busy(dpy->drm_fd, fb->gem_handle));
114*d83cc019SAndroid Build Coastguard Worker 	}
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren_timeout(5 * timeout,
117*d83cc019SAndroid Build Coastguard Worker 				 "flip blocked waiting for busy bo\n");
118*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(t);
119*d83cc019SAndroid Build Coastguard Worker 
120*d83cc019SAndroid Build Coastguard Worker 	igt_assert(read(dpy->drm_fd, &ev, sizeof(ev)) == sizeof(ev));
121*d83cc019SAndroid Build Coastguard Worker 	igt_assert(poll(&pfd, 1, 0) == 0);
122*d83cc019SAndroid Build Coastguard Worker 
123*d83cc019SAndroid Build Coastguard Worker 	if (modeset) {
124*d83cc019SAndroid Build Coastguard Worker 		gem_quiescent_gpu(dpy->drm_fd);
125*d83cc019SAndroid Build Coastguard Worker 		igt_set_module_param_int("enable_hangcheck", 1);
126*d83cc019SAndroid Build Coastguard Worker 
127*d83cc019SAndroid Build Coastguard Worker 		/* Clear old mode blob. */
128*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_refresh(dpy, pipe, true);
129*d83cc019SAndroid Build Coastguard Worker 
130*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, pipe);
131*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(dpy, COMMIT_ATOMIC);
132*d83cc019SAndroid Build Coastguard Worker 	}
133*d83cc019SAndroid Build Coastguard Worker 
134*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(dpy->drm_fd, t);
135*d83cc019SAndroid Build Coastguard Worker }
136*d83cc019SAndroid Build Coastguard Worker 
test_flip(igt_display_t * dpy,unsigned ring,int pipe,bool modeset)137*d83cc019SAndroid Build Coastguard Worker static void test_flip(igt_display_t *dpy, unsigned ring, int pipe, bool modeset)
138*d83cc019SAndroid Build Coastguard Worker {
139*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb[2];
140*d83cc019SAndroid Build Coastguard Worker 	int warmup[] = { 0, 1, 0, -1 };
141*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
142*d83cc019SAndroid Build Coastguard Worker 
143*d83cc019SAndroid Build Coastguard Worker 	if (modeset)
144*d83cc019SAndroid Build Coastguard Worker 		igt_require(dpy->is_atomic);
145*d83cc019SAndroid Build Coastguard Worker 
146*d83cc019SAndroid Build Coastguard Worker 	output = set_fb_on_crtc(dpy, pipe, &fb[0]);
147*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(dpy, COMMIT_LEGACY);
148*d83cc019SAndroid Build Coastguard Worker 
149*d83cc019SAndroid Build Coastguard Worker 	igt_create_pattern_fb(dpy->drm_fd,
150*d83cc019SAndroid Build Coastguard Worker 			      fb[0].width, fb[0].height,
151*d83cc019SAndroid Build Coastguard Worker 			      DRM_FORMAT_XRGB8888,
152*d83cc019SAndroid Build Coastguard Worker 			      LOCAL_I915_FORMAT_MOD_X_TILED,
153*d83cc019SAndroid Build Coastguard Worker 			      &fb[1]);
154*d83cc019SAndroid Build Coastguard Worker 
155*d83cc019SAndroid Build Coastguard Worker 	/* Bind both fb to the display (such that they are ready for future
156*d83cc019SAndroid Build Coastguard Worker 	 * flips without stalling for the bind) leaving fb[0] as bound.
157*d83cc019SAndroid Build Coastguard Worker 	 */
158*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; warmup[i] != -1; i++) {
159*d83cc019SAndroid Build Coastguard Worker 		struct drm_event_vblank ev;
160*d83cc019SAndroid Build Coastguard Worker 
161*d83cc019SAndroid Build Coastguard Worker 		do_or_die(drmModePageFlip(dpy->drm_fd,
162*d83cc019SAndroid Build Coastguard Worker 					  dpy->pipes[pipe].crtc_id,
163*d83cc019SAndroid Build Coastguard Worker 					  fb[warmup[i]].fb_id,
164*d83cc019SAndroid Build Coastguard Worker 					  DRM_MODE_PAGE_FLIP_EVENT,
165*d83cc019SAndroid Build Coastguard Worker 					  &fb[warmup[i]]));
166*d83cc019SAndroid Build Coastguard Worker 		igt_assert(read(dpy->drm_fd, &ev, sizeof(ev)) == sizeof(ev));
167*d83cc019SAndroid Build Coastguard Worker 	}
168*d83cc019SAndroid Build Coastguard Worker 
169*d83cc019SAndroid Build Coastguard Worker 	/* Make the frontbuffer busy and try to flip to itself */
170*d83cc019SAndroid Build Coastguard Worker 	flip_to_fb(dpy, pipe, output, &fb[0], ring, "fb[0]", modeset);
171*d83cc019SAndroid Build Coastguard Worker 
172*d83cc019SAndroid Build Coastguard Worker 	/* Repeat for flip to second buffer */
173*d83cc019SAndroid Build Coastguard Worker 	flip_to_fb(dpy, pipe, output, &fb[1], ring, "fb[1]", modeset);
174*d83cc019SAndroid Build Coastguard Worker 
175*d83cc019SAndroid Build Coastguard Worker 	do_cleanup_display(dpy);
176*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(dpy->drm_fd, &fb[1]);
177*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(dpy->drm_fd, &fb[0]);
178*d83cc019SAndroid Build Coastguard Worker }
179*d83cc019SAndroid Build Coastguard Worker 
test_atomic_commit_hang(igt_display_t * dpy,igt_plane_t * primary,struct igt_fb * busy_fb,unsigned ring)180*d83cc019SAndroid Build Coastguard Worker static void test_atomic_commit_hang(igt_display_t *dpy, igt_plane_t *primary,
181*d83cc019SAndroid Build Coastguard Worker 				    struct igt_fb *busy_fb, unsigned ring)
182*d83cc019SAndroid Build Coastguard Worker {
183*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *t = igt_spin_new(dpy->drm_fd,
184*d83cc019SAndroid Build Coastguard Worker 				     .engine = ring,
185*d83cc019SAndroid Build Coastguard Worker 				     .dependency = busy_fb->gem_handle);
186*d83cc019SAndroid Build Coastguard Worker 	struct pollfd pfd = { .fd = dpy->drm_fd, .events = POLLIN };
187*d83cc019SAndroid Build Coastguard Worker 	unsigned flags = 0;
188*d83cc019SAndroid Build Coastguard Worker 	struct drm_event_vblank ev;
189*d83cc019SAndroid Build Coastguard Worker 
190*d83cc019SAndroid Build Coastguard Worker 	flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
191*d83cc019SAndroid Build Coastguard Worker 	flags |= DRM_MODE_ATOMIC_NONBLOCK;
192*d83cc019SAndroid Build Coastguard Worker 	flags |= DRM_MODE_PAGE_FLIP_EVENT;
193*d83cc019SAndroid Build Coastguard Worker 
194*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit_atomic(dpy, flags, NULL);
195*d83cc019SAndroid Build Coastguard Worker 
196*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
197*d83cc019SAndroid Build Coastguard Worker 		/*
198*d83cc019SAndroid Build Coastguard Worker 		 * bit of a hack, just set atomic commit to NULL fb to make sure
199*d83cc019SAndroid Build Coastguard Worker 		 * that we don't wait for the new update to complete.
200*d83cc019SAndroid Build Coastguard Worker 		 */
201*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(primary, NULL);
202*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit_atomic(dpy, 0, NULL);
203*d83cc019SAndroid Build Coastguard Worker 
204*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(poll(&pfd, 1, 1) > 0,
205*d83cc019SAndroid Build Coastguard Worker 			    "nonblocking update completed whilst fb[%d] was still busy [%d]\n",
206*d83cc019SAndroid Build Coastguard Worker 			    busy_fb->fb_id, gem_bo_busy(dpy->drm_fd, busy_fb->gem_handle));
207*d83cc019SAndroid Build Coastguard Worker 	}
208*d83cc019SAndroid Build Coastguard Worker 
209*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
210*d83cc019SAndroid Build Coastguard Worker 
211*d83cc019SAndroid Build Coastguard Worker 	igt_assert(read(dpy->drm_fd, &ev, sizeof(ev)) == sizeof(ev));
212*d83cc019SAndroid Build Coastguard Worker 
213*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(t);
214*d83cc019SAndroid Build Coastguard Worker }
215*d83cc019SAndroid Build Coastguard Worker 
test_hang(igt_display_t * dpy,unsigned ring,enum pipe pipe,bool modeset,bool hang_newfb)216*d83cc019SAndroid Build Coastguard Worker static void test_hang(igt_display_t *dpy, unsigned ring,
217*d83cc019SAndroid Build Coastguard Worker 		      enum pipe pipe, bool modeset, bool hang_newfb)
218*d83cc019SAndroid Build Coastguard Worker {
219*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb[2];
220*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
221*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
222*d83cc019SAndroid Build Coastguard Worker 
223*d83cc019SAndroid Build Coastguard Worker 	output = set_fb_on_crtc(dpy, pipe, &fb[0]);
224*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(dpy, COMMIT_ATOMIC);
225*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
226*d83cc019SAndroid Build Coastguard Worker 
227*d83cc019SAndroid Build Coastguard Worker 	igt_create_pattern_fb(dpy->drm_fd,
228*d83cc019SAndroid Build Coastguard Worker 			      fb[0].width, fb[0].height,
229*d83cc019SAndroid Build Coastguard Worker 			      DRM_FORMAT_XRGB8888,
230*d83cc019SAndroid Build Coastguard Worker 			      LOCAL_I915_FORMAT_MOD_X_TILED,
231*d83cc019SAndroid Build Coastguard Worker 			      &fb[1]);
232*d83cc019SAndroid Build Coastguard Worker 
233*d83cc019SAndroid Build Coastguard Worker 	if (modeset) {
234*d83cc019SAndroid Build Coastguard Worker 		/* Test modeset disable with hang */
235*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, PIPE_NONE);
236*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(primary, &fb[1]);
237*d83cc019SAndroid Build Coastguard Worker 		test_atomic_commit_hang(dpy, primary, &fb[hang_newfb], ring);
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker 		/* Test modeset enable with hang */
240*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(primary, &fb[0]);
241*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, pipe);
242*d83cc019SAndroid Build Coastguard Worker 		test_atomic_commit_hang(dpy, primary, &fb[!hang_newfb], ring);
243*d83cc019SAndroid Build Coastguard Worker 	} else {
244*d83cc019SAndroid Build Coastguard Worker 		/*
245*d83cc019SAndroid Build Coastguard Worker 		 * Test what happens with a single hanging pageflip.
246*d83cc019SAndroid Build Coastguard Worker 		 * This always completes early, because we have some
247*d83cc019SAndroid Build Coastguard Worker 		 * timeouts taking care of it.
248*d83cc019SAndroid Build Coastguard Worker 		 */
249*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(primary, &fb[1]);
250*d83cc019SAndroid Build Coastguard Worker 		test_atomic_commit_hang(dpy, primary, &fb[hang_newfb], ring);
251*d83cc019SAndroid Build Coastguard Worker 	}
252*d83cc019SAndroid Build Coastguard Worker 
253*d83cc019SAndroid Build Coastguard Worker 	do_cleanup_display(dpy);
254*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(dpy->drm_fd, &fb[1]);
255*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(dpy->drm_fd, &fb[0]);
256*d83cc019SAndroid Build Coastguard Worker }
257*d83cc019SAndroid Build Coastguard Worker 
test_pageflip_modeset_hang(igt_display_t * dpy,unsigned ring,enum pipe pipe)258*d83cc019SAndroid Build Coastguard Worker static void test_pageflip_modeset_hang(igt_display_t *dpy,
259*d83cc019SAndroid Build Coastguard Worker 				       unsigned ring, enum pipe pipe)
260*d83cc019SAndroid Build Coastguard Worker {
261*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb;
262*d83cc019SAndroid Build Coastguard Worker 	struct drm_event_vblank ev;
263*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
264*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
265*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *t;
266*d83cc019SAndroid Build Coastguard Worker 
267*d83cc019SAndroid Build Coastguard Worker 	output = set_fb_on_crtc(dpy, pipe, &fb);
268*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
269*d83cc019SAndroid Build Coastguard Worker 
270*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(dpy, dpy->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
271*d83cc019SAndroid Build Coastguard Worker 
272*d83cc019SAndroid Build Coastguard Worker 	t = igt_spin_new(dpy->drm_fd,
273*d83cc019SAndroid Build Coastguard Worker 			 .engine = ring,
274*d83cc019SAndroid Build Coastguard Worker 			 .dependency = fb.gem_handle);
275*d83cc019SAndroid Build Coastguard Worker 
276*d83cc019SAndroid Build Coastguard Worker 	do_or_die(drmModePageFlip(dpy->drm_fd, dpy->pipes[pipe].crtc_id, fb.fb_id, DRM_MODE_PAGE_FLIP_EVENT, &fb));
277*d83cc019SAndroid Build Coastguard Worker 
278*d83cc019SAndroid Build Coastguard Worker 	/* Kill crtc with hung fb */
279*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, NULL);
280*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_pipe(output, PIPE_NONE);
281*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(dpy, dpy->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
282*d83cc019SAndroid Build Coastguard Worker 
283*d83cc019SAndroid Build Coastguard Worker 	igt_assert(read(dpy->drm_fd, &ev, sizeof(ev)) == sizeof(ev));
284*d83cc019SAndroid Build Coastguard Worker 
285*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(t);
286*d83cc019SAndroid Build Coastguard Worker 
287*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(dpy->drm_fd, &fb);
288*d83cc019SAndroid Build Coastguard Worker }
289*d83cc019SAndroid Build Coastguard Worker 
290*d83cc019SAndroid Build Coastguard Worker igt_main
291*d83cc019SAndroid Build Coastguard Worker {
292*d83cc019SAndroid Build Coastguard Worker 	igt_display_t display = { .drm_fd = -1, .n_pipes = IGT_MAX_PIPES };
293*d83cc019SAndroid Build Coastguard Worker 	/* we only test on render */
294*d83cc019SAndroid Build Coastguard Worker 	const struct intel_execution_engine *e = &intel_execution_engines[1];
295*d83cc019SAndroid Build Coastguard Worker 	enum pipe n;
296*d83cc019SAndroid Build Coastguard Worker 
297*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
298*d83cc019SAndroid Build Coastguard Worker 
299*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
300*d83cc019SAndroid Build Coastguard Worker 		int fd = drm_open_driver_master(DRIVER_INTEL);
301*d83cc019SAndroid Build Coastguard Worker 
302*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(fd);
303*d83cc019SAndroid Build Coastguard Worker 		gem_require_mmap_wc(fd);
304*d83cc019SAndroid Build Coastguard Worker 
305*d83cc019SAndroid Build Coastguard Worker 		kmstest_set_vt_graphics_mode();
306*d83cc019SAndroid Build Coastguard Worker 		igt_display_require(&display, fd);
307*d83cc019SAndroid Build Coastguard Worker 	}
308*d83cc019SAndroid Build Coastguard Worker 
309*d83cc019SAndroid Build Coastguard Worker 	/* XXX Extend to cover atomic rendering tests to all planes + legacy */
310*d83cc019SAndroid Build Coastguard Worker 
for_each_pipe_static(n)311*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe_static(n) igt_subtest_group {
312*d83cc019SAndroid Build Coastguard Worker 		igt_hang_t hang;
313*d83cc019SAndroid Build Coastguard Worker 
314*d83cc019SAndroid Build Coastguard Worker 		errno = 0;
315*d83cc019SAndroid Build Coastguard Worker 
316*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
317*d83cc019SAndroid Build Coastguard Worker 			igt_display_require_output_on_pipe(&display, n);
318*d83cc019SAndroid Build Coastguard Worker 		}
319*d83cc019SAndroid Build Coastguard Worker 
320*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("basic-flip-%s",
321*d83cc019SAndroid Build Coastguard Worker 			kmstest_pipe_name(n)) {
322*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_has_ring(display.drm_fd,
323*d83cc019SAndroid Build Coastguard Worker 						e->exec_id | e->flags));
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 			test_flip(&display, e->exec_id | e->flags, n, false);
326*d83cc019SAndroid Build Coastguard Worker 		}
327*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("basic-modeset-%s",
328*d83cc019SAndroid Build Coastguard Worker 			kmstest_pipe_name(n)) {
329*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_has_ring(display.drm_fd,
330*d83cc019SAndroid Build Coastguard Worker 						e->exec_id | e->flags));
331*d83cc019SAndroid Build Coastguard Worker 
332*d83cc019SAndroid Build Coastguard Worker 			test_flip(&display, e->exec_id | e->flags, n, true);
333*d83cc019SAndroid Build Coastguard Worker 		}
334*d83cc019SAndroid Build Coastguard Worker 
335*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
336*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_has_ring(display.drm_fd,
337*d83cc019SAndroid Build Coastguard Worker 						e->exec_id | e->flags));
338*d83cc019SAndroid Build Coastguard Worker 
339*d83cc019SAndroid Build Coastguard Worker 			hang = igt_allow_hang(display.drm_fd, 0, 0);
340*d83cc019SAndroid Build Coastguard Worker 		}
341*d83cc019SAndroid Build Coastguard Worker 
342*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("extended-pageflip-modeset-hang-oldfb-%s-%s",
343*d83cc019SAndroid Build Coastguard Worker 				e->name, kmstest_pipe_name(n)) {
344*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_has_ring(display.drm_fd,
345*d83cc019SAndroid Build Coastguard Worker 						e->exec_id | e->flags));
346*d83cc019SAndroid Build Coastguard Worker 
347*d83cc019SAndroid Build Coastguard Worker 			test_pageflip_modeset_hang(&display, e->exec_id | e->flags, n);
348*d83cc019SAndroid Build Coastguard Worker 		}
349*d83cc019SAndroid Build Coastguard Worker 
350*d83cc019SAndroid Build Coastguard Worker 		igt_fixture
351*d83cc019SAndroid Build Coastguard Worker 			igt_require(display.is_atomic);
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("extended-pageflip-hang-oldfb-%s-%s",
354*d83cc019SAndroid Build Coastguard Worker 				e->name, kmstest_pipe_name(n))
355*d83cc019SAndroid Build Coastguard Worker 			test_hang(&display, e->exec_id | e->flags, n, false, false);
356*d83cc019SAndroid Build Coastguard Worker 
357*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("extended-pageflip-hang-newfb-%s-%s",
358*d83cc019SAndroid Build Coastguard Worker 				e->name, kmstest_pipe_name(n))
359*d83cc019SAndroid Build Coastguard Worker 			test_hang(&display, e->exec_id | e->flags, n, false, true);
360*d83cc019SAndroid Build Coastguard Worker 
361*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("extended-modeset-hang-oldfb-%s-%s",
362*d83cc019SAndroid Build Coastguard Worker 				e->name, kmstest_pipe_name(n))
363*d83cc019SAndroid Build Coastguard Worker 			test_hang(&display, e->exec_id | e->flags, n, true, false);
364*d83cc019SAndroid Build Coastguard Worker 
365*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("extended-modeset-hang-newfb-%s-%s",
366*d83cc019SAndroid Build Coastguard Worker 				e->name, kmstest_pipe_name(n))
367*d83cc019SAndroid Build Coastguard Worker 			test_hang(&display, e->exec_id | e->flags, n, true, true);
368*d83cc019SAndroid Build Coastguard Worker 
369*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("extended-modeset-hang-oldfb-with-reset-%s-%s",
370*d83cc019SAndroid Build Coastguard Worker 				e->name, kmstest_pipe_name(n)) {
371*d83cc019SAndroid Build Coastguard Worker 			igt_set_module_param_int("force_reset_modeset_test", 1);
372*d83cc019SAndroid Build Coastguard Worker 
373*d83cc019SAndroid Build Coastguard Worker 			test_hang(&display, e->exec_id | e->flags, n, true, false);
374*d83cc019SAndroid Build Coastguard Worker 
375*d83cc019SAndroid Build Coastguard Worker 			igt_set_module_param_int("force_reset_modeset_test", 0);
376*d83cc019SAndroid Build Coastguard Worker 		}
377*d83cc019SAndroid Build Coastguard Worker 
378*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("extended-modeset-hang-newfb-with-reset-%s-%s",
379*d83cc019SAndroid Build Coastguard Worker 				e->name, kmstest_pipe_name(n)) {
380*d83cc019SAndroid Build Coastguard Worker 			igt_set_module_param_int("force_reset_modeset_test", 1);
381*d83cc019SAndroid Build Coastguard Worker 
382*d83cc019SAndroid Build Coastguard Worker 			test_hang(&display, e->exec_id | e->flags, n, true, true);
383*d83cc019SAndroid Build Coastguard Worker 
384*d83cc019SAndroid Build Coastguard Worker 			igt_set_module_param_int("force_reset_modeset_test", 0);
385*d83cc019SAndroid Build Coastguard Worker 		}
386*d83cc019SAndroid Build Coastguard Worker 
387*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
388*d83cc019SAndroid Build Coastguard Worker 			igt_disallow_hang(display.drm_fd, hang);
389*d83cc019SAndroid Build Coastguard Worker 		}
390*d83cc019SAndroid Build Coastguard Worker 	}
391*d83cc019SAndroid Build Coastguard Worker 
392*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
393*d83cc019SAndroid Build Coastguard Worker 		igt_display_fini(&display);
394*d83cc019SAndroid Build Coastguard Worker 	}
395*d83cc019SAndroid Build Coastguard Worker }
396