1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2013 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
25*d83cc019SAndroid Build Coastguard Worker #include <sched.h>
26*d83cc019SAndroid Build Coastguard Worker #include <sys/poll.h>
27*d83cc019SAndroid Build Coastguard Worker
28*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
29*d83cc019SAndroid Build Coastguard Worker #include "igt_rand.h"
30*d83cc019SAndroid Build Coastguard Worker #include "igt_stats.h"
31*d83cc019SAndroid Build Coastguard Worker
32*d83cc019SAndroid Build Coastguard Worker #if defined(__x86_64__) || defined(__i386__)
33*d83cc019SAndroid Build Coastguard Worker #define cpu_relax() __builtin_ia32_pause()
34*d83cc019SAndroid Build Coastguard Worker #else
35*d83cc019SAndroid Build Coastguard Worker #define cpu_relax() asm volatile("": : :"memory")
36*d83cc019SAndroid Build Coastguard Worker #endif
37*d83cc019SAndroid Build Coastguard Worker
38*d83cc019SAndroid Build Coastguard Worker #ifndef DRM_CAP_CURSOR_WIDTH
39*d83cc019SAndroid Build Coastguard Worker #define DRM_CAP_CURSOR_WIDTH 0x8
40*d83cc019SAndroid Build Coastguard Worker #endif
41*d83cc019SAndroid Build Coastguard Worker
42*d83cc019SAndroid Build Coastguard Worker #ifndef DRM_CAP_CURSOR_HEIGHT
43*d83cc019SAndroid Build Coastguard Worker #define DRM_CAP_CURSOR_HEIGHT 0x9
44*d83cc019SAndroid Build Coastguard Worker #endif
45*d83cc019SAndroid Build Coastguard Worker
46*d83cc019SAndroid Build Coastguard Worker #define PAGE_SIZE 4096
47*d83cc019SAndroid Build Coastguard Worker
48*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Stress legacy cursor ioctl");
49*d83cc019SAndroid Build Coastguard Worker
50*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_t *pipe_crc;
51*d83cc019SAndroid Build Coastguard Worker
stress(igt_display_t * display,enum pipe pipe,int num_children,unsigned mode,int timeout)52*d83cc019SAndroid Build Coastguard Worker static void stress(igt_display_t *display,
53*d83cc019SAndroid Build Coastguard Worker enum pipe pipe, int num_children, unsigned mode,
54*d83cc019SAndroid Build Coastguard Worker int timeout)
55*d83cc019SAndroid Build Coastguard Worker {
56*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg;
57*d83cc019SAndroid Build Coastguard Worker uint64_t *results;
58*d83cc019SAndroid Build Coastguard Worker bool torture;
59*d83cc019SAndroid Build Coastguard Worker int n;
60*d83cc019SAndroid Build Coastguard Worker unsigned crtc_id[IGT_MAX_PIPES], num_crtcs;
61*d83cc019SAndroid Build Coastguard Worker
62*d83cc019SAndroid Build Coastguard Worker torture = false;
63*d83cc019SAndroid Build Coastguard Worker if (num_children < 0) {
64*d83cc019SAndroid Build Coastguard Worker torture = true;
65*d83cc019SAndroid Build Coastguard Worker num_children = -num_children;
66*d83cc019SAndroid Build Coastguard Worker }
67*d83cc019SAndroid Build Coastguard Worker
68*d83cc019SAndroid Build Coastguard Worker results = mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
69*d83cc019SAndroid Build Coastguard Worker igt_assert(results != MAP_FAILED);
70*d83cc019SAndroid Build Coastguard Worker
71*d83cc019SAndroid Build Coastguard Worker memset(&arg, 0, sizeof(arg));
72*d83cc019SAndroid Build Coastguard Worker arg.flags = DRM_MODE_CURSOR_BO;
73*d83cc019SAndroid Build Coastguard Worker arg.crtc_id = 0;
74*d83cc019SAndroid Build Coastguard Worker arg.width = 64;
75*d83cc019SAndroid Build Coastguard Worker arg.height = 64;
76*d83cc019SAndroid Build Coastguard Worker arg.handle = kmstest_dumb_create(display->drm_fd, 64, 64, 32, NULL, NULL);
77*d83cc019SAndroid Build Coastguard Worker
78*d83cc019SAndroid Build Coastguard Worker if (pipe < 0) {
79*d83cc019SAndroid Build Coastguard Worker num_crtcs = display->n_pipes;
80*d83cc019SAndroid Build Coastguard Worker for_each_pipe(display, n) {
81*d83cc019SAndroid Build Coastguard Worker arg.crtc_id = crtc_id[n] = display->pipes[n].crtc_id;
82*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg);
83*d83cc019SAndroid Build Coastguard Worker }
84*d83cc019SAndroid Build Coastguard Worker } else {
85*d83cc019SAndroid Build Coastguard Worker num_crtcs = 1;
86*d83cc019SAndroid Build Coastguard Worker arg.crtc_id = crtc_id[0] = display->pipes[pipe].crtc_id;
87*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg);
88*d83cc019SAndroid Build Coastguard Worker }
89*d83cc019SAndroid Build Coastguard Worker
90*d83cc019SAndroid Build Coastguard Worker arg.flags = mode;
91*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_children) {
92*d83cc019SAndroid Build Coastguard Worker struct sched_param rt = {.sched_priority = 99 };
93*d83cc019SAndroid Build Coastguard Worker cpu_set_t allowed;
94*d83cc019SAndroid Build Coastguard Worker unsigned long count = 0;
95*d83cc019SAndroid Build Coastguard Worker
96*d83cc019SAndroid Build Coastguard Worker sched_setscheduler(getpid(), SCHED_RR, &rt);
97*d83cc019SAndroid Build Coastguard Worker
98*d83cc019SAndroid Build Coastguard Worker CPU_ZERO(&allowed);
99*d83cc019SAndroid Build Coastguard Worker CPU_SET(child, &allowed);
100*d83cc019SAndroid Build Coastguard Worker sched_setaffinity(getpid(), sizeof(cpu_set_t), &allowed);
101*d83cc019SAndroid Build Coastguard Worker
102*d83cc019SAndroid Build Coastguard Worker hars_petruska_f54_1_random_perturb(child);
103*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
104*d83cc019SAndroid Build Coastguard Worker arg.crtc_id = crtc_id[hars_petruska_f54_1_random_unsafe() % num_crtcs];
105*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg);
106*d83cc019SAndroid Build Coastguard Worker count++;
107*d83cc019SAndroid Build Coastguard Worker }
108*d83cc019SAndroid Build Coastguard Worker
109*d83cc019SAndroid Build Coastguard Worker igt_debug("[%d] count=%lu\n", child, count);
110*d83cc019SAndroid Build Coastguard Worker results[child] = count;
111*d83cc019SAndroid Build Coastguard Worker }
112*d83cc019SAndroid Build Coastguard Worker if (torture) {
113*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_children) {
114*d83cc019SAndroid Build Coastguard Worker struct sched_param rt = {.sched_priority = 1 };
115*d83cc019SAndroid Build Coastguard Worker cpu_set_t allowed;
116*d83cc019SAndroid Build Coastguard Worker unsigned long long count = 0;
117*d83cc019SAndroid Build Coastguard Worker
118*d83cc019SAndroid Build Coastguard Worker sched_setscheduler(getpid(), SCHED_RR, &rt);
119*d83cc019SAndroid Build Coastguard Worker
120*d83cc019SAndroid Build Coastguard Worker CPU_ZERO(&allowed);
121*d83cc019SAndroid Build Coastguard Worker CPU_SET(child, &allowed);
122*d83cc019SAndroid Build Coastguard Worker sched_setaffinity(getpid(), sizeof(cpu_set_t), &allowed);
123*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
124*d83cc019SAndroid Build Coastguard Worker count++;
125*d83cc019SAndroid Build Coastguard Worker cpu_relax();
126*d83cc019SAndroid Build Coastguard Worker }
127*d83cc019SAndroid Build Coastguard Worker igt_debug("[hog:%d] count=%llu\n", child, count);
128*d83cc019SAndroid Build Coastguard Worker }
129*d83cc019SAndroid Build Coastguard Worker }
130*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
131*d83cc019SAndroid Build Coastguard Worker
132*d83cc019SAndroid Build Coastguard Worker if (num_children > 1) {
133*d83cc019SAndroid Build Coastguard Worker igt_stats_t stats;
134*d83cc019SAndroid Build Coastguard Worker
135*d83cc019SAndroid Build Coastguard Worker igt_stats_init_with_size(&stats, num_children);
136*d83cc019SAndroid Build Coastguard Worker results[num_children] = 0;
137*d83cc019SAndroid Build Coastguard Worker for (int child = 0; child < num_children; child++) {
138*d83cc019SAndroid Build Coastguard Worker igt_stats_push(&stats, results[child]);
139*d83cc019SAndroid Build Coastguard Worker results[num_children] += results[child];
140*d83cc019SAndroid Build Coastguard Worker }
141*d83cc019SAndroid Build Coastguard Worker igt_info("Total updates %llu (median of %d processes is %.2f)\n",
142*d83cc019SAndroid Build Coastguard Worker (long long)results[num_children],
143*d83cc019SAndroid Build Coastguard Worker num_children,
144*d83cc019SAndroid Build Coastguard Worker igt_stats_get_median(&stats));
145*d83cc019SAndroid Build Coastguard Worker igt_stats_fini(&stats);
146*d83cc019SAndroid Build Coastguard Worker } else {
147*d83cc019SAndroid Build Coastguard Worker igt_info("Total updates %llu\n", (long long)results[0]);
148*d83cc019SAndroid Build Coastguard Worker }
149*d83cc019SAndroid Build Coastguard Worker
150*d83cc019SAndroid Build Coastguard Worker gem_close(display->drm_fd, arg.handle);
151*d83cc019SAndroid Build Coastguard Worker munmap(results, PAGE_SIZE);
152*d83cc019SAndroid Build Coastguard Worker }
153*d83cc019SAndroid Build Coastguard Worker
set_fb_on_crtc(igt_display_t * display,enum pipe pipe,struct igt_fb * fb_info)154*d83cc019SAndroid Build Coastguard Worker static igt_output_t *set_fb_on_crtc(igt_display_t *display, enum pipe pipe, struct igt_fb *fb_info)
155*d83cc019SAndroid Build Coastguard Worker {
156*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
157*d83cc019SAndroid Build Coastguard Worker
158*d83cc019SAndroid Build Coastguard Worker for_each_valid_output_on_pipe(display, pipe, output) {
159*d83cc019SAndroid Build Coastguard Worker drmModeModeInfoPtr mode;
160*d83cc019SAndroid Build Coastguard Worker igt_plane_t *primary;
161*d83cc019SAndroid Build Coastguard Worker
162*d83cc019SAndroid Build Coastguard Worker if (output->pending_pipe != PIPE_NONE)
163*d83cc019SAndroid Build Coastguard Worker continue;
164*d83cc019SAndroid Build Coastguard Worker
165*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output, pipe);
166*d83cc019SAndroid Build Coastguard Worker mode = igt_output_get_mode(output);
167*d83cc019SAndroid Build Coastguard Worker
168*d83cc019SAndroid Build Coastguard Worker igt_create_pattern_fb(display->drm_fd,
169*d83cc019SAndroid Build Coastguard Worker mode->hdisplay, mode->vdisplay,
170*d83cc019SAndroid Build Coastguard Worker DRM_FORMAT_XRGB8888, I915_TILING_NONE, fb_info);
171*d83cc019SAndroid Build Coastguard Worker
172*d83cc019SAndroid Build Coastguard Worker primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
173*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(primary, fb_info);
174*d83cc019SAndroid Build Coastguard Worker
175*d83cc019SAndroid Build Coastguard Worker return output;
176*d83cc019SAndroid Build Coastguard Worker }
177*d83cc019SAndroid Build Coastguard Worker
178*d83cc019SAndroid Build Coastguard Worker return NULL;
179*d83cc019SAndroid Build Coastguard Worker }
180*d83cc019SAndroid Build Coastguard Worker
set_cursor_on_pipe(igt_display_t * display,enum pipe pipe,struct igt_fb * fb)181*d83cc019SAndroid Build Coastguard Worker static void set_cursor_on_pipe(igt_display_t *display, enum pipe pipe, struct igt_fb *fb)
182*d83cc019SAndroid Build Coastguard Worker {
183*d83cc019SAndroid Build Coastguard Worker igt_plane_t *plane, *cursor = NULL;
184*d83cc019SAndroid Build Coastguard Worker
185*d83cc019SAndroid Build Coastguard Worker for_each_plane_on_pipe(display, pipe, plane) {
186*d83cc019SAndroid Build Coastguard Worker if (plane->type != DRM_PLANE_TYPE_CURSOR)
187*d83cc019SAndroid Build Coastguard Worker continue;
188*d83cc019SAndroid Build Coastguard Worker
189*d83cc019SAndroid Build Coastguard Worker cursor = plane;
190*d83cc019SAndroid Build Coastguard Worker break;
191*d83cc019SAndroid Build Coastguard Worker }
192*d83cc019SAndroid Build Coastguard Worker
193*d83cc019SAndroid Build Coastguard Worker igt_require(cursor);
194*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(cursor, fb);
195*d83cc019SAndroid Build Coastguard Worker }
196*d83cc019SAndroid Build Coastguard Worker
populate_cursor_args(igt_display_t * display,enum pipe pipe,struct drm_mode_cursor * arg,struct igt_fb * fb)197*d83cc019SAndroid Build Coastguard Worker static void populate_cursor_args(igt_display_t *display, enum pipe pipe,
198*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor *arg, struct igt_fb *fb)
199*d83cc019SAndroid Build Coastguard Worker {
200*d83cc019SAndroid Build Coastguard Worker arg->crtc_id = display->pipes[pipe].crtc_id;
201*d83cc019SAndroid Build Coastguard Worker arg->flags = DRM_MODE_CURSOR_MOVE;
202*d83cc019SAndroid Build Coastguard Worker arg->x = 128;
203*d83cc019SAndroid Build Coastguard Worker arg->y = 128;
204*d83cc019SAndroid Build Coastguard Worker arg->width = fb->width;
205*d83cc019SAndroid Build Coastguard Worker arg->height = fb->height;
206*d83cc019SAndroid Build Coastguard Worker arg->handle = fb->gem_handle;
207*d83cc019SAndroid Build Coastguard Worker arg[1] = *arg;
208*d83cc019SAndroid Build Coastguard Worker }
209*d83cc019SAndroid Build Coastguard Worker
find_connected_pipe(igt_display_t * display,bool second)210*d83cc019SAndroid Build Coastguard Worker static enum pipe find_connected_pipe(igt_display_t *display, bool second)
211*d83cc019SAndroid Build Coastguard Worker {
212*d83cc019SAndroid Build Coastguard Worker enum pipe pipe, first = PIPE_NONE;
213*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
214*d83cc019SAndroid Build Coastguard Worker igt_output_t *first_output = NULL;
215*d83cc019SAndroid Build Coastguard Worker bool found = false;
216*d83cc019SAndroid Build Coastguard Worker
217*d83cc019SAndroid Build Coastguard Worker if (!second) {
218*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_free(pipe_crc);
219*d83cc019SAndroid Build Coastguard Worker pipe_crc = NULL;
220*d83cc019SAndroid Build Coastguard Worker
221*d83cc019SAndroid Build Coastguard Worker /* Clear display, events will be eaten by commit.. */
222*d83cc019SAndroid Build Coastguard Worker igt_display_reset(display);
223*d83cc019SAndroid Build Coastguard Worker }
224*d83cc019SAndroid Build Coastguard Worker
225*d83cc019SAndroid Build Coastguard Worker for_each_pipe_with_valid_output(display, pipe, output) {
226*d83cc019SAndroid Build Coastguard Worker if (first == pipe || output == first_output)
227*d83cc019SAndroid Build Coastguard Worker continue;
228*d83cc019SAndroid Build Coastguard Worker
229*d83cc019SAndroid Build Coastguard Worker if (second) {
230*d83cc019SAndroid Build Coastguard Worker first = pipe;
231*d83cc019SAndroid Build Coastguard Worker first_output = output;
232*d83cc019SAndroid Build Coastguard Worker second = false;
233*d83cc019SAndroid Build Coastguard Worker continue;
234*d83cc019SAndroid Build Coastguard Worker }
235*d83cc019SAndroid Build Coastguard Worker
236*d83cc019SAndroid Build Coastguard Worker found = true;
237*d83cc019SAndroid Build Coastguard Worker break;
238*d83cc019SAndroid Build Coastguard Worker }
239*d83cc019SAndroid Build Coastguard Worker
240*d83cc019SAndroid Build Coastguard Worker if (first_output)
241*d83cc019SAndroid Build Coastguard Worker igt_require_f(found, "No second valid output found\n");
242*d83cc019SAndroid Build Coastguard Worker else
243*d83cc019SAndroid Build Coastguard Worker igt_require_f(found, "No valid outputs found\n");
244*d83cc019SAndroid Build Coastguard Worker
245*d83cc019SAndroid Build Coastguard Worker return pipe;
246*d83cc019SAndroid Build Coastguard Worker }
247*d83cc019SAndroid Build Coastguard Worker
flip_nonblocking(igt_display_t * display,enum pipe pipe_id,bool atomic,struct igt_fb * fb,void * data)248*d83cc019SAndroid Build Coastguard Worker static void flip_nonblocking(igt_display_t *display, enum pipe pipe_id, bool atomic, struct igt_fb *fb, void *data)
249*d83cc019SAndroid Build Coastguard Worker {
250*d83cc019SAndroid Build Coastguard Worker igt_pipe_t *pipe = &display->pipes[pipe_id];
251*d83cc019SAndroid Build Coastguard Worker igt_plane_t *primary = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY);
252*d83cc019SAndroid Build Coastguard Worker int ret;
253*d83cc019SAndroid Build Coastguard Worker
254*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Scheduling page flip\n");
255*d83cc019SAndroid Build Coastguard Worker if (!atomic) {
256*d83cc019SAndroid Build Coastguard Worker /* Schedule a nonblocking flip for the next vblank */
257*d83cc019SAndroid Build Coastguard Worker do {
258*d83cc019SAndroid Build Coastguard Worker ret = drmModePageFlip(display->drm_fd, pipe->crtc_id, fb->fb_id,
259*d83cc019SAndroid Build Coastguard Worker DRM_MODE_PAGE_FLIP_EVENT, data);
260*d83cc019SAndroid Build Coastguard Worker } while (ret == -EBUSY);
261*d83cc019SAndroid Build Coastguard Worker } else {
262*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(primary, fb);
263*d83cc019SAndroid Build Coastguard Worker do {
264*d83cc019SAndroid Build Coastguard Worker ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, data);
265*d83cc019SAndroid Build Coastguard Worker } while (ret == -EBUSY);
266*d83cc019SAndroid Build Coastguard Worker }
267*d83cc019SAndroid Build Coastguard Worker igt_assert(!ret);
268*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
269*d83cc019SAndroid Build Coastguard Worker }
270*d83cc019SAndroid Build Coastguard Worker
271*d83cc019SAndroid Build Coastguard Worker enum flip_test {
272*d83cc019SAndroid Build Coastguard Worker flip_test_legacy = 0,
273*d83cc019SAndroid Build Coastguard Worker flip_test_varying_size,
274*d83cc019SAndroid Build Coastguard Worker flip_test_toggle_visibility,
275*d83cc019SAndroid Build Coastguard Worker flip_test_atomic,
276*d83cc019SAndroid Build Coastguard Worker flip_test_atomic_transitions,
277*d83cc019SAndroid Build Coastguard Worker flip_test_atomic_transitions_varying_size,
278*d83cc019SAndroid Build Coastguard Worker flip_test_last = flip_test_atomic_transitions_varying_size
279*d83cc019SAndroid Build Coastguard Worker };
280*d83cc019SAndroid Build Coastguard Worker
cursor_slowpath(enum flip_test mode)281*d83cc019SAndroid Build Coastguard Worker static bool cursor_slowpath(enum flip_test mode)
282*d83cc019SAndroid Build Coastguard Worker {
283*d83cc019SAndroid Build Coastguard Worker /* cursor moving doesn't take slowpath, everything else does. */
284*d83cc019SAndroid Build Coastguard Worker if (mode == flip_test_legacy || mode == flip_test_atomic)
285*d83cc019SAndroid Build Coastguard Worker return false;
286*d83cc019SAndroid Build Coastguard Worker
287*d83cc019SAndroid Build Coastguard Worker return true;
288*d83cc019SAndroid Build Coastguard Worker }
289*d83cc019SAndroid Build Coastguard Worker
290*d83cc019SAndroid Build Coastguard Worker /*
291*d83cc019SAndroid Build Coastguard Worker * On platforms with two-stage watermark programming
292*d83cc019SAndroid Build Coastguard Worker * changing sprite visibility may require a extra vblank wait.
293*d83cc019SAndroid Build Coastguard Worker *
294*d83cc019SAndroid Build Coastguard Worker * Handle this here.
295*d83cc019SAndroid Build Coastguard Worker */
mode_requires_extra_vblank(enum flip_test mode)296*d83cc019SAndroid Build Coastguard Worker static bool mode_requires_extra_vblank(enum flip_test mode)
297*d83cc019SAndroid Build Coastguard Worker {
298*d83cc019SAndroid Build Coastguard Worker if (mode == flip_test_atomic_transitions ||
299*d83cc019SAndroid Build Coastguard Worker mode == flip_test_atomic_transitions_varying_size)
300*d83cc019SAndroid Build Coastguard Worker return true;
301*d83cc019SAndroid Build Coastguard Worker
302*d83cc019SAndroid Build Coastguard Worker return false;
303*d83cc019SAndroid Build Coastguard Worker }
304*d83cc019SAndroid Build Coastguard Worker
transition_nonblocking(igt_display_t * display,enum pipe pipe_id,struct igt_fb * prim_fb,struct igt_fb * argb_fb,bool hide_sprite)305*d83cc019SAndroid Build Coastguard Worker static void transition_nonblocking(igt_display_t *display, enum pipe pipe_id,
306*d83cc019SAndroid Build Coastguard Worker struct igt_fb *prim_fb, struct igt_fb *argb_fb,
307*d83cc019SAndroid Build Coastguard Worker bool hide_sprite)
308*d83cc019SAndroid Build Coastguard Worker {
309*d83cc019SAndroid Build Coastguard Worker igt_pipe_t *pipe = &display->pipes[pipe_id];
310*d83cc019SAndroid Build Coastguard Worker igt_plane_t *primary = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY);
311*d83cc019SAndroid Build Coastguard Worker igt_plane_t *sprite = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_OVERLAY);
312*d83cc019SAndroid Build Coastguard Worker
313*d83cc019SAndroid Build Coastguard Worker if (hide_sprite) {
314*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(primary, prim_fb);
315*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(sprite, NULL);
316*d83cc019SAndroid Build Coastguard Worker } else {
317*d83cc019SAndroid Build Coastguard Worker int ret;
318*d83cc019SAndroid Build Coastguard Worker
319*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(primary, NULL);
320*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(sprite, argb_fb);
321*d83cc019SAndroid Build Coastguard Worker
322*d83cc019SAndroid Build Coastguard Worker ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, display);
323*d83cc019SAndroid Build Coastguard Worker if (!ret)
324*d83cc019SAndroid Build Coastguard Worker return;
325*d83cc019SAndroid Build Coastguard Worker
326*d83cc019SAndroid Build Coastguard Worker igt_assert(ret == -EINVAL);
327*d83cc019SAndroid Build Coastguard Worker
328*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(sprite, prim_fb);
329*d83cc019SAndroid Build Coastguard Worker }
330*d83cc019SAndroid Build Coastguard Worker igt_display_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, display);
331*d83cc019SAndroid Build Coastguard Worker }
332*d83cc019SAndroid Build Coastguard Worker
prepare_flip_test(igt_display_t * display,enum flip_test mode,enum pipe flip_pipe,enum pipe cursor_pipe,struct drm_mode_cursor * arg,const struct igt_fb * prim_fb,struct igt_fb * argb_fb,struct igt_fb * cursor_fb2)333*d83cc019SAndroid Build Coastguard Worker static void prepare_flip_test(igt_display_t *display,
334*d83cc019SAndroid Build Coastguard Worker enum flip_test mode,
335*d83cc019SAndroid Build Coastguard Worker enum pipe flip_pipe,
336*d83cc019SAndroid Build Coastguard Worker enum pipe cursor_pipe,
337*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor *arg,
338*d83cc019SAndroid Build Coastguard Worker const struct igt_fb *prim_fb,
339*d83cc019SAndroid Build Coastguard Worker struct igt_fb *argb_fb,
340*d83cc019SAndroid Build Coastguard Worker struct igt_fb *cursor_fb2)
341*d83cc019SAndroid Build Coastguard Worker {
342*d83cc019SAndroid Build Coastguard Worker argb_fb->gem_handle = 0;
343*d83cc019SAndroid Build Coastguard Worker cursor_fb2->gem_handle = 0;
344*d83cc019SAndroid Build Coastguard Worker
345*d83cc019SAndroid Build Coastguard Worker if (mode == flip_test_varying_size ||
346*d83cc019SAndroid Build Coastguard Worker mode == flip_test_atomic_transitions_varying_size) {
347*d83cc019SAndroid Build Coastguard Worker uint64_t width, height;
348*d83cc019SAndroid Build Coastguard Worker
349*d83cc019SAndroid Build Coastguard Worker do_or_die(drmGetCap(display->drm_fd, DRM_CAP_CURSOR_WIDTH, &width));
350*d83cc019SAndroid Build Coastguard Worker do_or_die(drmGetCap(display->drm_fd, DRM_CAP_CURSOR_HEIGHT, &height));
351*d83cc019SAndroid Build Coastguard Worker
352*d83cc019SAndroid Build Coastguard Worker igt_skip_on(width <= 64 && height <= 64);
353*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, width, height,
354*d83cc019SAndroid Build Coastguard Worker DRM_FORMAT_ARGB8888, 0, 1., 0., .7, cursor_fb2);
355*d83cc019SAndroid Build Coastguard Worker
356*d83cc019SAndroid Build Coastguard Worker arg[0].flags = arg[1].flags = DRM_MODE_CURSOR_BO;
357*d83cc019SAndroid Build Coastguard Worker arg[1].handle = cursor_fb2->gem_handle;
358*d83cc019SAndroid Build Coastguard Worker arg[1].width = width;
359*d83cc019SAndroid Build Coastguard Worker arg[1].height = height;
360*d83cc019SAndroid Build Coastguard Worker }
361*d83cc019SAndroid Build Coastguard Worker
362*d83cc019SAndroid Build Coastguard Worker if (mode == flip_test_legacy ||
363*d83cc019SAndroid Build Coastguard Worker mode == flip_test_atomic) {
364*d83cc019SAndroid Build Coastguard Worker arg[1].x = 192;
365*d83cc019SAndroid Build Coastguard Worker arg[1].y = 192;
366*d83cc019SAndroid Build Coastguard Worker }
367*d83cc019SAndroid Build Coastguard Worker
368*d83cc019SAndroid Build Coastguard Worker if (mode == flip_test_toggle_visibility) {
369*d83cc019SAndroid Build Coastguard Worker arg[0].flags = arg[1].flags = DRM_MODE_CURSOR_BO;
370*d83cc019SAndroid Build Coastguard Worker arg[1].handle = 0;
371*d83cc019SAndroid Build Coastguard Worker arg[1].width = arg[1].height = 0;
372*d83cc019SAndroid Build Coastguard Worker }
373*d83cc019SAndroid Build Coastguard Worker
374*d83cc019SAndroid Build Coastguard Worker if (mode == flip_test_atomic_transitions ||
375*d83cc019SAndroid Build Coastguard Worker mode == flip_test_atomic_transitions_varying_size) {
376*d83cc019SAndroid Build Coastguard Worker igt_require(display->pipes[flip_pipe].n_planes > 1 &&
377*d83cc019SAndroid Build Coastguard Worker display->pipes[flip_pipe].planes[1].type != DRM_PLANE_TYPE_CURSOR);
378*d83cc019SAndroid Build Coastguard Worker
379*d83cc019SAndroid Build Coastguard Worker igt_create_color_pattern_fb(display->drm_fd, prim_fb->width, prim_fb->height,
380*d83cc019SAndroid Build Coastguard Worker DRM_FORMAT_ARGB8888, 0, .1, .1, .1, argb_fb);
381*d83cc019SAndroid Build Coastguard Worker }
382*d83cc019SAndroid Build Coastguard Worker }
383*d83cc019SAndroid Build Coastguard Worker
flip(igt_display_t * display,int cursor_pipe,int flip_pipe,int timeout,enum flip_test mode)384*d83cc019SAndroid Build Coastguard Worker static void flip(igt_display_t *display,
385*d83cc019SAndroid Build Coastguard Worker int cursor_pipe, int flip_pipe,
386*d83cc019SAndroid Build Coastguard Worker int timeout, enum flip_test mode)
387*d83cc019SAndroid Build Coastguard Worker {
388*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg[2];
389*d83cc019SAndroid Build Coastguard Worker uint64_t *results;
390*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info, fb_info2, argb_fb, cursor_fb, cursor_fb2;
391*d83cc019SAndroid Build Coastguard Worker
392*d83cc019SAndroid Build Coastguard Worker results = mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
393*d83cc019SAndroid Build Coastguard Worker igt_assert(results != MAP_FAILED);
394*d83cc019SAndroid Build Coastguard Worker
395*d83cc019SAndroid Build Coastguard Worker flip_pipe = find_connected_pipe(display, !!flip_pipe);
396*d83cc019SAndroid Build Coastguard Worker cursor_pipe = find_connected_pipe(display, !!cursor_pipe);
397*d83cc019SAndroid Build Coastguard Worker
398*d83cc019SAndroid Build Coastguard Worker igt_info("Using pipe %s for page flip, pipe %s for cursor\n",
399*d83cc019SAndroid Build Coastguard Worker kmstest_pipe_name(flip_pipe), kmstest_pipe_name(cursor_pipe));
400*d83cc019SAndroid Build Coastguard Worker
401*d83cc019SAndroid Build Coastguard Worker if (mode >= flip_test_atomic)
402*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
403*d83cc019SAndroid Build Coastguard Worker
404*d83cc019SAndroid Build Coastguard Worker igt_require(set_fb_on_crtc(display, flip_pipe, &fb_info));
405*d83cc019SAndroid Build Coastguard Worker if (flip_pipe != cursor_pipe)
406*d83cc019SAndroid Build Coastguard Worker igt_require(set_fb_on_crtc(display, cursor_pipe, &fb_info2));
407*d83cc019SAndroid Build Coastguard Worker
408*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, fb_info.width, fb_info.height, DRM_FORMAT_ARGB8888, 0, .5, .5, .5, &cursor_fb);
409*d83cc019SAndroid Build Coastguard Worker
410*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
411*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, cursor_pipe, &cursor_fb);
412*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, cursor_pipe, arg, &cursor_fb);
413*d83cc019SAndroid Build Coastguard Worker
414*d83cc019SAndroid Build Coastguard Worker prepare_flip_test(display, mode, flip_pipe, cursor_pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
415*d83cc019SAndroid Build Coastguard Worker
416*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
417*d83cc019SAndroid Build Coastguard Worker
418*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 1) {
419*d83cc019SAndroid Build Coastguard Worker unsigned long count = 0;
420*d83cc019SAndroid Build Coastguard Worker
421*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
422*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[(count & 64)/64]);
423*d83cc019SAndroid Build Coastguard Worker count++;
424*d83cc019SAndroid Build Coastguard Worker }
425*d83cc019SAndroid Build Coastguard Worker
426*d83cc019SAndroid Build Coastguard Worker igt_debug("cursor count=%lu\n", count);
427*d83cc019SAndroid Build Coastguard Worker results[0] = count;
428*d83cc019SAndroid Build Coastguard Worker }
429*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 1) {
430*d83cc019SAndroid Build Coastguard Worker unsigned long count = 0;
431*d83cc019SAndroid Build Coastguard Worker
432*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
433*d83cc019SAndroid Build Coastguard Worker char buf[128];
434*d83cc019SAndroid Build Coastguard Worker
435*d83cc019SAndroid Build Coastguard Worker switch (mode) {
436*d83cc019SAndroid Build Coastguard Worker default:
437*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, flip_pipe, mode >= flip_test_atomic, &fb_info, NULL);
438*d83cc019SAndroid Build Coastguard Worker break;
439*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions:
440*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions_varying_size:
441*d83cc019SAndroid Build Coastguard Worker transition_nonblocking(display, flip_pipe, &fb_info, &argb_fb, count & 1);
442*d83cc019SAndroid Build Coastguard Worker break;
443*d83cc019SAndroid Build Coastguard Worker }
444*d83cc019SAndroid Build Coastguard Worker
445*d83cc019SAndroid Build Coastguard Worker while (read(display->drm_fd, buf, sizeof(buf)) < 0 &&
446*d83cc019SAndroid Build Coastguard Worker (errno == EINTR || errno == EAGAIN))
447*d83cc019SAndroid Build Coastguard Worker ;
448*d83cc019SAndroid Build Coastguard Worker count++;
449*d83cc019SAndroid Build Coastguard Worker }
450*d83cc019SAndroid Build Coastguard Worker
451*d83cc019SAndroid Build Coastguard Worker igt_debug("flip count=%lu\n", count);
452*d83cc019SAndroid Build Coastguard Worker results[1] = count;
453*d83cc019SAndroid Build Coastguard Worker }
454*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
455*d83cc019SAndroid Build Coastguard Worker
456*d83cc019SAndroid Build Coastguard Worker munmap(results, PAGE_SIZE);
457*d83cc019SAndroid Build Coastguard Worker
458*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info);
459*d83cc019SAndroid Build Coastguard Worker if (flip_pipe != cursor_pipe)
460*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info2);
461*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
462*d83cc019SAndroid Build Coastguard Worker if (argb_fb.gem_handle)
463*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &argb_fb);
464*d83cc019SAndroid Build Coastguard Worker if (cursor_fb2.gem_handle)
465*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb2);
466*d83cc019SAndroid Build Coastguard Worker }
467*d83cc019SAndroid Build Coastguard Worker
pipe_select(enum pipe pipe)468*d83cc019SAndroid Build Coastguard Worker static inline uint32_t pipe_select(enum pipe pipe)
469*d83cc019SAndroid Build Coastguard Worker {
470*d83cc019SAndroid Build Coastguard Worker if (pipe > 1)
471*d83cc019SAndroid Build Coastguard Worker return pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
472*d83cc019SAndroid Build Coastguard Worker else if (pipe > 0)
473*d83cc019SAndroid Build Coastguard Worker return DRM_VBLANK_SECONDARY;
474*d83cc019SAndroid Build Coastguard Worker else
475*d83cc019SAndroid Build Coastguard Worker return 0;
476*d83cc019SAndroid Build Coastguard Worker }
477*d83cc019SAndroid Build Coastguard Worker
get_vblank(int fd,enum pipe pipe,unsigned flags)478*d83cc019SAndroid Build Coastguard Worker static unsigned get_vblank(int fd, enum pipe pipe, unsigned flags)
479*d83cc019SAndroid Build Coastguard Worker {
480*d83cc019SAndroid Build Coastguard Worker union drm_wait_vblank vbl;
481*d83cc019SAndroid Build Coastguard Worker
482*d83cc019SAndroid Build Coastguard Worker memset(&vbl, 0, sizeof(vbl));
483*d83cc019SAndroid Build Coastguard Worker vbl.request.type = DRM_VBLANK_RELATIVE | pipe_select(pipe) | flags;
484*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl))
485*d83cc019SAndroid Build Coastguard Worker return 0;
486*d83cc019SAndroid Build Coastguard Worker
487*d83cc019SAndroid Build Coastguard Worker return vbl.reply.sequence;
488*d83cc019SAndroid Build Coastguard Worker }
489*d83cc019SAndroid Build Coastguard Worker
490*d83cc019SAndroid Build Coastguard Worker enum basic_flip_cursor {
491*d83cc019SAndroid Build Coastguard Worker FLIP_BEFORE_CURSOR,
492*d83cc019SAndroid Build Coastguard Worker FLIP_AFTER_CURSOR
493*d83cc019SAndroid Build Coastguard Worker };
494*d83cc019SAndroid Build Coastguard Worker
495*d83cc019SAndroid Build Coastguard Worker #define BASIC_BUSY 0x1
496*d83cc019SAndroid Build Coastguard Worker
basic_flip_cursor(igt_display_t * display,enum flip_test mode,enum basic_flip_cursor order,unsigned flags)497*d83cc019SAndroid Build Coastguard Worker static void basic_flip_cursor(igt_display_t *display,
498*d83cc019SAndroid Build Coastguard Worker enum flip_test mode,
499*d83cc019SAndroid Build Coastguard Worker enum basic_flip_cursor order,
500*d83cc019SAndroid Build Coastguard Worker unsigned flags)
501*d83cc019SAndroid Build Coastguard Worker {
502*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg[2];
503*d83cc019SAndroid Build Coastguard Worker struct drm_event_vblank vbl;
504*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info, cursor_fb, cursor_fb2, argb_fb;
505*d83cc019SAndroid Build Coastguard Worker unsigned vblank_start;
506*d83cc019SAndroid Build Coastguard Worker enum pipe pipe = find_connected_pipe(display, false);
507*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin;
508*d83cc019SAndroid Build Coastguard Worker int i, miss1 = 0, miss2 = 0, delta;
509*d83cc019SAndroid Build Coastguard Worker
510*d83cc019SAndroid Build Coastguard Worker if (mode >= flip_test_atomic)
511*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
512*d83cc019SAndroid Build Coastguard Worker
513*d83cc019SAndroid Build Coastguard Worker igt_require(set_fb_on_crtc(display, pipe, &fb_info));
514*d83cc019SAndroid Build Coastguard Worker
515*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
516*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe, &cursor_fb);
517*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe, arg, &cursor_fb);
518*d83cc019SAndroid Build Coastguard Worker
519*d83cc019SAndroid Build Coastguard Worker prepare_flip_test(display, mode, pipe, pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
520*d83cc019SAndroid Build Coastguard Worker
521*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
522*d83cc019SAndroid Build Coastguard Worker
523*d83cc019SAndroid Build Coastguard Worker /* Quick sanity check that we can update a cursor in a single vblank */
524*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
525*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
526*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
527*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
528*d83cc019SAndroid Build Coastguard Worker
529*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 25; i++) {
530*d83cc019SAndroid Build Coastguard Worker bool miss;
531*d83cc019SAndroid Build Coastguard Worker
532*d83cc019SAndroid Build Coastguard Worker /* Bind the cursor first to warm up */
533*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
534*d83cc019SAndroid Build Coastguard Worker
535*d83cc019SAndroid Build Coastguard Worker spin = NULL;
536*d83cc019SAndroid Build Coastguard Worker if (flags & BASIC_BUSY)
537*d83cc019SAndroid Build Coastguard Worker spin = igt_spin_new(display->drm_fd,
538*d83cc019SAndroid Build Coastguard Worker .dependency = fb_info.gem_handle);
539*d83cc019SAndroid Build Coastguard Worker
540*d83cc019SAndroid Build Coastguard Worker /* Start with a synchronous query to align with the vblank */
541*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
542*d83cc019SAndroid Build Coastguard Worker
543*d83cc019SAndroid Build Coastguard Worker switch (order) {
544*d83cc019SAndroid Build Coastguard Worker case FLIP_BEFORE_CURSOR:
545*d83cc019SAndroid Build Coastguard Worker switch (mode) {
546*d83cc019SAndroid Build Coastguard Worker default:
547*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
548*d83cc019SAndroid Build Coastguard Worker break;
549*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions:
550*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions_varying_size:
551*d83cc019SAndroid Build Coastguard Worker transition_nonblocking(display, pipe, &fb_info, &argb_fb, 0);
552*d83cc019SAndroid Build Coastguard Worker break;
553*d83cc019SAndroid Build Coastguard Worker }
554*d83cc019SAndroid Build Coastguard Worker
555*d83cc019SAndroid Build Coastguard Worker delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
556*d83cc019SAndroid Build Coastguard Worker miss = delta != 0;
557*d83cc019SAndroid Build Coastguard Worker
558*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
559*d83cc019SAndroid Build Coastguard Worker break;
560*d83cc019SAndroid Build Coastguard Worker
561*d83cc019SAndroid Build Coastguard Worker case FLIP_AFTER_CURSOR:
562*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
563*d83cc019SAndroid Build Coastguard Worker
564*d83cc019SAndroid Build Coastguard Worker delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
565*d83cc019SAndroid Build Coastguard Worker miss = delta != 0;
566*d83cc019SAndroid Build Coastguard Worker
567*d83cc019SAndroid Build Coastguard Worker switch (mode) {
568*d83cc019SAndroid Build Coastguard Worker default:
569*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
570*d83cc019SAndroid Build Coastguard Worker break;
571*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions:
572*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions_varying_size:
573*d83cc019SAndroid Build Coastguard Worker transition_nonblocking(display, pipe, &fb_info, &argb_fb, 0);
574*d83cc019SAndroid Build Coastguard Worker break;
575*d83cc019SAndroid Build Coastguard Worker }
576*d83cc019SAndroid Build Coastguard Worker }
577*d83cc019SAndroid Build Coastguard Worker
578*d83cc019SAndroid Build Coastguard Worker delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
579*d83cc019SAndroid Build Coastguard Worker
580*d83cc019SAndroid Build Coastguard Worker if (spin) {
581*d83cc019SAndroid Build Coastguard Worker struct pollfd pfd = { display->drm_fd, POLLIN };
582*d83cc019SAndroid Build Coastguard Worker igt_assert(poll(&pfd, 1, 0) == 0);
583*d83cc019SAndroid Build Coastguard Worker igt_spin_free(display->drm_fd, spin);
584*d83cc019SAndroid Build Coastguard Worker }
585*d83cc019SAndroid Build Coastguard Worker
586*d83cc019SAndroid Build Coastguard Worker if (miss)
587*d83cc019SAndroid Build Coastguard Worker { /* compare nothing, already failed */ }
588*d83cc019SAndroid Build Coastguard Worker else if (!cursor_slowpath(mode))
589*d83cc019SAndroid Build Coastguard Worker miss = delta != 0;
590*d83cc019SAndroid Build Coastguard Worker else
591*d83cc019SAndroid Build Coastguard Worker miss = delta != 0 && delta != 1;
592*d83cc019SAndroid Build Coastguard Worker
593*d83cc019SAndroid Build Coastguard Worker miss1 += miss;
594*d83cc019SAndroid Build Coastguard Worker
595*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Stuck page flip");
596*d83cc019SAndroid Build Coastguard Worker igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
597*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
598*d83cc019SAndroid Build Coastguard Worker
599*d83cc019SAndroid Build Coastguard Worker if (miss1)
600*d83cc019SAndroid Build Coastguard Worker continue;
601*d83cc019SAndroid Build Coastguard Worker
602*d83cc019SAndroid Build Coastguard Worker delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
603*d83cc019SAndroid Build Coastguard Worker
604*d83cc019SAndroid Build Coastguard Worker if (!mode_requires_extra_vblank(mode))
605*d83cc019SAndroid Build Coastguard Worker miss2 += delta != 1;
606*d83cc019SAndroid Build Coastguard Worker else
607*d83cc019SAndroid Build Coastguard Worker miss2 += delta != 1 && delta != 2;
608*d83cc019SAndroid Build Coastguard Worker }
609*d83cc019SAndroid Build Coastguard Worker
610*d83cc019SAndroid Build Coastguard Worker igt_fail_on_f(miss1 > 2 || miss1 + miss2 > 5, "Failed to evade %i vblanks and missed %i page flips\n", miss1, miss2);
611*d83cc019SAndroid Build Coastguard Worker if (miss1 || miss2)
612*d83cc019SAndroid Build Coastguard Worker igt_info("Failed to evade %i vblanks and missed %i page flips\n", miss1, miss2);
613*d83cc019SAndroid Build Coastguard Worker
614*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info);
615*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
616*d83cc019SAndroid Build Coastguard Worker
617*d83cc019SAndroid Build Coastguard Worker if (argb_fb.gem_handle)
618*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &argb_fb);
619*d83cc019SAndroid Build Coastguard Worker if (cursor_fb2.gem_handle)
620*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb2);
621*d83cc019SAndroid Build Coastguard Worker }
622*d83cc019SAndroid Build Coastguard Worker
623*d83cc019SAndroid Build Coastguard Worker static int
get_cursor_updates_per_vblank(igt_display_t * display,enum pipe pipe,struct drm_mode_cursor * arg)624*d83cc019SAndroid Build Coastguard Worker get_cursor_updates_per_vblank(igt_display_t *display, enum pipe pipe,
625*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor *arg)
626*d83cc019SAndroid Build Coastguard Worker {
627*d83cc019SAndroid Build Coastguard Worker int target;
628*d83cc019SAndroid Build Coastguard Worker
629*d83cc019SAndroid Build Coastguard Worker for (target = 65536; target; target /= 2) {
630*d83cc019SAndroid Build Coastguard Worker unsigned vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
631*d83cc019SAndroid Build Coastguard Worker
632*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
633*d83cc019SAndroid Build Coastguard Worker
634*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < target; n++)
635*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, arg);
636*d83cc019SAndroid Build Coastguard Worker if (get_vblank(display->drm_fd, pipe, 0) == vblank_start)
637*d83cc019SAndroid Build Coastguard Worker break;
638*d83cc019SAndroid Build Coastguard Worker }
639*d83cc019SAndroid Build Coastguard Worker
640*d83cc019SAndroid Build Coastguard Worker /*
641*d83cc019SAndroid Build Coastguard Worker * Divide by 4, to handle variations in amount of vblanks
642*d83cc019SAndroid Build Coastguard Worker * caused by cpufreq throttling.
643*d83cc019SAndroid Build Coastguard Worker */
644*d83cc019SAndroid Build Coastguard Worker target /= 4;
645*d83cc019SAndroid Build Coastguard Worker igt_require(target > 1);
646*d83cc019SAndroid Build Coastguard Worker
647*d83cc019SAndroid Build Coastguard Worker igt_info("Using a target of %d cursor updates per quarter-vblank\n", target);
648*d83cc019SAndroid Build Coastguard Worker
649*d83cc019SAndroid Build Coastguard Worker return target;
650*d83cc019SAndroid Build Coastguard Worker }
651*d83cc019SAndroid Build Coastguard Worker
flip_vs_cursor(igt_display_t * display,enum flip_test mode,int nloops)652*d83cc019SAndroid Build Coastguard Worker static void flip_vs_cursor(igt_display_t *display, enum flip_test mode, int nloops)
653*d83cc019SAndroid Build Coastguard Worker {
654*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg[2];
655*d83cc019SAndroid Build Coastguard Worker struct drm_event_vblank vbl;
656*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info, cursor_fb, cursor_fb2, argb_fb;
657*d83cc019SAndroid Build Coastguard Worker unsigned vblank_start;
658*d83cc019SAndroid Build Coastguard Worker int target, cpu;
659*d83cc019SAndroid Build Coastguard Worker enum pipe pipe = find_connected_pipe(display, false);
660*d83cc019SAndroid Build Coastguard Worker volatile unsigned long *shared;
661*d83cc019SAndroid Build Coastguard Worker cpu_set_t mask, oldmask;
662*d83cc019SAndroid Build Coastguard Worker
663*d83cc019SAndroid Build Coastguard Worker if (mode >= flip_test_atomic)
664*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
665*d83cc019SAndroid Build Coastguard Worker
666*d83cc019SAndroid Build Coastguard Worker igt_require(set_fb_on_crtc(display, pipe, &fb_info));
667*d83cc019SAndroid Build Coastguard Worker
668*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
669*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe, &cursor_fb);
670*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe, arg, &cursor_fb);
671*d83cc019SAndroid Build Coastguard Worker
672*d83cc019SAndroid Build Coastguard Worker prepare_flip_test(display, mode, pipe, pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
673*d83cc019SAndroid Build Coastguard Worker
674*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
675*d83cc019SAndroid Build Coastguard Worker
676*d83cc019SAndroid Build Coastguard Worker if (nloops)
677*d83cc019SAndroid Build Coastguard Worker target = get_cursor_updates_per_vblank(display, pipe, &arg[0]);
678*d83cc019SAndroid Build Coastguard Worker else
679*d83cc019SAndroid Build Coastguard Worker target = 1;
680*d83cc019SAndroid Build Coastguard Worker
681*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
682*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
683*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < target; n++)
684*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
685*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
686*d83cc019SAndroid Build Coastguard Worker
687*d83cc019SAndroid Build Coastguard Worker /*
688*d83cc019SAndroid Build Coastguard Worker * There are variations caused by using cpu frequency changing. To
689*d83cc019SAndroid Build Coastguard Worker * eliminate those we force this test to run on the same cpu as an
690*d83cc019SAndroid Build Coastguard Worker * idle thread that does a busy loop of sched_yield(); The effect is
691*d83cc019SAndroid Build Coastguard Worker * that we don't throttle the cpu to a lower frequency, and the
692*d83cc019SAndroid Build Coastguard Worker * variations caused by cpu speed changing are eliminated.
693*d83cc019SAndroid Build Coastguard Worker */
694*d83cc019SAndroid Build Coastguard Worker if (target > 1) {
695*d83cc019SAndroid Build Coastguard Worker shared = mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
696*d83cc019SAndroid Build Coastguard Worker igt_assert(shared != MAP_FAILED);
697*d83cc019SAndroid Build Coastguard Worker
698*d83cc019SAndroid Build Coastguard Worker cpu = sched_getcpu();
699*d83cc019SAndroid Build Coastguard Worker igt_assert(cpu >= 0);
700*d83cc019SAndroid Build Coastguard Worker
701*d83cc019SAndroid Build Coastguard Worker CPU_ZERO(&mask);
702*d83cc019SAndroid Build Coastguard Worker CPU_SET(cpu, &mask);
703*d83cc019SAndroid Build Coastguard Worker sched_getaffinity(0, sizeof(oldmask), &oldmask);
704*d83cc019SAndroid Build Coastguard Worker sched_setaffinity(0, sizeof(mask), &mask);
705*d83cc019SAndroid Build Coastguard Worker
706*d83cc019SAndroid Build Coastguard Worker shared[0] = 0;
707*d83cc019SAndroid Build Coastguard Worker
708*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 1) {
709*d83cc019SAndroid Build Coastguard Worker struct sched_param parm = { .sched_priority = 0 };
710*d83cc019SAndroid Build Coastguard Worker
711*d83cc019SAndroid Build Coastguard Worker igt_assert(sched_setscheduler(0, SCHED_IDLE, &parm) == 0);
712*d83cc019SAndroid Build Coastguard Worker
713*d83cc019SAndroid Build Coastguard Worker while (!shared[0])
714*d83cc019SAndroid Build Coastguard Worker sched_yield();
715*d83cc019SAndroid Build Coastguard Worker }
716*d83cc019SAndroid Build Coastguard Worker }
717*d83cc019SAndroid Build Coastguard Worker
718*d83cc019SAndroid Build Coastguard Worker do {
719*d83cc019SAndroid Build Coastguard Worker /* Bind the cursor first to warm up */
720*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
721*d83cc019SAndroid Build Coastguard Worker
722*d83cc019SAndroid Build Coastguard Worker /* Start with a synchronous query to align with the vblank */
723*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
724*d83cc019SAndroid Build Coastguard Worker switch (mode) {
725*d83cc019SAndroid Build Coastguard Worker default:
726*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
727*d83cc019SAndroid Build Coastguard Worker break;
728*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions:
729*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions_varying_size:
730*d83cc019SAndroid Build Coastguard Worker transition_nonblocking(display, pipe, &fb_info, &argb_fb, (nloops & 2) /2);
731*d83cc019SAndroid Build Coastguard Worker break;
732*d83cc019SAndroid Build Coastguard Worker }
733*d83cc019SAndroid Build Coastguard Worker
734*d83cc019SAndroid Build Coastguard Worker /* The nonblocking flip should not have delayed us */
735*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
736*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < target; n++)
737*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
738*d83cc019SAndroid Build Coastguard Worker
739*d83cc019SAndroid Build Coastguard Worker /* Nor should it have delayed the following cursor update */
740*d83cc019SAndroid Build Coastguard Worker if (!cursor_slowpath(mode))
741*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
742*d83cc019SAndroid Build Coastguard Worker else
743*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
744*d83cc019SAndroid Build Coastguard Worker
745*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Stuck page flip");
746*d83cc019SAndroid Build Coastguard Worker igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
747*d83cc019SAndroid Build Coastguard Worker
748*d83cc019SAndroid Build Coastguard Worker if (!mode_requires_extra_vblank(mode))
749*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
750*d83cc019SAndroid Build Coastguard Worker else
751*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(get_vblank(display->drm_fd, pipe, 0), vblank_start + 2);
752*d83cc019SAndroid Build Coastguard Worker
753*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
754*d83cc019SAndroid Build Coastguard Worker } while (nloops--);
755*d83cc019SAndroid Build Coastguard Worker
756*d83cc019SAndroid Build Coastguard Worker if (target > 1) {
757*d83cc019SAndroid Build Coastguard Worker shared[0] = 1;
758*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
759*d83cc019SAndroid Build Coastguard Worker munmap((void *)shared, PAGE_SIZE);
760*d83cc019SAndroid Build Coastguard Worker sched_setaffinity(0, sizeof(oldmask), &oldmask);
761*d83cc019SAndroid Build Coastguard Worker }
762*d83cc019SAndroid Build Coastguard Worker
763*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info);
764*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
765*d83cc019SAndroid Build Coastguard Worker
766*d83cc019SAndroid Build Coastguard Worker if (argb_fb.gem_handle)
767*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &argb_fb);
768*d83cc019SAndroid Build Coastguard Worker if (cursor_fb2.gem_handle)
769*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb2);
770*d83cc019SAndroid Build Coastguard Worker }
771*d83cc019SAndroid Build Coastguard Worker
nonblocking_modeset_vs_cursor(igt_display_t * display,int loops)772*d83cc019SAndroid Build Coastguard Worker static void nonblocking_modeset_vs_cursor(igt_display_t *display, int loops)
773*d83cc019SAndroid Build Coastguard Worker {
774*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info, cursor_fb;
775*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
776*d83cc019SAndroid Build Coastguard Worker enum pipe pipe = find_connected_pipe(display, false);
777*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg[2];
778*d83cc019SAndroid Build Coastguard Worker igt_plane_t *cursor = NULL, *plane;
779*d83cc019SAndroid Build Coastguard Worker
780*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
781*d83cc019SAndroid Build Coastguard Worker igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
782*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
783*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe, &cursor_fb);
784*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe, arg, &cursor_fb);
785*d83cc019SAndroid Build Coastguard Worker arg[0].flags |= DRM_MODE_CURSOR_BO;
786*d83cc019SAndroid Build Coastguard Worker
787*d83cc019SAndroid Build Coastguard Worker for_each_plane_on_pipe(display, pipe, plane) {
788*d83cc019SAndroid Build Coastguard Worker if (plane->type != DRM_PLANE_TYPE_CURSOR)
789*d83cc019SAndroid Build Coastguard Worker continue;
790*d83cc019SAndroid Build Coastguard Worker
791*d83cc019SAndroid Build Coastguard Worker cursor = plane;
792*d83cc019SAndroid Build Coastguard Worker break;
793*d83cc019SAndroid Build Coastguard Worker }
794*d83cc019SAndroid Build Coastguard Worker
795*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!cursor);
796*d83cc019SAndroid Build Coastguard Worker
797*d83cc019SAndroid Build Coastguard Worker /*
798*d83cc019SAndroid Build Coastguard Worker * Start disabled. No way around it, since the first atomic
799*d83cc019SAndroid Build Coastguard Worker * commit may be unreliable with amount of events sent.
800*d83cc019SAndroid Build Coastguard Worker */
801*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output, PIPE_NONE);
802*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, COMMIT_ATOMIC);
803*d83cc019SAndroid Build Coastguard Worker
804*d83cc019SAndroid Build Coastguard Worker while (loops--) {
805*d83cc019SAndroid Build Coastguard Worker unsigned flags;
806*d83cc019SAndroid Build Coastguard Worker struct pollfd pfd = { display->drm_fd, POLLIN };
807*d83cc019SAndroid Build Coastguard Worker struct drm_event_vblank vbl;
808*d83cc019SAndroid Build Coastguard Worker
809*d83cc019SAndroid Build Coastguard Worker flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
810*d83cc019SAndroid Build Coastguard Worker flags |= DRM_MODE_ATOMIC_NONBLOCK;
811*d83cc019SAndroid Build Coastguard Worker flags |= DRM_MODE_PAGE_FLIP_EVENT;
812*d83cc019SAndroid Build Coastguard Worker
813*d83cc019SAndroid Build Coastguard Worker /*
814*d83cc019SAndroid Build Coastguard Worker * Test that a cursor update after a nonblocking modeset
815*d83cc019SAndroid Build Coastguard Worker * works as intended. It should block until the modeset completes.
816*d83cc019SAndroid Build Coastguard Worker */
817*d83cc019SAndroid Build Coastguard Worker
818*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output, pipe);
819*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(cursor, NULL);
820*d83cc019SAndroid Build Coastguard Worker igt_display_commit_atomic(display, flags, NULL);
821*d83cc019SAndroid Build Coastguard Worker
822*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(0, poll(&pfd, 1, 0));
823*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(0, pfd.revents);
824*d83cc019SAndroid Build Coastguard Worker
825*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
826*d83cc019SAndroid Build Coastguard Worker
827*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(1, poll(&pfd, 1, 0));
828*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(POLLIN, pfd.revents);
829*d83cc019SAndroid Build Coastguard Worker
830*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Stuck page flip");
831*d83cc019SAndroid Build Coastguard Worker igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
832*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
833*d83cc019SAndroid Build Coastguard Worker
834*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output, PIPE_NONE);
835*d83cc019SAndroid Build Coastguard Worker igt_display_commit_atomic(display, flags, NULL);
836*d83cc019SAndroid Build Coastguard Worker
837*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(0, poll(&pfd, 1, 0));
838*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(0, pfd.revents);
839*d83cc019SAndroid Build Coastguard Worker
840*d83cc019SAndroid Build Coastguard Worker /* Same for cursor on disabled crtc. */
841*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
842*d83cc019SAndroid Build Coastguard Worker
843*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(1, poll(&pfd, 1, 0));
844*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(POLLIN, pfd.revents);
845*d83cc019SAndroid Build Coastguard Worker
846*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Stuck page flip");
847*d83cc019SAndroid Build Coastguard Worker igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
848*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
849*d83cc019SAndroid Build Coastguard Worker }
850*d83cc019SAndroid Build Coastguard Worker
851*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info);
852*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
853*d83cc019SAndroid Build Coastguard Worker }
854*d83cc019SAndroid Build Coastguard Worker
two_screens_flip_vs_cursor(igt_display_t * display,int nloops,bool modeset,bool atomic)855*d83cc019SAndroid Build Coastguard Worker static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool modeset, bool atomic)
856*d83cc019SAndroid Build Coastguard Worker {
857*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg1[2], arg2[2];
858*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info, fb2_info, cursor_fb;
859*d83cc019SAndroid Build Coastguard Worker enum pipe pipe = find_connected_pipe(display, false);
860*d83cc019SAndroid Build Coastguard Worker enum pipe pipe2 = find_connected_pipe(display, true);
861*d83cc019SAndroid Build Coastguard Worker igt_output_t *output, *output2;
862*d83cc019SAndroid Build Coastguard Worker bool enabled = false;
863*d83cc019SAndroid Build Coastguard Worker volatile unsigned long *shared;
864*d83cc019SAndroid Build Coastguard Worker unsigned flags = 0, vblank_start;
865*d83cc019SAndroid Build Coastguard Worker struct drm_event_vblank vbl;
866*d83cc019SAndroid Build Coastguard Worker int ret;
867*d83cc019SAndroid Build Coastguard Worker
868*d83cc019SAndroid Build Coastguard Worker if (modeset) {
869*d83cc019SAndroid Build Coastguard Worker uint64_t val;
870*d83cc019SAndroid Build Coastguard Worker
871*d83cc019SAndroid Build Coastguard Worker igt_fail_on(!atomic);
872*d83cc019SAndroid Build Coastguard Worker igt_require(drmGetCap(display->drm_fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &val) == 0);
873*d83cc019SAndroid Build Coastguard Worker }
874*d83cc019SAndroid Build Coastguard Worker
875*d83cc019SAndroid Build Coastguard Worker shared = mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
876*d83cc019SAndroid Build Coastguard Worker igt_assert(shared != MAP_FAILED);
877*d83cc019SAndroid Build Coastguard Worker
878*d83cc019SAndroid Build Coastguard Worker igt_fail_on(modeset && !atomic);
879*d83cc019SAndroid Build Coastguard Worker
880*d83cc019SAndroid Build Coastguard Worker if (atomic)
881*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
882*d83cc019SAndroid Build Coastguard Worker
883*d83cc019SAndroid Build Coastguard Worker igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
884*d83cc019SAndroid Build Coastguard Worker igt_require((output2 = set_fb_on_crtc(display, pipe2, &fb2_info)));
885*d83cc019SAndroid Build Coastguard Worker
886*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
887*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe, &cursor_fb);
888*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe, arg1, &cursor_fb);
889*d83cc019SAndroid Build Coastguard Worker
890*d83cc019SAndroid Build Coastguard Worker arg1[1].x = arg1[1].y = 192;
891*d83cc019SAndroid Build Coastguard Worker
892*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe2, &cursor_fb);
893*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe2, arg2, &cursor_fb);
894*d83cc019SAndroid Build Coastguard Worker
895*d83cc019SAndroid Build Coastguard Worker arg2[1].x = arg2[1].y = 192;
896*d83cc019SAndroid Build Coastguard Worker
897*d83cc019SAndroid Build Coastguard Worker
898*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
899*d83cc019SAndroid Build Coastguard Worker
900*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 2) {
901*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor *arg = child ? arg2 : arg1;
902*d83cc019SAndroid Build Coastguard Worker
903*d83cc019SAndroid Build Coastguard Worker while (!shared[0])
904*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR,
905*d83cc019SAndroid Build Coastguard Worker &arg[!shared[1]]);
906*d83cc019SAndroid Build Coastguard Worker }
907*d83cc019SAndroid Build Coastguard Worker
908*d83cc019SAndroid Build Coastguard Worker if (modeset) {
909*d83cc019SAndroid Build Coastguard Worker igt_plane_t *plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
910*d83cc019SAndroid Build Coastguard Worker
911*d83cc019SAndroid Build Coastguard Worker flags = DRM_MODE_ATOMIC_ALLOW_MODESET |
912*d83cc019SAndroid Build Coastguard Worker DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
913*d83cc019SAndroid Build Coastguard Worker
914*d83cc019SAndroid Build Coastguard Worker /* Disable pipe2 */
915*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output2, PIPE_NONE);
916*d83cc019SAndroid Build Coastguard Worker igt_display_commit_atomic(display, flags, NULL);
917*d83cc019SAndroid Build Coastguard Worker enabled = false;
918*d83cc019SAndroid Build Coastguard Worker
919*d83cc019SAndroid Build Coastguard Worker /*
920*d83cc019SAndroid Build Coastguard Worker * Try a page flip on crtc 1, if we succeed pump page flips and
921*d83cc019SAndroid Build Coastguard Worker * modesets interleaved, else do a single atomic commit with both.
922*d83cc019SAndroid Build Coastguard Worker */
923*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
924*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(plane, &fb_info);
925*d83cc019SAndroid Build Coastguard Worker ret = igt_display_try_commit_atomic(display, flags, (void*)(ptrdiff_t)vblank_start);
926*d83cc019SAndroid Build Coastguard Worker igt_assert(!ret || ret == -EBUSY);
927*d83cc019SAndroid Build Coastguard Worker
928*d83cc019SAndroid Build Coastguard Worker if (ret == -EBUSY) {
929*d83cc019SAndroid Build Coastguard Worker /* Force completion on both pipes, and generate event. */
930*d83cc019SAndroid Build Coastguard Worker igt_display_commit_atomic(display, flags, NULL);
931*d83cc019SAndroid Build Coastguard Worker
932*d83cc019SAndroid Build Coastguard Worker while (nloops--) {
933*d83cc019SAndroid Build Coastguard Worker shared[1] = nloops & 1;
934*d83cc019SAndroid Build Coastguard Worker
935*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(35, "Stuck modeset");
936*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
937*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
938*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
939*d83cc019SAndroid Build Coastguard Worker
940*d83cc019SAndroid Build Coastguard Worker if (!nloops)
941*d83cc019SAndroid Build Coastguard Worker break;
942*d83cc019SAndroid Build Coastguard Worker
943*d83cc019SAndroid Build Coastguard Worker /* Commit page flip and modeset simultaneously. */
944*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(plane, &fb_info);
945*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output2, enabled ? PIPE_NONE : pipe2);
946*d83cc019SAndroid Build Coastguard Worker enabled = !enabled;
947*d83cc019SAndroid Build Coastguard Worker
948*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(5, "Scheduling modeset\n");
949*d83cc019SAndroid Build Coastguard Worker do {
950*d83cc019SAndroid Build Coastguard Worker ret = igt_display_try_commit_atomic(display, flags, NULL);
951*d83cc019SAndroid Build Coastguard Worker } while (ret == -EBUSY);
952*d83cc019SAndroid Build Coastguard Worker igt_assert(!ret);
953*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
954*d83cc019SAndroid Build Coastguard Worker }
955*d83cc019SAndroid Build Coastguard Worker
956*d83cc019SAndroid Build Coastguard Worker goto done;
957*d83cc019SAndroid Build Coastguard Worker }
958*d83cc019SAndroid Build Coastguard Worker } else {
959*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
960*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, atomic, &fb_info, (void*)(ptrdiff_t)vblank_start);
961*d83cc019SAndroid Build Coastguard Worker
962*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe2, DRM_VBLANK_NEXTONMISS);
963*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe2, atomic, &fb2_info, (void*)(ptrdiff_t)vblank_start);
964*d83cc019SAndroid Build Coastguard Worker }
965*d83cc019SAndroid Build Coastguard Worker
966*d83cc019SAndroid Build Coastguard Worker while (nloops) {
967*d83cc019SAndroid Build Coastguard Worker shared[1] = nloops & 1;
968*d83cc019SAndroid Build Coastguard Worker
969*d83cc019SAndroid Build Coastguard Worker if (!modeset || nloops > 1)
970*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Stuck page flip");
971*d83cc019SAndroid Build Coastguard Worker else
972*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(35, "Stuck modeset");
973*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
974*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
975*d83cc019SAndroid Build Coastguard Worker
976*d83cc019SAndroid Build Coastguard Worker vblank_start = vbl.user_data;
977*d83cc019SAndroid Build Coastguard Worker if (!modeset)
978*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(vbl.sequence, vblank_start + 1);
979*d83cc019SAndroid Build Coastguard Worker
980*d83cc019SAndroid Build Coastguard Worker /* Do not requeue on the last 2 events. */
981*d83cc019SAndroid Build Coastguard Worker if (nloops <= 2) {
982*d83cc019SAndroid Build Coastguard Worker nloops--;
983*d83cc019SAndroid Build Coastguard Worker continue;
984*d83cc019SAndroid Build Coastguard Worker }
985*d83cc019SAndroid Build Coastguard Worker
986*d83cc019SAndroid Build Coastguard Worker if (vbl.crtc_id == display->pipes[pipe].crtc_id) {
987*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
988*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, atomic, &fb_info, (void*)(ptrdiff_t)vblank_start);
989*d83cc019SAndroid Build Coastguard Worker } else {
990*d83cc019SAndroid Build Coastguard Worker igt_assert(vbl.crtc_id == display->pipes[pipe2].crtc_id);
991*d83cc019SAndroid Build Coastguard Worker
992*d83cc019SAndroid Build Coastguard Worker nloops--;
993*d83cc019SAndroid Build Coastguard Worker
994*d83cc019SAndroid Build Coastguard Worker if (!modeset) {
995*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe2, DRM_VBLANK_NEXTONMISS);
996*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe2, atomic, &fb2_info, (void*)(ptrdiff_t)vblank_start);
997*d83cc019SAndroid Build Coastguard Worker } else {
998*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output2, enabled ? PIPE_NONE : pipe2);
999*d83cc019SAndroid Build Coastguard Worker
1000*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Scheduling modeset\n");
1001*d83cc019SAndroid Build Coastguard Worker do {
1002*d83cc019SAndroid Build Coastguard Worker ret = igt_display_try_commit_atomic(display, flags, NULL);
1003*d83cc019SAndroid Build Coastguard Worker } while (ret == -EBUSY);
1004*d83cc019SAndroid Build Coastguard Worker igt_assert(!ret);
1005*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
1006*d83cc019SAndroid Build Coastguard Worker
1007*d83cc019SAndroid Build Coastguard Worker enabled = !enabled;
1008*d83cc019SAndroid Build Coastguard Worker }
1009*d83cc019SAndroid Build Coastguard Worker }
1010*d83cc019SAndroid Build Coastguard Worker }
1011*d83cc019SAndroid Build Coastguard Worker
1012*d83cc019SAndroid Build Coastguard Worker done:
1013*d83cc019SAndroid Build Coastguard Worker shared[0] = 1;
1014*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
1015*d83cc019SAndroid Build Coastguard Worker
1016*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info);
1017*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb2_info);
1018*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
1019*d83cc019SAndroid Build Coastguard Worker munmap((void *)shared, PAGE_SIZE);
1020*d83cc019SAndroid Build Coastguard Worker }
1021*d83cc019SAndroid Build Coastguard Worker
cursor_vs_flip(igt_display_t * display,enum flip_test mode,int nloops)1022*d83cc019SAndroid Build Coastguard Worker static void cursor_vs_flip(igt_display_t *display, enum flip_test mode, int nloops)
1023*d83cc019SAndroid Build Coastguard Worker {
1024*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg[2];
1025*d83cc019SAndroid Build Coastguard Worker struct drm_event_vblank vbl;
1026*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info, cursor_fb, cursor_fb2, argb_fb;
1027*d83cc019SAndroid Build Coastguard Worker unsigned vblank_start, vblank_last;
1028*d83cc019SAndroid Build Coastguard Worker volatile unsigned long *shared;
1029*d83cc019SAndroid Build Coastguard Worker long target;
1030*d83cc019SAndroid Build Coastguard Worker enum pipe pipe = find_connected_pipe(display, false);
1031*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
1032*d83cc019SAndroid Build Coastguard Worker uint32_t vrefresh;
1033*d83cc019SAndroid Build Coastguard Worker int fail_count;
1034*d83cc019SAndroid Build Coastguard Worker
1035*d83cc019SAndroid Build Coastguard Worker if (mode >= flip_test_atomic)
1036*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
1037*d83cc019SAndroid Build Coastguard Worker
1038*d83cc019SAndroid Build Coastguard Worker shared = mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
1039*d83cc019SAndroid Build Coastguard Worker igt_assert(shared != MAP_FAILED);
1040*d83cc019SAndroid Build Coastguard Worker
1041*d83cc019SAndroid Build Coastguard Worker igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
1042*d83cc019SAndroid Build Coastguard Worker vrefresh = igt_output_get_mode(output)->vrefresh;
1043*d83cc019SAndroid Build Coastguard Worker
1044*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
1045*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe, &cursor_fb);
1046*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe, arg, &cursor_fb);
1047*d83cc019SAndroid Build Coastguard Worker
1048*d83cc019SAndroid Build Coastguard Worker prepare_flip_test(display, mode, pipe, pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
1049*d83cc019SAndroid Build Coastguard Worker
1050*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1051*d83cc019SAndroid Build Coastguard Worker
1052*d83cc019SAndroid Build Coastguard Worker target = get_cursor_updates_per_vblank(display, pipe, &arg[0]);
1053*d83cc019SAndroid Build Coastguard Worker
1054*d83cc019SAndroid Build Coastguard Worker fail_count = 0;
1055*d83cc019SAndroid Build Coastguard Worker
1056*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < nloops; i++) {
1057*d83cc019SAndroid Build Coastguard Worker shared[0] = 0;
1058*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 1) {
1059*d83cc019SAndroid Build Coastguard Worker unsigned long count = 0;
1060*d83cc019SAndroid Build Coastguard Worker while (!shared[0]) {
1061*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i & 1]);
1062*d83cc019SAndroid Build Coastguard Worker count++;
1063*d83cc019SAndroid Build Coastguard Worker }
1064*d83cc019SAndroid Build Coastguard Worker igt_debug("child: %lu cursor updates\n", count);
1065*d83cc019SAndroid Build Coastguard Worker shared[0] = count;
1066*d83cc019SAndroid Build Coastguard Worker }
1067*d83cc019SAndroid Build Coastguard Worker
1068*d83cc019SAndroid Build Coastguard Worker switch (mode) {
1069*d83cc019SAndroid Build Coastguard Worker default:
1070*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
1071*d83cc019SAndroid Build Coastguard Worker break;
1072*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions:
1073*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic_transitions_varying_size:
1074*d83cc019SAndroid Build Coastguard Worker transition_nonblocking(display, pipe, &fb_info, &argb_fb, (i & 2) >> 1);
1075*d83cc019SAndroid Build Coastguard Worker break;
1076*d83cc019SAndroid Build Coastguard Worker }
1077*d83cc019SAndroid Build Coastguard Worker
1078*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
1079*d83cc019SAndroid Build Coastguard Worker vblank_start = vblank_last = vbl.sequence;
1080*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < vrefresh / 2; n++) {
1081*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
1082*d83cc019SAndroid Build Coastguard Worker
1083*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
1084*d83cc019SAndroid Build Coastguard Worker if (vbl.sequence != vblank_last + 1) {
1085*d83cc019SAndroid Build Coastguard Worker igt_info("page flip %d was delayed, missed %d frames\n",
1086*d83cc019SAndroid Build Coastguard Worker n, vbl.sequence - vblank_last - 1);
1087*d83cc019SAndroid Build Coastguard Worker }
1088*d83cc019SAndroid Build Coastguard Worker vblank_last = vbl.sequence;
1089*d83cc019SAndroid Build Coastguard Worker }
1090*d83cc019SAndroid Build Coastguard Worker
1091*d83cc019SAndroid Build Coastguard Worker if (!cursor_slowpath(mode))
1092*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(vbl.sequence, vblank_start + 5 * vrefresh / 8);
1093*d83cc019SAndroid Build Coastguard Worker
1094*d83cc019SAndroid Build Coastguard Worker shared[0] = 1;
1095*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
1096*d83cc019SAndroid Build Coastguard Worker if (shared[0] <= vrefresh*target / 2) {
1097*d83cc019SAndroid Build Coastguard Worker fail_count++;
1098*d83cc019SAndroid Build Coastguard Worker igt_critical("completed %lu cursor updated in a period of %u flips, "
1099*d83cc019SAndroid Build Coastguard Worker "we expect to complete approximately %lu updates, "
1100*d83cc019SAndroid Build Coastguard Worker "with the threshold set at %lu\n",
1101*d83cc019SAndroid Build Coastguard Worker shared[0], vrefresh / 2,
1102*d83cc019SAndroid Build Coastguard Worker vrefresh*target, vrefresh*target / 2);
1103*d83cc019SAndroid Build Coastguard Worker }
1104*d83cc019SAndroid Build Coastguard Worker }
1105*d83cc019SAndroid Build Coastguard Worker
1106*d83cc019SAndroid Build Coastguard Worker igt_assert_f(fail_count == 0,
1107*d83cc019SAndroid Build Coastguard Worker "Failed to meet cursor update expectations in %d out of %d iterations\n",
1108*d83cc019SAndroid Build Coastguard Worker fail_count, nloops);
1109*d83cc019SAndroid Build Coastguard Worker
1110*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info);
1111*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
1112*d83cc019SAndroid Build Coastguard Worker munmap((void *)shared, PAGE_SIZE);
1113*d83cc019SAndroid Build Coastguard Worker if (argb_fb.gem_handle)
1114*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &argb_fb);
1115*d83cc019SAndroid Build Coastguard Worker if (cursor_fb2.gem_handle)
1116*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb2);
1117*d83cc019SAndroid Build Coastguard Worker }
1118*d83cc019SAndroid Build Coastguard Worker
two_screens_cursor_vs_flip(igt_display_t * display,int nloops,bool atomic)1119*d83cc019SAndroid Build Coastguard Worker static void two_screens_cursor_vs_flip(igt_display_t *display, int nloops, bool atomic)
1120*d83cc019SAndroid Build Coastguard Worker {
1121*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg[2][2];
1122*d83cc019SAndroid Build Coastguard Worker struct drm_event_vblank vbl;
1123*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info[2], cursor_fb;
1124*d83cc019SAndroid Build Coastguard Worker volatile unsigned long *shared;
1125*d83cc019SAndroid Build Coastguard Worker int target[2];
1126*d83cc019SAndroid Build Coastguard Worker enum pipe pipe[2] = {
1127*d83cc019SAndroid Build Coastguard Worker find_connected_pipe(display, false),
1128*d83cc019SAndroid Build Coastguard Worker find_connected_pipe(display, true)
1129*d83cc019SAndroid Build Coastguard Worker };
1130*d83cc019SAndroid Build Coastguard Worker igt_output_t *outputs[2];
1131*d83cc019SAndroid Build Coastguard Worker
1132*d83cc019SAndroid Build Coastguard Worker shared = mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
1133*d83cc019SAndroid Build Coastguard Worker igt_assert(shared != MAP_FAILED);
1134*d83cc019SAndroid Build Coastguard Worker
1135*d83cc019SAndroid Build Coastguard Worker if (atomic)
1136*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
1137*d83cc019SAndroid Build Coastguard Worker
1138*d83cc019SAndroid Build Coastguard Worker igt_require((outputs[0] = set_fb_on_crtc(display, pipe[0], &fb_info[0])));
1139*d83cc019SAndroid Build Coastguard Worker igt_require((outputs[1] = set_fb_on_crtc(display, pipe[1], &fb_info[1])));
1140*d83cc019SAndroid Build Coastguard Worker
1141*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
1142*d83cc019SAndroid Build Coastguard Worker
1143*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe[0], &cursor_fb);
1144*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe[0], arg[0], &cursor_fb);
1145*d83cc019SAndroid Build Coastguard Worker arg[0][1].x = arg[0][1].y = 192;
1146*d83cc019SAndroid Build Coastguard Worker
1147*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe[1], &cursor_fb);
1148*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe[1], arg[1], &cursor_fb);
1149*d83cc019SAndroid Build Coastguard Worker arg[1][1].x = arg[1][1].y = 192;
1150*d83cc019SAndroid Build Coastguard Worker
1151*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1152*d83cc019SAndroid Build Coastguard Worker
1153*d83cc019SAndroid Build Coastguard Worker target[0] = get_cursor_updates_per_vblank(display, pipe[0], &arg[0][0]);
1154*d83cc019SAndroid Build Coastguard Worker target[1] = get_cursor_updates_per_vblank(display, pipe[1], &arg[1][0]);
1155*d83cc019SAndroid Build Coastguard Worker
1156*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < nloops; i++) {
1157*d83cc019SAndroid Build Coastguard Worker unsigned long vrefresh[2];
1158*d83cc019SAndroid Build Coastguard Worker unsigned vblank_start[2], vblank_last[2];
1159*d83cc019SAndroid Build Coastguard Worker int done[2] = {};
1160*d83cc019SAndroid Build Coastguard Worker
1161*d83cc019SAndroid Build Coastguard Worker vrefresh[0] = igt_output_get_mode(outputs[0])->vrefresh;
1162*d83cc019SAndroid Build Coastguard Worker vrefresh[1] = igt_output_get_mode(outputs[1])->vrefresh;
1163*d83cc019SAndroid Build Coastguard Worker
1164*d83cc019SAndroid Build Coastguard Worker shared[0] = 0;
1165*d83cc019SAndroid Build Coastguard Worker shared[1] = 0;
1166*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 2) {
1167*d83cc019SAndroid Build Coastguard Worker unsigned long count = 0;
1168*d83cc019SAndroid Build Coastguard Worker
1169*d83cc019SAndroid Build Coastguard Worker while (!shared[child]) {
1170*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[child][(i >> child) & 1]);
1171*d83cc019SAndroid Build Coastguard Worker count++;
1172*d83cc019SAndroid Build Coastguard Worker }
1173*d83cc019SAndroid Build Coastguard Worker igt_debug("child %i: %lu cursor updates\n", child, count);
1174*d83cc019SAndroid Build Coastguard Worker shared[child] = count;
1175*d83cc019SAndroid Build Coastguard Worker }
1176*d83cc019SAndroid Build Coastguard Worker
1177*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe[0], atomic, &fb_info[0], (void *)0UL);
1178*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe[1], atomic, &fb_info[1], (void *)1UL);
1179*d83cc019SAndroid Build Coastguard Worker
1180*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < vrefresh[0] / 2 + vrefresh[1] / 2; n++) {
1181*d83cc019SAndroid Build Coastguard Worker unsigned long child;
1182*d83cc019SAndroid Build Coastguard Worker
1183*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
1184*d83cc019SAndroid Build Coastguard Worker child = vbl.user_data;
1185*d83cc019SAndroid Build Coastguard Worker
1186*d83cc019SAndroid Build Coastguard Worker if (!done[child]++)
1187*d83cc019SAndroid Build Coastguard Worker vblank_start[child] = vbl.sequence;
1188*d83cc019SAndroid Build Coastguard Worker else if (vbl.sequence != vblank_last[child] + 1)
1189*d83cc019SAndroid Build Coastguard Worker igt_info("page flip %d was delayed, missed %d frames\n",
1190*d83cc019SAndroid Build Coastguard Worker done[child], vbl.sequence - vblank_last[child] - 1);
1191*d83cc019SAndroid Build Coastguard Worker
1192*d83cc019SAndroid Build Coastguard Worker vblank_last[child] = vbl.sequence;
1193*d83cc019SAndroid Build Coastguard Worker
1194*d83cc019SAndroid Build Coastguard Worker if (done[child] < vrefresh[child] / 2) {
1195*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe[child], atomic, &fb_info[child], (void *)child);
1196*d83cc019SAndroid Build Coastguard Worker } else {
1197*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(vbl.sequence, vblank_start[child] + 5 * vrefresh[child] / 8);
1198*d83cc019SAndroid Build Coastguard Worker
1199*d83cc019SAndroid Build Coastguard Worker shared[child] = 1;
1200*d83cc019SAndroid Build Coastguard Worker }
1201*d83cc019SAndroid Build Coastguard Worker }
1202*d83cc019SAndroid Build Coastguard Worker
1203*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(done[0], vrefresh[0] / 2);
1204*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(done[1], vrefresh[1] / 2);
1205*d83cc019SAndroid Build Coastguard Worker
1206*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
1207*d83cc019SAndroid Build Coastguard Worker for (int child = 0; child < 2; child++)
1208*d83cc019SAndroid Build Coastguard Worker igt_assert_f(shared[child] > vrefresh[child]*target[child] / 2,
1209*d83cc019SAndroid Build Coastguard Worker "completed %lu cursor updated in a period of %lu flips, "
1210*d83cc019SAndroid Build Coastguard Worker "we expect to complete approximately %lu updates, "
1211*d83cc019SAndroid Build Coastguard Worker "with the threshold set at %lu\n",
1212*d83cc019SAndroid Build Coastguard Worker shared[child], vrefresh[child] / 2,
1213*d83cc019SAndroid Build Coastguard Worker vrefresh[child]*target[child], vrefresh[child]*target[child] / 2);
1214*d83cc019SAndroid Build Coastguard Worker }
1215*d83cc019SAndroid Build Coastguard Worker
1216*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info[0]);
1217*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info[1]);
1218*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
1219*d83cc019SAndroid Build Coastguard Worker munmap((void *)shared, PAGE_SIZE);
1220*d83cc019SAndroid Build Coastguard Worker }
1221*d83cc019SAndroid Build Coastguard Worker
flip_vs_cursor_crc(igt_display_t * display,bool atomic)1222*d83cc019SAndroid Build Coastguard Worker static void flip_vs_cursor_crc(igt_display_t *display, bool atomic)
1223*d83cc019SAndroid Build Coastguard Worker {
1224*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg[2];
1225*d83cc019SAndroid Build Coastguard Worker struct drm_event_vblank vbl;
1226*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info, cursor_fb;
1227*d83cc019SAndroid Build Coastguard Worker unsigned vblank_start;
1228*d83cc019SAndroid Build Coastguard Worker enum pipe pipe = find_connected_pipe(display, false);
1229*d83cc019SAndroid Build Coastguard Worker igt_crc_t crcs[3];
1230*d83cc019SAndroid Build Coastguard Worker
1231*d83cc019SAndroid Build Coastguard Worker if (atomic)
1232*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
1233*d83cc019SAndroid Build Coastguard Worker
1234*d83cc019SAndroid Build Coastguard Worker igt_require(set_fb_on_crtc(display, pipe, &fb_info));
1235*d83cc019SAndroid Build Coastguard Worker
1236*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
1237*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe, arg, &cursor_fb);
1238*d83cc019SAndroid Build Coastguard Worker
1239*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1240*d83cc019SAndroid Build Coastguard Worker
1241*d83cc019SAndroid Build Coastguard Worker pipe_crc = igt_pipe_crc_new(display->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
1242*d83cc019SAndroid Build Coastguard Worker
1243*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe, &cursor_fb);
1244*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, COMMIT_UNIVERSAL);
1245*d83cc019SAndroid Build Coastguard Worker
1246*d83cc019SAndroid Build Coastguard Worker /* Collect reference crcs, crcs[0] last. */
1247*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[1]);
1248*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_collect_crc(pipe_crc, &crcs[1]);
1249*d83cc019SAndroid Build Coastguard Worker
1250*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
1251*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_collect_crc(pipe_crc, &crcs[0]);
1252*d83cc019SAndroid Build Coastguard Worker
1253*d83cc019SAndroid Build Coastguard Worker /* Disable cursor, and immediately queue a flip. Check if resulting crc is correct. */
1254*d83cc019SAndroid Build Coastguard Worker for (int i = 1; i >= 0; i--) {
1255*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
1256*d83cc019SAndroid Build Coastguard Worker
1257*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, atomic, &fb_info, NULL);
1258*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i]);
1259*d83cc019SAndroid Build Coastguard Worker
1260*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
1261*d83cc019SAndroid Build Coastguard Worker
1262*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Stuck page flip");
1263*d83cc019SAndroid Build Coastguard Worker igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
1264*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
1265*d83cc019SAndroid Build Coastguard Worker
1266*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
1267*d83cc019SAndroid Build Coastguard Worker
1268*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_collect_crc(pipe_crc, &crcs[2]);
1269*d83cc019SAndroid Build Coastguard Worker
1270*d83cc019SAndroid Build Coastguard Worker igt_assert_crc_equal(&crcs[i], &crcs[2]);
1271*d83cc019SAndroid Build Coastguard Worker }
1272*d83cc019SAndroid Build Coastguard Worker
1273*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info);
1274*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
1275*d83cc019SAndroid Build Coastguard Worker }
1276*d83cc019SAndroid Build Coastguard Worker
flip_vs_cursor_busy_crc(igt_display_t * display,bool atomic)1277*d83cc019SAndroid Build Coastguard Worker static void flip_vs_cursor_busy_crc(igt_display_t *display, bool atomic)
1278*d83cc019SAndroid Build Coastguard Worker {
1279*d83cc019SAndroid Build Coastguard Worker struct drm_mode_cursor arg[2];
1280*d83cc019SAndroid Build Coastguard Worker struct drm_event_vblank vbl;
1281*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb_info[2], cursor_fb;
1282*d83cc019SAndroid Build Coastguard Worker unsigned vblank_start;
1283*d83cc019SAndroid Build Coastguard Worker enum pipe pipe = find_connected_pipe(display, false);
1284*d83cc019SAndroid Build Coastguard Worker igt_pipe_t *pipe_connected = &display->pipes[pipe];
1285*d83cc019SAndroid Build Coastguard Worker igt_plane_t *plane_primary = igt_pipe_get_plane_type(pipe_connected, DRM_PLANE_TYPE_PRIMARY);
1286*d83cc019SAndroid Build Coastguard Worker igt_crc_t crcs[2], test_crc;
1287*d83cc019SAndroid Build Coastguard Worker
1288*d83cc019SAndroid Build Coastguard Worker if (atomic)
1289*d83cc019SAndroid Build Coastguard Worker igt_require(display->is_atomic);
1290*d83cc019SAndroid Build Coastguard Worker
1291*d83cc019SAndroid Build Coastguard Worker igt_require(set_fb_on_crtc(display, pipe, &fb_info[0]));
1292*d83cc019SAndroid Build Coastguard Worker igt_create_color_pattern_fb(display->drm_fd, fb_info[0].width, fb_info[0].height,
1293*d83cc019SAndroid Build Coastguard Worker DRM_FORMAT_XRGB8888, LOCAL_I915_FORMAT_MOD_X_TILED, .1, .1, .1, &fb_info[1]);
1294*d83cc019SAndroid Build Coastguard Worker
1295*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
1296*d83cc019SAndroid Build Coastguard Worker populate_cursor_args(display, pipe, arg, &cursor_fb);
1297*d83cc019SAndroid Build Coastguard Worker
1298*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1299*d83cc019SAndroid Build Coastguard Worker
1300*d83cc019SAndroid Build Coastguard Worker pipe_crc = igt_pipe_crc_new(display->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
1301*d83cc019SAndroid Build Coastguard Worker
1302*d83cc019SAndroid Build Coastguard Worker set_cursor_on_pipe(display, pipe, &cursor_fb);
1303*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, COMMIT_UNIVERSAL);
1304*d83cc019SAndroid Build Coastguard Worker
1305*d83cc019SAndroid Build Coastguard Worker /* Collect reference crcs, crc[0] last for the loop. */
1306*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[1]);
1307*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_collect_crc(pipe_crc, &crcs[1]);
1308*d83cc019SAndroid Build Coastguard Worker
1309*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
1310*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_collect_crc(pipe_crc, &crcs[0]);
1311*d83cc019SAndroid Build Coastguard Worker
1312*d83cc019SAndroid Build Coastguard Worker /*
1313*d83cc019SAndroid Build Coastguard Worker * Set fb 1 on primary at least once before flipping to force
1314*d83cc019SAndroid Build Coastguard Worker * setting the correct cache level, else we get a stall in the
1315*d83cc019SAndroid Build Coastguard Worker * page flip handler.
1316*d83cc019SAndroid Build Coastguard Worker */
1317*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(plane_primary, &fb_info[1]);
1318*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, COMMIT_UNIVERSAL);
1319*d83cc019SAndroid Build Coastguard Worker
1320*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(plane_primary, &fb_info[0]);
1321*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, COMMIT_UNIVERSAL);
1322*d83cc019SAndroid Build Coastguard Worker
1323*d83cc019SAndroid Build Coastguard Worker /*
1324*d83cc019SAndroid Build Coastguard Worker * We must enable CRC collecting here since this may force
1325*d83cc019SAndroid Build Coastguard Worker * a modeset, and this loop is timing sensitive.
1326*d83cc019SAndroid Build Coastguard Worker */
1327*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_start(pipe_crc);
1328*d83cc019SAndroid Build Coastguard Worker
1329*d83cc019SAndroid Build Coastguard Worker /* Disable cursor, and immediately queue a flip. Check if resulting crc is correct. */
1330*d83cc019SAndroid Build Coastguard Worker for (int i = 1; i >= 0; i--) {
1331*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin;
1332*d83cc019SAndroid Build Coastguard Worker
1333*d83cc019SAndroid Build Coastguard Worker spin = igt_spin_new(display->drm_fd,
1334*d83cc019SAndroid Build Coastguard Worker .dependency = fb_info[1].gem_handle);
1335*d83cc019SAndroid Build Coastguard Worker
1336*d83cc019SAndroid Build Coastguard Worker vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
1337*d83cc019SAndroid Build Coastguard Worker
1338*d83cc019SAndroid Build Coastguard Worker flip_nonblocking(display, pipe, atomic, &fb_info[1], NULL);
1339*d83cc019SAndroid Build Coastguard Worker do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i]);
1340*d83cc019SAndroid Build Coastguard Worker
1341*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
1342*d83cc019SAndroid Build Coastguard Worker
1343*d83cc019SAndroid Build Coastguard Worker igt_pipe_crc_get_current(display->drm_fd, pipe_crc, &test_crc);
1344*d83cc019SAndroid Build Coastguard Worker
1345*d83cc019SAndroid Build Coastguard Worker igt_spin_free(display->drm_fd, spin);
1346*d83cc019SAndroid Build Coastguard Worker
1347*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "Stuck page flip");
1348*d83cc019SAndroid Build Coastguard Worker igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
1349*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
1350*d83cc019SAndroid Build Coastguard Worker
1351*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(vblank_start + 1, get_vblank(display->drm_fd, pipe, 0));
1352*d83cc019SAndroid Build Coastguard Worker
1353*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(plane_primary, &fb_info[0]);
1354*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, COMMIT_UNIVERSAL);
1355*d83cc019SAndroid Build Coastguard Worker
1356*d83cc019SAndroid Build Coastguard Worker igt_assert_crc_equal(&crcs[i], &test_crc);
1357*d83cc019SAndroid Build Coastguard Worker }
1358*d83cc019SAndroid Build Coastguard Worker
1359*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info[1]);
1360*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &fb_info[0]);
1361*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, &cursor_fb);
1362*d83cc019SAndroid Build Coastguard Worker }
1363*d83cc019SAndroid Build Coastguard Worker
1364*d83cc019SAndroid Build Coastguard Worker igt_main
1365*d83cc019SAndroid Build Coastguard Worker {
1366*d83cc019SAndroid Build Coastguard Worker const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
1367*d83cc019SAndroid Build Coastguard Worker igt_display_t display = { .drm_fd = -1 };
1368*d83cc019SAndroid Build Coastguard Worker int i;
1369*d83cc019SAndroid Build Coastguard Worker
1370*d83cc019SAndroid Build Coastguard Worker igt_fixture {
1371*d83cc019SAndroid Build Coastguard Worker display.drm_fd = drm_open_driver_master(DRIVER_ANY);
1372*d83cc019SAndroid Build Coastguard Worker kmstest_set_vt_graphics_mode();
1373*d83cc019SAndroid Build Coastguard Worker
1374*d83cc019SAndroid Build Coastguard Worker igt_display_require(&display, display.drm_fd);
1375*d83cc019SAndroid Build Coastguard Worker }
1376*d83cc019SAndroid Build Coastguard Worker
1377*d83cc019SAndroid Build Coastguard Worker igt_subtest_group {
1378*d83cc019SAndroid Build Coastguard Worker enum pipe n;
for_each_pipe_static(n)1379*d83cc019SAndroid Build Coastguard Worker for_each_pipe_static(n) {
1380*d83cc019SAndroid Build Coastguard Worker errno = 0;
1381*d83cc019SAndroid Build Coastguard Worker
1382*d83cc019SAndroid Build Coastguard Worker igt_fixture {
1383*d83cc019SAndroid Build Coastguard Worker igt_skip_on(n >= display.n_pipes);
1384*d83cc019SAndroid Build Coastguard Worker }
1385*d83cc019SAndroid Build Coastguard Worker
1386*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("pipe-%s-single-bo", kmstest_pipe_name(n))
1387*d83cc019SAndroid Build Coastguard Worker stress(&display, n, 1, DRM_MODE_CURSOR_BO, 20);
1388*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("pipe-%s-single-move", kmstest_pipe_name(n))
1389*d83cc019SAndroid Build Coastguard Worker stress(&display, n, 1, DRM_MODE_CURSOR_MOVE, 20);
1390*d83cc019SAndroid Build Coastguard Worker
1391*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("pipe-%s-forked-bo", kmstest_pipe_name(n))
1392*d83cc019SAndroid Build Coastguard Worker stress(&display, n, ncpus, DRM_MODE_CURSOR_BO, 20);
1393*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("pipe-%s-forked-move", kmstest_pipe_name(n))
1394*d83cc019SAndroid Build Coastguard Worker stress(&display, n, ncpus, DRM_MODE_CURSOR_MOVE, 20);
1395*d83cc019SAndroid Build Coastguard Worker
1396*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("pipe-%s-torture-bo", kmstest_pipe_name(n))
1397*d83cc019SAndroid Build Coastguard Worker stress(&display, n, -ncpus, DRM_MODE_CURSOR_BO, 20);
1398*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("pipe-%s-torture-move", kmstest_pipe_name(n))
1399*d83cc019SAndroid Build Coastguard Worker stress(&display, n, -ncpus, DRM_MODE_CURSOR_MOVE, 20);
1400*d83cc019SAndroid Build Coastguard Worker }
1401*d83cc019SAndroid Build Coastguard Worker }
1402*d83cc019SAndroid Build Coastguard Worker
1403*d83cc019SAndroid Build Coastguard Worker igt_subtest("all-pipes-single-bo")
1404*d83cc019SAndroid Build Coastguard Worker stress(&display, -1, 1, DRM_MODE_CURSOR_BO, 20);
1405*d83cc019SAndroid Build Coastguard Worker igt_subtest("all-pipes-single-move")
1406*d83cc019SAndroid Build Coastguard Worker stress(&display, -1, 1, DRM_MODE_CURSOR_MOVE, 20);
1407*d83cc019SAndroid Build Coastguard Worker
1408*d83cc019SAndroid Build Coastguard Worker igt_subtest("all-pipes-forked-bo")
1409*d83cc019SAndroid Build Coastguard Worker stress(&display, -1, ncpus, DRM_MODE_CURSOR_BO, 20);
1410*d83cc019SAndroid Build Coastguard Worker igt_subtest("all-pipes-forked-move")
1411*d83cc019SAndroid Build Coastguard Worker stress(&display, -1, ncpus, DRM_MODE_CURSOR_MOVE, 20);
1412*d83cc019SAndroid Build Coastguard Worker
1413*d83cc019SAndroid Build Coastguard Worker igt_subtest("all-pipes-torture-bo")
1414*d83cc019SAndroid Build Coastguard Worker stress(&display, -1, -ncpus, DRM_MODE_CURSOR_BO, 20);
1415*d83cc019SAndroid Build Coastguard Worker igt_subtest("all-pipes-torture-move")
1416*d83cc019SAndroid Build Coastguard Worker stress(&display, -1, -ncpus, DRM_MODE_CURSOR_MOVE, 20);
1417*d83cc019SAndroid Build Coastguard Worker
1418*d83cc019SAndroid Build Coastguard Worker igt_subtest("nonblocking-modeset-vs-cursor-atomic")
1419*d83cc019SAndroid Build Coastguard Worker nonblocking_modeset_vs_cursor(&display, 1);
1420*d83cc019SAndroid Build Coastguard Worker
1421*d83cc019SAndroid Build Coastguard Worker igt_subtest("long-nonblocking-modeset-vs-cursor-atomic")
1422*d83cc019SAndroid Build Coastguard Worker nonblocking_modeset_vs_cursor(&display, 16);
1423*d83cc019SAndroid Build Coastguard Worker
1424*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-flip-vs-cursor-legacy")
1425*d83cc019SAndroid Build Coastguard Worker two_screens_flip_vs_cursor(&display, 8, false, false);
1426*d83cc019SAndroid Build Coastguard Worker
1427*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-flip-vs-cursor-atomic")
1428*d83cc019SAndroid Build Coastguard Worker two_screens_flip_vs_cursor(&display, 8, false, true);
1429*d83cc019SAndroid Build Coastguard Worker
1430*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-cursor-vs-flip-legacy")
1431*d83cc019SAndroid Build Coastguard Worker two_screens_cursor_vs_flip(&display, 8, false);
1432*d83cc019SAndroid Build Coastguard Worker
1433*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-long-flip-vs-cursor-legacy")
1434*d83cc019SAndroid Build Coastguard Worker two_screens_flip_vs_cursor(&display, 150, false, false);
1435*d83cc019SAndroid Build Coastguard Worker
1436*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-long-flip-vs-cursor-atomic")
1437*d83cc019SAndroid Build Coastguard Worker two_screens_flip_vs_cursor(&display, 150, false, true);
1438*d83cc019SAndroid Build Coastguard Worker
1439*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-long-cursor-vs-flip-legacy")
1440*d83cc019SAndroid Build Coastguard Worker two_screens_cursor_vs_flip(&display, 50, false);
1441*d83cc019SAndroid Build Coastguard Worker
1442*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-nonblocking-modeset-vs-cursor-atomic")
1443*d83cc019SAndroid Build Coastguard Worker two_screens_flip_vs_cursor(&display, 4, true, true);
1444*d83cc019SAndroid Build Coastguard Worker
1445*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-cursor-vs-flip-atomic")
1446*d83cc019SAndroid Build Coastguard Worker two_screens_cursor_vs_flip(&display, 8, true);
1447*d83cc019SAndroid Build Coastguard Worker
1448*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-long-nonblocking-modeset-vs-cursor-atomic")
1449*d83cc019SAndroid Build Coastguard Worker two_screens_flip_vs_cursor(&display, 15, true, true);
1450*d83cc019SAndroid Build Coastguard Worker
1451*d83cc019SAndroid Build Coastguard Worker igt_subtest("2x-long-cursor-vs-flip-atomic")
1452*d83cc019SAndroid Build Coastguard Worker two_screens_cursor_vs_flip(&display, 50, true);
1453*d83cc019SAndroid Build Coastguard Worker
1454*d83cc019SAndroid Build Coastguard Worker igt_subtest("flip-vs-cursor-crc-legacy")
1455*d83cc019SAndroid Build Coastguard Worker flip_vs_cursor_crc(&display, false);
1456*d83cc019SAndroid Build Coastguard Worker
1457*d83cc019SAndroid Build Coastguard Worker igt_subtest("flip-vs-cursor-crc-atomic")
1458*d83cc019SAndroid Build Coastguard Worker flip_vs_cursor_crc(&display, true);
1459*d83cc019SAndroid Build Coastguard Worker
1460*d83cc019SAndroid Build Coastguard Worker igt_subtest("flip-vs-cursor-busy-crc-legacy")
1461*d83cc019SAndroid Build Coastguard Worker flip_vs_cursor_busy_crc(&display, false);
1462*d83cc019SAndroid Build Coastguard Worker
1463*d83cc019SAndroid Build Coastguard Worker igt_subtest("flip-vs-cursor-busy-crc-atomic")
1464*d83cc019SAndroid Build Coastguard Worker flip_vs_cursor_busy_crc(&display, true);
1465*d83cc019SAndroid Build Coastguard Worker
1466*d83cc019SAndroid Build Coastguard Worker for (i = 0; i <= flip_test_last; i++) {
1467*d83cc019SAndroid Build Coastguard Worker const char *modes[flip_test_last+1] = {
1468*d83cc019SAndroid Build Coastguard Worker "legacy",
1469*d83cc019SAndroid Build Coastguard Worker "varying-size",
1470*d83cc019SAndroid Build Coastguard Worker "toggle",
1471*d83cc019SAndroid Build Coastguard Worker "atomic",
1472*d83cc019SAndroid Build Coastguard Worker "atomic-transitions",
1473*d83cc019SAndroid Build Coastguard Worker "atomic-transitions-varying-size"
1474*d83cc019SAndroid Build Coastguard Worker };
1475*d83cc019SAndroid Build Coastguard Worker const char *prefix = "short-";
1476*d83cc019SAndroid Build Coastguard Worker
1477*d83cc019SAndroid Build Coastguard Worker switch (i) {
1478*d83cc019SAndroid Build Coastguard Worker case flip_test_legacy:
1479*d83cc019SAndroid Build Coastguard Worker case flip_test_varying_size:
1480*d83cc019SAndroid Build Coastguard Worker case flip_test_atomic:
1481*d83cc019SAndroid Build Coastguard Worker prefix = "basic-";
1482*d83cc019SAndroid Build Coastguard Worker break;
1483*d83cc019SAndroid Build Coastguard Worker default: break;
1484*d83cc019SAndroid Build Coastguard Worker }
1485*d83cc019SAndroid Build Coastguard Worker
1486*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%sflip-before-cursor-%s", prefix, modes[i])
1487*d83cc019SAndroid Build Coastguard Worker basic_flip_cursor(&display, i, FLIP_BEFORE_CURSOR, 0);
1488*d83cc019SAndroid Build Coastguard Worker
1489*d83cc019SAndroid Build Coastguard Worker if (!cursor_slowpath(i)) {
1490*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%sbusy-flip-before-cursor-%s", prefix, modes[i]) {
1491*d83cc019SAndroid Build Coastguard Worker igt_require_gem(display.drm_fd);
1492*d83cc019SAndroid Build Coastguard Worker basic_flip_cursor(&display, i, FLIP_BEFORE_CURSOR,
1493*d83cc019SAndroid Build Coastguard Worker BASIC_BUSY);
1494*d83cc019SAndroid Build Coastguard Worker }
1495*d83cc019SAndroid Build Coastguard Worker }
1496*d83cc019SAndroid Build Coastguard Worker
1497*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%sflip-after-cursor-%s", prefix, modes[i])
1498*d83cc019SAndroid Build Coastguard Worker basic_flip_cursor(&display, i, FLIP_AFTER_CURSOR, 0);
1499*d83cc019SAndroid Build Coastguard Worker
1500*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("flip-vs-cursor-%s", modes[i])
1501*d83cc019SAndroid Build Coastguard Worker flip_vs_cursor(&display, i, 150);
1502*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("cursor-vs-flip-%s", modes[i])
1503*d83cc019SAndroid Build Coastguard Worker cursor_vs_flip(&display, i, 50);
1504*d83cc019SAndroid Build Coastguard Worker
1505*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("cursorA-vs-flipA-%s", modes[i])
1506*d83cc019SAndroid Build Coastguard Worker flip(&display, 0, 0, 10, i);
1507*d83cc019SAndroid Build Coastguard Worker
1508*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("cursorA-vs-flipB-%s", modes[i])
1509*d83cc019SAndroid Build Coastguard Worker flip(&display, 0, 1, 10, i);
1510*d83cc019SAndroid Build Coastguard Worker
1511*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("cursorB-vs-flipA-%s", modes[i])
1512*d83cc019SAndroid Build Coastguard Worker flip(&display, 1, 0, 10, i);
1513*d83cc019SAndroid Build Coastguard Worker
1514*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("cursorB-vs-flipB-%s", modes[i])
1515*d83cc019SAndroid Build Coastguard Worker flip(&display, 1, 1, 10, i);
1516*d83cc019SAndroid Build Coastguard Worker }
1517*d83cc019SAndroid Build Coastguard Worker
1518*d83cc019SAndroid Build Coastguard Worker igt_fixture {
1519*d83cc019SAndroid Build Coastguard Worker igt_display_fini(&display);
1520*d83cc019SAndroid Build Coastguard Worker }
1521*d83cc019SAndroid Build Coastguard Worker }
1522