1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2017 Keith Packard
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 /** @file kms_lease.c
25*d83cc019SAndroid Build Coastguard Worker *
26*d83cc019SAndroid Build Coastguard Worker * This is a test of DRM leases
27*d83cc019SAndroid Build Coastguard Worker */
28*d83cc019SAndroid Build Coastguard Worker
29*d83cc019SAndroid Build Coastguard Worker
30*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
31*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
32*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
33*d83cc019SAndroid Build Coastguard Worker #include <string.h>
34*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
35*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
36*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
37*d83cc019SAndroid Build Coastguard Worker #include <time.h>
38*d83cc019SAndroid Build Coastguard Worker #include <sys/poll.h>
39*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
40*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
41*d83cc019SAndroid Build Coastguard Worker #include <sys/wait.h>
42*d83cc019SAndroid Build Coastguard Worker
43*d83cc019SAndroid Build Coastguard Worker #include <libudev.h>
44*d83cc019SAndroid Build Coastguard Worker
45*d83cc019SAndroid Build Coastguard Worker #include <drm.h>
46*d83cc019SAndroid Build Coastguard Worker #include "igt_device.h"
47*d83cc019SAndroid Build Coastguard Worker
48*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Test of CreateLease.");
49*d83cc019SAndroid Build Coastguard Worker
50*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease {
51*d83cc019SAndroid Build Coastguard Worker /** Pointer to array of object ids (__u32) */
52*d83cc019SAndroid Build Coastguard Worker __u64 object_ids;
53*d83cc019SAndroid Build Coastguard Worker /** Number of object ids */
54*d83cc019SAndroid Build Coastguard Worker __u32 object_count;
55*d83cc019SAndroid Build Coastguard Worker /** flags for new FD (O_CLOEXEC, etc) */
56*d83cc019SAndroid Build Coastguard Worker __u32 flags;
57*d83cc019SAndroid Build Coastguard Worker
58*d83cc019SAndroid Build Coastguard Worker /** Return: unique identifier for lessee. */
59*d83cc019SAndroid Build Coastguard Worker __u32 lessee_id;
60*d83cc019SAndroid Build Coastguard Worker /** Return: file descriptor to new drm_master file */
61*d83cc019SAndroid Build Coastguard Worker __u32 fd;
62*d83cc019SAndroid Build Coastguard Worker };
63*d83cc019SAndroid Build Coastguard Worker
64*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_list_lessees {
65*d83cc019SAndroid Build Coastguard Worker /** Number of lessees.
66*d83cc019SAndroid Build Coastguard Worker * On input, provides length of the array.
67*d83cc019SAndroid Build Coastguard Worker * On output, provides total number. No
68*d83cc019SAndroid Build Coastguard Worker * more than the input number will be written
69*d83cc019SAndroid Build Coastguard Worker * back, so two calls can be used to get
70*d83cc019SAndroid Build Coastguard Worker * the size and then the data.
71*d83cc019SAndroid Build Coastguard Worker */
72*d83cc019SAndroid Build Coastguard Worker __u32 count_lessees;
73*d83cc019SAndroid Build Coastguard Worker __u32 pad;
74*d83cc019SAndroid Build Coastguard Worker
75*d83cc019SAndroid Build Coastguard Worker /** Pointer to lessees.
76*d83cc019SAndroid Build Coastguard Worker * pointer to __u64 array of lessee ids
77*d83cc019SAndroid Build Coastguard Worker */
78*d83cc019SAndroid Build Coastguard Worker __u64 lessees_ptr;
79*d83cc019SAndroid Build Coastguard Worker };
80*d83cc019SAndroid Build Coastguard Worker
81*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_get_lease {
82*d83cc019SAndroid Build Coastguard Worker /** Number of leased objects.
83*d83cc019SAndroid Build Coastguard Worker * On input, provides length of the array.
84*d83cc019SAndroid Build Coastguard Worker * On output, provides total number. No
85*d83cc019SAndroid Build Coastguard Worker * more than the input number will be written
86*d83cc019SAndroid Build Coastguard Worker * back, so two calls can be used to get
87*d83cc019SAndroid Build Coastguard Worker * the size and then the data.
88*d83cc019SAndroid Build Coastguard Worker */
89*d83cc019SAndroid Build Coastguard Worker __u32 count_objects;
90*d83cc019SAndroid Build Coastguard Worker __u32 pad;
91*d83cc019SAndroid Build Coastguard Worker
92*d83cc019SAndroid Build Coastguard Worker /** Pointer to objects.
93*d83cc019SAndroid Build Coastguard Worker * pointer to __u32 array of object ids
94*d83cc019SAndroid Build Coastguard Worker */
95*d83cc019SAndroid Build Coastguard Worker __u64 objects_ptr;
96*d83cc019SAndroid Build Coastguard Worker };
97*d83cc019SAndroid Build Coastguard Worker
98*d83cc019SAndroid Build Coastguard Worker /**
99*d83cc019SAndroid Build Coastguard Worker * Revoke lease
100*d83cc019SAndroid Build Coastguard Worker */
101*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_revoke_lease {
102*d83cc019SAndroid Build Coastguard Worker /** Unique ID of lessee
103*d83cc019SAndroid Build Coastguard Worker */
104*d83cc019SAndroid Build Coastguard Worker __u32 lessee_id;
105*d83cc019SAndroid Build Coastguard Worker };
106*d83cc019SAndroid Build Coastguard Worker
107*d83cc019SAndroid Build Coastguard Worker
108*d83cc019SAndroid Build Coastguard Worker #define LOCAL_DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct local_drm_mode_create_lease)
109*d83cc019SAndroid Build Coastguard Worker #define LOCAL_DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct local_drm_mode_list_lessees)
110*d83cc019SAndroid Build Coastguard Worker #define LOCAL_DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct local_drm_mode_get_lease)
111*d83cc019SAndroid Build Coastguard Worker #define LOCAL_DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct local_drm_mode_revoke_lease)
112*d83cc019SAndroid Build Coastguard Worker
113*d83cc019SAndroid Build Coastguard Worker typedef struct {
114*d83cc019SAndroid Build Coastguard Worker int fd;
115*d83cc019SAndroid Build Coastguard Worker uint32_t lessee_id;
116*d83cc019SAndroid Build Coastguard Worker igt_display_t display;
117*d83cc019SAndroid Build Coastguard Worker struct igt_fb primary_fb;
118*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
119*d83cc019SAndroid Build Coastguard Worker drmModeModeInfo *mode;
120*d83cc019SAndroid Build Coastguard Worker } lease_t;
121*d83cc019SAndroid Build Coastguard Worker
122*d83cc019SAndroid Build Coastguard Worker typedef struct {
123*d83cc019SAndroid Build Coastguard Worker lease_t master;
124*d83cc019SAndroid Build Coastguard Worker enum pipe pipe;
125*d83cc019SAndroid Build Coastguard Worker uint32_t crtc_id;
126*d83cc019SAndroid Build Coastguard Worker uint32_t connector_id;
127*d83cc019SAndroid Build Coastguard Worker uint32_t plane_id;
128*d83cc019SAndroid Build Coastguard Worker } data_t;
129*d83cc019SAndroid Build Coastguard Worker
pipe_to_crtc_id(igt_display_t * display,enum pipe pipe)130*d83cc019SAndroid Build Coastguard Worker static uint32_t pipe_to_crtc_id(igt_display_t *display, enum pipe pipe)
131*d83cc019SAndroid Build Coastguard Worker {
132*d83cc019SAndroid Build Coastguard Worker return display->pipes[pipe].crtc_id;
133*d83cc019SAndroid Build Coastguard Worker }
134*d83cc019SAndroid Build Coastguard Worker
crtc_id_to_pipe(igt_display_t * display,uint32_t crtc_id)135*d83cc019SAndroid Build Coastguard Worker static enum pipe crtc_id_to_pipe(igt_display_t *display, uint32_t crtc_id)
136*d83cc019SAndroid Build Coastguard Worker {
137*d83cc019SAndroid Build Coastguard Worker enum pipe pipe;
138*d83cc019SAndroid Build Coastguard Worker
139*d83cc019SAndroid Build Coastguard Worker for (pipe = 0; pipe < display->n_pipes; pipe++)
140*d83cc019SAndroid Build Coastguard Worker if (display->pipes[pipe].crtc_id == crtc_id)
141*d83cc019SAndroid Build Coastguard Worker return pipe;
142*d83cc019SAndroid Build Coastguard Worker return -1;
143*d83cc019SAndroid Build Coastguard Worker }
144*d83cc019SAndroid Build Coastguard Worker
connector_id_to_output(igt_display_t * display,uint32_t connector_id)145*d83cc019SAndroid Build Coastguard Worker static igt_output_t *connector_id_to_output(igt_display_t *display, uint32_t connector_id)
146*d83cc019SAndroid Build Coastguard Worker {
147*d83cc019SAndroid Build Coastguard Worker drmModeConnector connector;
148*d83cc019SAndroid Build Coastguard Worker
149*d83cc019SAndroid Build Coastguard Worker connector.connector_id = connector_id;
150*d83cc019SAndroid Build Coastguard Worker return igt_output_from_connector(display, &connector);
151*d83cc019SAndroid Build Coastguard Worker }
152*d83cc019SAndroid Build Coastguard Worker
prepare_crtc(lease_t * lease,uint32_t connector_id,uint32_t crtc_id)153*d83cc019SAndroid Build Coastguard Worker static int prepare_crtc(lease_t *lease, uint32_t connector_id, uint32_t crtc_id)
154*d83cc019SAndroid Build Coastguard Worker {
155*d83cc019SAndroid Build Coastguard Worker drmModeModeInfo *mode;
156*d83cc019SAndroid Build Coastguard Worker igt_display_t *display = &lease->display;
157*d83cc019SAndroid Build Coastguard Worker igt_output_t *output = connector_id_to_output(display, connector_id);
158*d83cc019SAndroid Build Coastguard Worker enum pipe pipe = crtc_id_to_pipe(display, crtc_id);
159*d83cc019SAndroid Build Coastguard Worker igt_plane_t *primary;
160*d83cc019SAndroid Build Coastguard Worker int ret;
161*d83cc019SAndroid Build Coastguard Worker
162*d83cc019SAndroid Build Coastguard Worker if (!output)
163*d83cc019SAndroid Build Coastguard Worker return -ENOENT;
164*d83cc019SAndroid Build Coastguard Worker
165*d83cc019SAndroid Build Coastguard Worker /* select the pipe we want to use */
166*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output, pipe);
167*d83cc019SAndroid Build Coastguard Worker
168*d83cc019SAndroid Build Coastguard Worker /* create and set the primary plane fb */
169*d83cc019SAndroid Build Coastguard Worker mode = igt_output_get_mode(output);
170*d83cc019SAndroid Build Coastguard Worker igt_create_color_fb(lease->fd, mode->hdisplay, mode->vdisplay,
171*d83cc019SAndroid Build Coastguard Worker DRM_FORMAT_XRGB8888,
172*d83cc019SAndroid Build Coastguard Worker LOCAL_DRM_FORMAT_MOD_NONE,
173*d83cc019SAndroid Build Coastguard Worker 0.0, 0.0, 0.0,
174*d83cc019SAndroid Build Coastguard Worker &lease->primary_fb);
175*d83cc019SAndroid Build Coastguard Worker
176*d83cc019SAndroid Build Coastguard Worker primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
177*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(primary, &lease->primary_fb);
178*d83cc019SAndroid Build Coastguard Worker
179*d83cc019SAndroid Build Coastguard Worker ret = igt_display_try_commit2(display, COMMIT_LEGACY);
180*d83cc019SAndroid Build Coastguard Worker
181*d83cc019SAndroid Build Coastguard Worker if (ret)
182*d83cc019SAndroid Build Coastguard Worker return ret;
183*d83cc019SAndroid Build Coastguard Worker
184*d83cc019SAndroid Build Coastguard Worker igt_wait_for_vblank(lease->fd, pipe);
185*d83cc019SAndroid Build Coastguard Worker
186*d83cc019SAndroid Build Coastguard Worker lease->output = output;
187*d83cc019SAndroid Build Coastguard Worker lease->mode = mode;
188*d83cc019SAndroid Build Coastguard Worker return 0;
189*d83cc019SAndroid Build Coastguard Worker }
190*d83cc019SAndroid Build Coastguard Worker
cleanup_crtc(lease_t * lease,igt_output_t * output)191*d83cc019SAndroid Build Coastguard Worker static void cleanup_crtc(lease_t *lease, igt_output_t *output)
192*d83cc019SAndroid Build Coastguard Worker {
193*d83cc019SAndroid Build Coastguard Worker igt_display_t *display = &lease->display;
194*d83cc019SAndroid Build Coastguard Worker igt_plane_t *primary;
195*d83cc019SAndroid Build Coastguard Worker
196*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(lease->fd, &lease->primary_fb);
197*d83cc019SAndroid Build Coastguard Worker
198*d83cc019SAndroid Build Coastguard Worker primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
199*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(primary, NULL);
200*d83cc019SAndroid Build Coastguard Worker
201*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output, PIPE_ANY);
202*d83cc019SAndroid Build Coastguard Worker igt_display_commit(display);
203*d83cc019SAndroid Build Coastguard Worker }
204*d83cc019SAndroid Build Coastguard Worker
create_lease(int fd,struct local_drm_mode_create_lease * mcl)205*d83cc019SAndroid Build Coastguard Worker static int create_lease(int fd, struct local_drm_mode_create_lease *mcl)
206*d83cc019SAndroid Build Coastguard Worker {
207*d83cc019SAndroid Build Coastguard Worker int err = 0;
208*d83cc019SAndroid Build Coastguard Worker
209*d83cc019SAndroid Build Coastguard Worker if (igt_ioctl(fd, LOCAL_DRM_IOCTL_MODE_CREATE_LEASE, mcl))
210*d83cc019SAndroid Build Coastguard Worker err = -errno;
211*d83cc019SAndroid Build Coastguard Worker return err;
212*d83cc019SAndroid Build Coastguard Worker }
213*d83cc019SAndroid Build Coastguard Worker
revoke_lease(int fd,struct local_drm_mode_revoke_lease * mrl)214*d83cc019SAndroid Build Coastguard Worker static int revoke_lease(int fd, struct local_drm_mode_revoke_lease *mrl)
215*d83cc019SAndroid Build Coastguard Worker {
216*d83cc019SAndroid Build Coastguard Worker int err = 0;
217*d83cc019SAndroid Build Coastguard Worker
218*d83cc019SAndroid Build Coastguard Worker if (igt_ioctl(fd, LOCAL_DRM_IOCTL_MODE_REVOKE_LEASE, mrl))
219*d83cc019SAndroid Build Coastguard Worker err = -errno;
220*d83cc019SAndroid Build Coastguard Worker return err;
221*d83cc019SAndroid Build Coastguard Worker }
222*d83cc019SAndroid Build Coastguard Worker
list_lessees(int fd,struct local_drm_mode_list_lessees * mll)223*d83cc019SAndroid Build Coastguard Worker static int list_lessees(int fd, struct local_drm_mode_list_lessees *mll)
224*d83cc019SAndroid Build Coastguard Worker {
225*d83cc019SAndroid Build Coastguard Worker int err = 0;
226*d83cc019SAndroid Build Coastguard Worker
227*d83cc019SAndroid Build Coastguard Worker if (igt_ioctl(fd, LOCAL_DRM_IOCTL_MODE_LIST_LESSEES, mll))
228*d83cc019SAndroid Build Coastguard Worker err = -errno;
229*d83cc019SAndroid Build Coastguard Worker return err;
230*d83cc019SAndroid Build Coastguard Worker }
231*d83cc019SAndroid Build Coastguard Worker
get_lease(int fd,struct local_drm_mode_get_lease * mgl)232*d83cc019SAndroid Build Coastguard Worker static int get_lease(int fd, struct local_drm_mode_get_lease *mgl)
233*d83cc019SAndroid Build Coastguard Worker {
234*d83cc019SAndroid Build Coastguard Worker int err = 0;
235*d83cc019SAndroid Build Coastguard Worker
236*d83cc019SAndroid Build Coastguard Worker if (igt_ioctl(fd, LOCAL_DRM_IOCTL_MODE_GET_LEASE, mgl))
237*d83cc019SAndroid Build Coastguard Worker err = -errno;
238*d83cc019SAndroid Build Coastguard Worker return err;
239*d83cc019SAndroid Build Coastguard Worker }
240*d83cc019SAndroid Build Coastguard Worker
make_lease(data_t * data,lease_t * lease)241*d83cc019SAndroid Build Coastguard Worker static int make_lease(data_t *data, lease_t *lease)
242*d83cc019SAndroid Build Coastguard Worker {
243*d83cc019SAndroid Build Coastguard Worker uint32_t object_ids[3];
244*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
245*d83cc019SAndroid Build Coastguard Worker int ret;
246*d83cc019SAndroid Build Coastguard Worker
247*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) &object_ids[0];
248*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 0;
249*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
250*d83cc019SAndroid Build Coastguard Worker
251*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->connector_id;
252*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->crtc_id;
253*d83cc019SAndroid Build Coastguard Worker /* We use universal planes, must add the primary plane */
254*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->plane_id;
255*d83cc019SAndroid Build Coastguard Worker
256*d83cc019SAndroid Build Coastguard Worker ret = create_lease(data->master.fd, &mcl);
257*d83cc019SAndroid Build Coastguard Worker
258*d83cc019SAndroid Build Coastguard Worker if (ret)
259*d83cc019SAndroid Build Coastguard Worker return ret;
260*d83cc019SAndroid Build Coastguard Worker
261*d83cc019SAndroid Build Coastguard Worker lease->fd = mcl.fd;
262*d83cc019SAndroid Build Coastguard Worker lease->lessee_id = mcl.lessee_id;
263*d83cc019SAndroid Build Coastguard Worker return 0;
264*d83cc019SAndroid Build Coastguard Worker }
265*d83cc019SAndroid Build Coastguard Worker
terminate_lease(lease_t * lease)266*d83cc019SAndroid Build Coastguard Worker static void terminate_lease(lease_t *lease)
267*d83cc019SAndroid Build Coastguard Worker {
268*d83cc019SAndroid Build Coastguard Worker close(lease->fd);
269*d83cc019SAndroid Build Coastguard Worker }
270*d83cc019SAndroid Build Coastguard Worker
paint_fb(int drm_fd,struct igt_fb * fb,const char * test_name,const char * mode_format_str,const char * connector_str,const char * pipe_str)271*d83cc019SAndroid Build Coastguard Worker static int paint_fb(int drm_fd, struct igt_fb *fb, const char *test_name,
272*d83cc019SAndroid Build Coastguard Worker const char *mode_format_str, const char *connector_str, const char *pipe_str)
273*d83cc019SAndroid Build Coastguard Worker {
274*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
275*d83cc019SAndroid Build Coastguard Worker
276*d83cc019SAndroid Build Coastguard Worker cr = igt_get_cairo_ctx(drm_fd, fb);
277*d83cc019SAndroid Build Coastguard Worker
278*d83cc019SAndroid Build Coastguard Worker igt_paint_color_gradient(cr, 0, 0, fb->width, fb->height, 1, 1, 1);
279*d83cc019SAndroid Build Coastguard Worker igt_paint_test_pattern(cr, fb->width, fb->height);
280*d83cc019SAndroid Build Coastguard Worker
281*d83cc019SAndroid Build Coastguard Worker cairo_move_to(cr, fb->width / 2, fb->height / 2);
282*d83cc019SAndroid Build Coastguard Worker cairo_set_font_size(cr, 36);
283*d83cc019SAndroid Build Coastguard Worker igt_cairo_printf_line(cr, align_hcenter, 10, "%s", test_name);
284*d83cc019SAndroid Build Coastguard Worker igt_cairo_printf_line(cr, align_hcenter, 10, "%s", mode_format_str);
285*d83cc019SAndroid Build Coastguard Worker igt_cairo_printf_line(cr, align_hcenter, 10, "%s", connector_str);
286*d83cc019SAndroid Build Coastguard Worker igt_cairo_printf_line(cr, align_hcenter, 10, "%s", pipe_str);
287*d83cc019SAndroid Build Coastguard Worker
288*d83cc019SAndroid Build Coastguard Worker cairo_destroy(cr);
289*d83cc019SAndroid Build Coastguard Worker
290*d83cc019SAndroid Build Coastguard Worker return 0;
291*d83cc019SAndroid Build Coastguard Worker }
292*d83cc019SAndroid Build Coastguard Worker
simple_lease(data_t * data)293*d83cc019SAndroid Build Coastguard Worker static void simple_lease(data_t *data)
294*d83cc019SAndroid Build Coastguard Worker {
295*d83cc019SAndroid Build Coastguard Worker lease_t lease;
296*d83cc019SAndroid Build Coastguard Worker
297*d83cc019SAndroid Build Coastguard Worker /* Create a valid lease */
298*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease), 0);
299*d83cc019SAndroid Build Coastguard Worker
300*d83cc019SAndroid Build Coastguard Worker igt_display_require(&lease.display, lease.fd);
301*d83cc019SAndroid Build Coastguard Worker
302*d83cc019SAndroid Build Coastguard Worker /* Set a mode on the leased output */
303*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(0, prepare_crtc(&lease, data->connector_id, data->crtc_id));
304*d83cc019SAndroid Build Coastguard Worker
305*d83cc019SAndroid Build Coastguard Worker /* Paint something attractive */
306*d83cc019SAndroid Build Coastguard Worker paint_fb(lease.fd, &lease.primary_fb, "simple_lease",
307*d83cc019SAndroid Build Coastguard Worker lease.mode->name, igt_output_name(lease.output), kmstest_pipe_name(data->pipe));
308*d83cc019SAndroid Build Coastguard Worker igt_debug_wait_for_keypress("lease");
309*d83cc019SAndroid Build Coastguard Worker cleanup_crtc(&lease,
310*d83cc019SAndroid Build Coastguard Worker connector_id_to_output(&lease.display, data->connector_id));
311*d83cc019SAndroid Build Coastguard Worker
312*d83cc019SAndroid Build Coastguard Worker terminate_lease(&lease);
313*d83cc019SAndroid Build Coastguard Worker }
314*d83cc019SAndroid Build Coastguard Worker
page_flip_implicit_plane(data_t * data)315*d83cc019SAndroid Build Coastguard Worker static void page_flip_implicit_plane(data_t *data)
316*d83cc019SAndroid Build Coastguard Worker {
317*d83cc019SAndroid Build Coastguard Worker uint32_t object_ids[3];
318*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
319*d83cc019SAndroid Build Coastguard Worker drmModePlaneRes *plane_resources;
320*d83cc019SAndroid Build Coastguard Worker uint32_t wrong_plane_id = 0;
321*d83cc019SAndroid Build Coastguard Worker int i;
322*d83cc019SAndroid Build Coastguard Worker
323*d83cc019SAndroid Build Coastguard Worker /* find a plane which isn't the primary one for us */
324*d83cc019SAndroid Build Coastguard Worker plane_resources = drmModeGetPlaneResources(data->master.fd);
325*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < plane_resources->count_planes; i++) {
326*d83cc019SAndroid Build Coastguard Worker if (plane_resources->planes[i] != data->plane_id) {
327*d83cc019SAndroid Build Coastguard Worker wrong_plane_id = plane_resources->planes[i];
328*d83cc019SAndroid Build Coastguard Worker break;
329*d83cc019SAndroid Build Coastguard Worker }
330*d83cc019SAndroid Build Coastguard Worker }
331*d83cc019SAndroid Build Coastguard Worker drmModeFreePlaneResources(plane_resources);
332*d83cc019SAndroid Build Coastguard Worker igt_require(wrong_plane_id);
333*d83cc019SAndroid Build Coastguard Worker
334*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) &object_ids[0];
335*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 0;
336*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
337*d83cc019SAndroid Build Coastguard Worker
338*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->connector_id;
339*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->crtc_id;
340*d83cc019SAndroid Build Coastguard Worker
341*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0);
342*d83cc019SAndroid Build Coastguard Worker do_or_die(create_lease(data->master.fd, &mcl));
343*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
344*d83cc019SAndroid Build Coastguard Worker
345*d83cc019SAndroid Build Coastguard Worker /* Set a mode on the leased output */
346*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(0, prepare_crtc(&data->master, data->connector_id, data->crtc_id));
347*d83cc019SAndroid Build Coastguard Worker
348*d83cc019SAndroid Build Coastguard Worker /* sanity check */
349*d83cc019SAndroid Build Coastguard Worker do_or_die(drmModePageFlip(data->master.fd, data->crtc_id,
350*d83cc019SAndroid Build Coastguard Worker data->master.primary_fb.fb_id,
351*d83cc019SAndroid Build Coastguard Worker 0, NULL));
352*d83cc019SAndroid Build Coastguard Worker igt_wait_for_vblank_count(data->master.fd,
353*d83cc019SAndroid Build Coastguard Worker crtc_id_to_pipe(&data->master.display, data->crtc_id),
354*d83cc019SAndroid Build Coastguard Worker 1);
355*d83cc019SAndroid Build Coastguard Worker do_or_die(drmModePageFlip(mcl.fd, data->crtc_id,
356*d83cc019SAndroid Build Coastguard Worker data->master.primary_fb.fb_id,
357*d83cc019SAndroid Build Coastguard Worker 0, NULL));
358*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
359*d83cc019SAndroid Build Coastguard Worker
360*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = wrong_plane_id;
361*d83cc019SAndroid Build Coastguard Worker do_or_die(create_lease(data->master.fd, &mcl));
362*d83cc019SAndroid Build Coastguard Worker
363*d83cc019SAndroid Build Coastguard Worker igt_wait_for_vblank_count(data->master.fd,
364*d83cc019SAndroid Build Coastguard Worker crtc_id_to_pipe(&data->master.display, data->crtc_id),
365*d83cc019SAndroid Build Coastguard Worker 1);
366*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(drmModePageFlip(mcl.fd, data->crtc_id,
367*d83cc019SAndroid Build Coastguard Worker data->master.primary_fb.fb_id,
368*d83cc019SAndroid Build Coastguard Worker 0, NULL),
369*d83cc019SAndroid Build Coastguard Worker -EACCES);
370*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
371*d83cc019SAndroid Build Coastguard Worker
372*d83cc019SAndroid Build Coastguard Worker cleanup_crtc(&data->master,
373*d83cc019SAndroid Build Coastguard Worker connector_id_to_output(&data->master.display, data->connector_id));
374*d83cc019SAndroid Build Coastguard Worker }
375*d83cc019SAndroid Build Coastguard Worker
setcrtc_implicit_plane(data_t * data)376*d83cc019SAndroid Build Coastguard Worker static void setcrtc_implicit_plane(data_t *data)
377*d83cc019SAndroid Build Coastguard Worker {
378*d83cc019SAndroid Build Coastguard Worker uint32_t object_ids[3];
379*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
380*d83cc019SAndroid Build Coastguard Worker drmModePlaneRes *plane_resources;
381*d83cc019SAndroid Build Coastguard Worker uint32_t wrong_plane_id = 0;
382*d83cc019SAndroid Build Coastguard Worker igt_output_t *output =
383*d83cc019SAndroid Build Coastguard Worker connector_id_to_output(&data->master.display,
384*d83cc019SAndroid Build Coastguard Worker data->connector_id);
385*d83cc019SAndroid Build Coastguard Worker drmModeModeInfo *mode = igt_output_get_mode(output);
386*d83cc019SAndroid Build Coastguard Worker int i;
387*d83cc019SAndroid Build Coastguard Worker
388*d83cc019SAndroid Build Coastguard Worker /* find a plane which isn't the primary one for us */
389*d83cc019SAndroid Build Coastguard Worker plane_resources = drmModeGetPlaneResources(data->master.fd);
390*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < plane_resources->count_planes; i++) {
391*d83cc019SAndroid Build Coastguard Worker if (plane_resources->planes[i] != data->plane_id) {
392*d83cc019SAndroid Build Coastguard Worker wrong_plane_id = plane_resources->planes[i];
393*d83cc019SAndroid Build Coastguard Worker break;
394*d83cc019SAndroid Build Coastguard Worker }
395*d83cc019SAndroid Build Coastguard Worker }
396*d83cc019SAndroid Build Coastguard Worker drmModeFreePlaneResources(plane_resources);
397*d83cc019SAndroid Build Coastguard Worker igt_require(wrong_plane_id);
398*d83cc019SAndroid Build Coastguard Worker
399*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) &object_ids[0];
400*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 0;
401*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
402*d83cc019SAndroid Build Coastguard Worker
403*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->connector_id;
404*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->crtc_id;
405*d83cc019SAndroid Build Coastguard Worker
406*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0);
407*d83cc019SAndroid Build Coastguard Worker do_or_die(create_lease(data->master.fd, &mcl));
408*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
409*d83cc019SAndroid Build Coastguard Worker
410*d83cc019SAndroid Build Coastguard Worker /* Set a mode on the leased output */
411*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(0, prepare_crtc(&data->master, data->connector_id, data->crtc_id));
412*d83cc019SAndroid Build Coastguard Worker
413*d83cc019SAndroid Build Coastguard Worker /* sanity check */
414*d83cc019SAndroid Build Coastguard Worker do_or_die(drmModeSetCrtc(data->master.fd, data->crtc_id, -1,
415*d83cc019SAndroid Build Coastguard Worker 0, 0, object_ids, 1, mode));
416*d83cc019SAndroid Build Coastguard Worker do_or_die(drmModeSetCrtc(mcl.fd, data->crtc_id, -1,
417*d83cc019SAndroid Build Coastguard Worker 0, 0, object_ids, 1, mode));
418*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
419*d83cc019SAndroid Build Coastguard Worker
420*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = wrong_plane_id;
421*d83cc019SAndroid Build Coastguard Worker do_or_die(create_lease(data->master.fd, &mcl));
422*d83cc019SAndroid Build Coastguard Worker
423*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(drmModeSetCrtc(mcl.fd, data->crtc_id, -1,
424*d83cc019SAndroid Build Coastguard Worker 0, 0, object_ids, 1, mode),
425*d83cc019SAndroid Build Coastguard Worker -EACCES);
426*d83cc019SAndroid Build Coastguard Worker /* make sure we are allowed to turn the CRTC off */
427*d83cc019SAndroid Build Coastguard Worker do_or_die(drmModeSetCrtc(mcl.fd, data->crtc_id,
428*d83cc019SAndroid Build Coastguard Worker 0, 0, 0, NULL, 0, NULL));
429*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
430*d83cc019SAndroid Build Coastguard Worker
431*d83cc019SAndroid Build Coastguard Worker cleanup_crtc(&data->master,
432*d83cc019SAndroid Build Coastguard Worker connector_id_to_output(&data->master.display, data->connector_id));
433*d83cc019SAndroid Build Coastguard Worker }
434*d83cc019SAndroid Build Coastguard Worker
cursor_implicit_plane(data_t * data)435*d83cc019SAndroid Build Coastguard Worker static void cursor_implicit_plane(data_t *data)
436*d83cc019SAndroid Build Coastguard Worker {
437*d83cc019SAndroid Build Coastguard Worker uint32_t object_ids[3];
438*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
439*d83cc019SAndroid Build Coastguard Worker
440*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) &object_ids[0];
441*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 0;
442*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
443*d83cc019SAndroid Build Coastguard Worker
444*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->connector_id;
445*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->crtc_id;
446*d83cc019SAndroid Build Coastguard Worker
447*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0);
448*d83cc019SAndroid Build Coastguard Worker do_or_die(create_lease(data->master.fd, &mcl));
449*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
450*d83cc019SAndroid Build Coastguard Worker
451*d83cc019SAndroid Build Coastguard Worker /* Set a mode on the leased output */
452*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(0, prepare_crtc(&data->master, data->connector_id, data->crtc_id));
453*d83cc019SAndroid Build Coastguard Worker
454*d83cc019SAndroid Build Coastguard Worker /* sanity check */
455*d83cc019SAndroid Build Coastguard Worker do_or_die(drmModeSetCursor(data->master.fd, data->crtc_id, 0, 0, 0));
456*d83cc019SAndroid Build Coastguard Worker do_or_die(drmModeSetCursor(mcl.fd, data->crtc_id, 0, 0, 0));
457*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
458*d83cc019SAndroid Build Coastguard Worker
459*d83cc019SAndroid Build Coastguard Worker /* primary plane is never the cursor */
460*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->plane_id;
461*d83cc019SAndroid Build Coastguard Worker do_or_die(create_lease(data->master.fd, &mcl));
462*d83cc019SAndroid Build Coastguard Worker
463*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(drmModeSetCursor(mcl.fd, data->crtc_id, 0, 0, 0),
464*d83cc019SAndroid Build Coastguard Worker -EACCES);
465*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
466*d83cc019SAndroid Build Coastguard Worker
467*d83cc019SAndroid Build Coastguard Worker cleanup_crtc(&data->master,
468*d83cc019SAndroid Build Coastguard Worker connector_id_to_output(&data->master.display, data->connector_id));
469*d83cc019SAndroid Build Coastguard Worker }
470*d83cc019SAndroid Build Coastguard Worker
atomic_implicit_crtc(data_t * data)471*d83cc019SAndroid Build Coastguard Worker static void atomic_implicit_crtc(data_t *data)
472*d83cc019SAndroid Build Coastguard Worker {
473*d83cc019SAndroid Build Coastguard Worker uint32_t object_ids[3];
474*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
475*d83cc019SAndroid Build Coastguard Worker drmModeRes *resources;
476*d83cc019SAndroid Build Coastguard Worker drmModeObjectPropertiesPtr props;
477*d83cc019SAndroid Build Coastguard Worker uint32_t wrong_crtc_id = 0;
478*d83cc019SAndroid Build Coastguard Worker uint32_t crtc_id_prop = 0;
479*d83cc019SAndroid Build Coastguard Worker drmModeAtomicReqPtr req = NULL;
480*d83cc019SAndroid Build Coastguard Worker int ret;
481*d83cc019SAndroid Build Coastguard Worker
482*d83cc019SAndroid Build Coastguard Worker igt_require(data->master.display.is_atomic);
483*d83cc019SAndroid Build Coastguard Worker
484*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) &object_ids[0];
485*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 0;
486*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
487*d83cc019SAndroid Build Coastguard Worker
488*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->connector_id;
489*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = data->plane_id;
490*d83cc019SAndroid Build Coastguard Worker
491*d83cc019SAndroid Build Coastguard Worker /* find a plane which isn't the primary one for us */
492*d83cc019SAndroid Build Coastguard Worker resources = drmModeGetResources(data->master.fd);
493*d83cc019SAndroid Build Coastguard Worker igt_assert(resources);
494*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < resources->count_crtcs; i++) {
495*d83cc019SAndroid Build Coastguard Worker if (resources->crtcs[i] != data->crtc_id) {
496*d83cc019SAndroid Build Coastguard Worker wrong_crtc_id = resources->crtcs[i];
497*d83cc019SAndroid Build Coastguard Worker break;
498*d83cc019SAndroid Build Coastguard Worker }
499*d83cc019SAndroid Build Coastguard Worker }
500*d83cc019SAndroid Build Coastguard Worker drmModeFreeResources(resources);
501*d83cc019SAndroid Build Coastguard Worker igt_require(wrong_crtc_id);
502*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count++] = wrong_crtc_id;
503*d83cc019SAndroid Build Coastguard Worker
504*d83cc019SAndroid Build Coastguard Worker /* find the CRTC_ID prop, it's global */
505*d83cc019SAndroid Build Coastguard Worker props = drmModeObjectGetProperties(data->master.fd, data->plane_id,
506*d83cc019SAndroid Build Coastguard Worker DRM_MODE_OBJECT_PLANE);
507*d83cc019SAndroid Build Coastguard Worker igt_assert(props);
508*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < props->count_props; i++) {
509*d83cc019SAndroid Build Coastguard Worker drmModePropertyPtr prop = drmModeGetProperty(data->master.fd,
510*d83cc019SAndroid Build Coastguard Worker props->props[i]);
511*d83cc019SAndroid Build Coastguard Worker if (strcmp(prop->name, "CRTC_ID") == 0)
512*d83cc019SAndroid Build Coastguard Worker crtc_id_prop = props->props[i];
513*d83cc019SAndroid Build Coastguard Worker
514*d83cc019SAndroid Build Coastguard Worker printf("prop name %s, prop id %u, prop id %u\n",
515*d83cc019SAndroid Build Coastguard Worker prop->name, props->props[i], prop->prop_id);
516*d83cc019SAndroid Build Coastguard Worker drmModeFreeProperty(prop);
517*d83cc019SAndroid Build Coastguard Worker if (crtc_id_prop)
518*d83cc019SAndroid Build Coastguard Worker break;
519*d83cc019SAndroid Build Coastguard Worker }
520*d83cc019SAndroid Build Coastguard Worker drmModeFreeObjectProperties(props);
521*d83cc019SAndroid Build Coastguard Worker igt_assert(crtc_id_prop);
522*d83cc019SAndroid Build Coastguard Worker
523*d83cc019SAndroid Build Coastguard Worker do_or_die(create_lease(data->master.fd, &mcl));
524*d83cc019SAndroid Build Coastguard Worker do_or_die(drmSetClientCap(mcl.fd, DRM_CLIENT_CAP_ATOMIC, 1));
525*d83cc019SAndroid Build Coastguard Worker
526*d83cc019SAndroid Build Coastguard Worker /* check CRTC_ID property on the plane */
527*d83cc019SAndroid Build Coastguard Worker req = drmModeAtomicAlloc();
528*d83cc019SAndroid Build Coastguard Worker igt_assert(req);
529*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicAddProperty(req, data->plane_id,
530*d83cc019SAndroid Build Coastguard Worker crtc_id_prop, data->crtc_id);
531*d83cc019SAndroid Build Coastguard Worker igt_assert(ret >= 0);
532*d83cc019SAndroid Build Coastguard Worker
533*d83cc019SAndroid Build Coastguard Worker /* sanity check */
534*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicCommit(data->master.fd, req, DRM_MODE_ATOMIC_TEST_ONLY, NULL);
535*d83cc019SAndroid Build Coastguard Worker igt_assert(ret == 0 || ret == -EINVAL);
536*d83cc019SAndroid Build Coastguard Worker
537*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicCommit(mcl.fd, req, DRM_MODE_ATOMIC_TEST_ONLY, NULL);
538*d83cc019SAndroid Build Coastguard Worker igt_assert(ret == -EACCES);
539*d83cc019SAndroid Build Coastguard Worker drmModeAtomicFree(req);
540*d83cc019SAndroid Build Coastguard Worker
541*d83cc019SAndroid Build Coastguard Worker /* check CRTC_ID property on the connector */
542*d83cc019SAndroid Build Coastguard Worker req = drmModeAtomicAlloc();
543*d83cc019SAndroid Build Coastguard Worker igt_assert(req);
544*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicAddProperty(req, data->connector_id,
545*d83cc019SAndroid Build Coastguard Worker crtc_id_prop, data->crtc_id);
546*d83cc019SAndroid Build Coastguard Worker igt_assert(ret >= 0);
547*d83cc019SAndroid Build Coastguard Worker
548*d83cc019SAndroid Build Coastguard Worker /* sanity check */
549*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicCommit(data->master.fd, req, DRM_MODE_ATOMIC_TEST_ONLY, NULL);
550*d83cc019SAndroid Build Coastguard Worker igt_assert(ret == 0 || ret == -EINVAL);
551*d83cc019SAndroid Build Coastguard Worker
552*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicCommit(mcl.fd, req, DRM_MODE_ATOMIC_TEST_ONLY, NULL);
553*d83cc019SAndroid Build Coastguard Worker igt_assert(ret == -EACCES);
554*d83cc019SAndroid Build Coastguard Worker drmModeAtomicFree(req);
555*d83cc019SAndroid Build Coastguard Worker
556*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
557*d83cc019SAndroid Build Coastguard Worker }
558*d83cc019SAndroid Build Coastguard Worker
559*d83cc019SAndroid Build Coastguard Worker /* Test listing lessees */
lessee_list(data_t * data)560*d83cc019SAndroid Build Coastguard Worker static void lessee_list(data_t *data)
561*d83cc019SAndroid Build Coastguard Worker {
562*d83cc019SAndroid Build Coastguard Worker lease_t lease;
563*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_list_lessees mll;
564*d83cc019SAndroid Build Coastguard Worker uint32_t lessees[1];
565*d83cc019SAndroid Build Coastguard Worker
566*d83cc019SAndroid Build Coastguard Worker mll.pad = 0;
567*d83cc019SAndroid Build Coastguard Worker
568*d83cc019SAndroid Build Coastguard Worker /* Create a valid lease */
569*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease), 0);
570*d83cc019SAndroid Build Coastguard Worker
571*d83cc019SAndroid Build Coastguard Worker /* check for nested leases */
572*d83cc019SAndroid Build Coastguard Worker mll.count_lessees = 0;
573*d83cc019SAndroid Build Coastguard Worker mll.lessees_ptr = 0;
574*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(list_lessees(lease.fd, &mll), 0);
575*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mll.count_lessees, 0);
576*d83cc019SAndroid Build Coastguard Worker
577*d83cc019SAndroid Build Coastguard Worker /* Get the number of lessees */
578*d83cc019SAndroid Build Coastguard Worker mll.count_lessees = 0;
579*d83cc019SAndroid Build Coastguard Worker mll.lessees_ptr = 0;
580*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(list_lessees(data->master.fd, &mll), 0);
581*d83cc019SAndroid Build Coastguard Worker
582*d83cc019SAndroid Build Coastguard Worker /* Make sure there's a single lessee */
583*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mll.count_lessees, 1);
584*d83cc019SAndroid Build Coastguard Worker
585*d83cc019SAndroid Build Coastguard Worker /* invalid ptr */
586*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(list_lessees(data->master.fd, &mll), -EFAULT);
587*d83cc019SAndroid Build Coastguard Worker
588*d83cc019SAndroid Build Coastguard Worker mll.lessees_ptr = (uint64_t) (uintptr_t) &lessees[0];
589*d83cc019SAndroid Build Coastguard Worker
590*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(list_lessees(data->master.fd, &mll), 0);
591*d83cc019SAndroid Build Coastguard Worker
592*d83cc019SAndroid Build Coastguard Worker /* Make sure there's a single lessee */
593*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mll.count_lessees, 1);
594*d83cc019SAndroid Build Coastguard Worker
595*d83cc019SAndroid Build Coastguard Worker /* Make sure the listed lease is the same as the one we created */
596*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(lessees[0], lease.lessee_id);
597*d83cc019SAndroid Build Coastguard Worker
598*d83cc019SAndroid Build Coastguard Worker /* invalid pad */
599*d83cc019SAndroid Build Coastguard Worker mll.pad = -1;
600*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(list_lessees(data->master.fd, &mll), -EINVAL);
601*d83cc019SAndroid Build Coastguard Worker mll.pad = 0;
602*d83cc019SAndroid Build Coastguard Worker
603*d83cc019SAndroid Build Coastguard Worker terminate_lease(&lease);
604*d83cc019SAndroid Build Coastguard Worker
605*d83cc019SAndroid Build Coastguard Worker /* Make sure the lease is gone */
606*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(list_lessees(data->master.fd, &mll), 0);
607*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mll.count_lessees, 0);
608*d83cc019SAndroid Build Coastguard Worker }
609*d83cc019SAndroid Build Coastguard Worker
610*d83cc019SAndroid Build Coastguard Worker /* Test getting the contents of a lease */
lease_get(data_t * data)611*d83cc019SAndroid Build Coastguard Worker static void lease_get(data_t *data)
612*d83cc019SAndroid Build Coastguard Worker {
613*d83cc019SAndroid Build Coastguard Worker lease_t lease;
614*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_get_lease mgl;
615*d83cc019SAndroid Build Coastguard Worker int num_leased_obj = 3;
616*d83cc019SAndroid Build Coastguard Worker uint32_t objects[num_leased_obj];
617*d83cc019SAndroid Build Coastguard Worker int o;
618*d83cc019SAndroid Build Coastguard Worker
619*d83cc019SAndroid Build Coastguard Worker mgl.pad = 0;
620*d83cc019SAndroid Build Coastguard Worker
621*d83cc019SAndroid Build Coastguard Worker /* Create a valid lease */
622*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease), 0);
623*d83cc019SAndroid Build Coastguard Worker
624*d83cc019SAndroid Build Coastguard Worker /* Get the number of objects */
625*d83cc019SAndroid Build Coastguard Worker mgl.count_objects = 0;
626*d83cc019SAndroid Build Coastguard Worker mgl.objects_ptr = 0;
627*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_lease(lease.fd, &mgl), 0);
628*d83cc019SAndroid Build Coastguard Worker
629*d83cc019SAndroid Build Coastguard Worker /* Make sure it's 2 */
630*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mgl.count_objects, num_leased_obj);
631*d83cc019SAndroid Build Coastguard Worker
632*d83cc019SAndroid Build Coastguard Worker /* Get the objects */
633*d83cc019SAndroid Build Coastguard Worker mgl.objects_ptr = (uint64_t) (uintptr_t) objects;
634*d83cc019SAndroid Build Coastguard Worker
635*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_lease(lease.fd, &mgl), 0);
636*d83cc019SAndroid Build Coastguard Worker
637*d83cc019SAndroid Build Coastguard Worker /* Make sure it's 2 */
638*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mgl.count_objects, num_leased_obj);
639*d83cc019SAndroid Build Coastguard Worker
640*d83cc019SAndroid Build Coastguard Worker /* Make sure we got the connector, crtc and plane back */
641*d83cc019SAndroid Build Coastguard Worker for (o = 0; o < num_leased_obj; o++)
642*d83cc019SAndroid Build Coastguard Worker if (objects[o] == data->connector_id)
643*d83cc019SAndroid Build Coastguard Worker break;
644*d83cc019SAndroid Build Coastguard Worker
645*d83cc019SAndroid Build Coastguard Worker igt_assert_neq(o, num_leased_obj);
646*d83cc019SAndroid Build Coastguard Worker
647*d83cc019SAndroid Build Coastguard Worker for (o = 0; o < num_leased_obj; o++)
648*d83cc019SAndroid Build Coastguard Worker if (objects[o] == data->crtc_id)
649*d83cc019SAndroid Build Coastguard Worker break;
650*d83cc019SAndroid Build Coastguard Worker
651*d83cc019SAndroid Build Coastguard Worker igt_assert_neq(o, num_leased_obj);
652*d83cc019SAndroid Build Coastguard Worker
653*d83cc019SAndroid Build Coastguard Worker for (o = 0; o < num_leased_obj; o++)
654*d83cc019SAndroid Build Coastguard Worker if (objects[o] == data->plane_id)
655*d83cc019SAndroid Build Coastguard Worker break;
656*d83cc019SAndroid Build Coastguard Worker
657*d83cc019SAndroid Build Coastguard Worker igt_assert_neq(o, num_leased_obj);
658*d83cc019SAndroid Build Coastguard Worker
659*d83cc019SAndroid Build Coastguard Worker /* invalid pad */
660*d83cc019SAndroid Build Coastguard Worker mgl.pad = -1;
661*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_lease(lease.fd, &mgl), -EINVAL);
662*d83cc019SAndroid Build Coastguard Worker mgl.pad = 0;
663*d83cc019SAndroid Build Coastguard Worker
664*d83cc019SAndroid Build Coastguard Worker /* invalid pointer */
665*d83cc019SAndroid Build Coastguard Worker mgl.objects_ptr = 0;
666*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_lease(lease.fd, &mgl), -EFAULT);
667*d83cc019SAndroid Build Coastguard Worker
668*d83cc019SAndroid Build Coastguard Worker terminate_lease(&lease);
669*d83cc019SAndroid Build Coastguard Worker }
670*d83cc019SAndroid Build Coastguard Worker
lease_unleased_crtc(data_t * data)671*d83cc019SAndroid Build Coastguard Worker static void lease_unleased_crtc(data_t *data)
672*d83cc019SAndroid Build Coastguard Worker {
673*d83cc019SAndroid Build Coastguard Worker lease_t lease;
674*d83cc019SAndroid Build Coastguard Worker enum pipe p;
675*d83cc019SAndroid Build Coastguard Worker uint32_t bad_crtc_id;
676*d83cc019SAndroid Build Coastguard Worker drmModeCrtc *crtc;
677*d83cc019SAndroid Build Coastguard Worker int ret;
678*d83cc019SAndroid Build Coastguard Worker
679*d83cc019SAndroid Build Coastguard Worker /* Create a valid lease */
680*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease), 0);
681*d83cc019SAndroid Build Coastguard Worker
682*d83cc019SAndroid Build Coastguard Worker igt_display_require(&lease.display, lease.fd);
683*d83cc019SAndroid Build Coastguard Worker
684*d83cc019SAndroid Build Coastguard Worker /* Find another CRTC that we don't control */
685*d83cc019SAndroid Build Coastguard Worker bad_crtc_id = 0;
686*d83cc019SAndroid Build Coastguard Worker for (p = 0; bad_crtc_id == 0 && p < data->master.display.n_pipes; p++) {
687*d83cc019SAndroid Build Coastguard Worker if (pipe_to_crtc_id(&data->master.display, p) != data->crtc_id)
688*d83cc019SAndroid Build Coastguard Worker bad_crtc_id = pipe_to_crtc_id(&data->master.display, p);
689*d83cc019SAndroid Build Coastguard Worker }
690*d83cc019SAndroid Build Coastguard Worker
691*d83cc019SAndroid Build Coastguard Worker /* Give up if there isn't another crtc */
692*d83cc019SAndroid Build Coastguard Worker igt_skip_on(bad_crtc_id == 0);
693*d83cc019SAndroid Build Coastguard Worker
694*d83cc019SAndroid Build Coastguard Worker /* sanity check */
695*d83cc019SAndroid Build Coastguard Worker ret = drmModeSetCrtc(lease.fd, data->crtc_id, 0, 0, 0, NULL, 0, NULL);
696*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, 0);
697*d83cc019SAndroid Build Coastguard Worker crtc = drmModeGetCrtc(lease.fd, data->crtc_id);
698*d83cc019SAndroid Build Coastguard Worker igt_assert(crtc);
699*d83cc019SAndroid Build Coastguard Worker drmModeFreeCrtc(crtc);
700*d83cc019SAndroid Build Coastguard Worker
701*d83cc019SAndroid Build Coastguard Worker /* Attempt to use the unleased crtc id. We need raw ioctl to bypass the
702*d83cc019SAndroid Build Coastguard Worker * igt_kms helpers.
703*d83cc019SAndroid Build Coastguard Worker */
704*d83cc019SAndroid Build Coastguard Worker ret = drmModeSetCrtc(lease.fd, bad_crtc_id, 0, 0, 0, NULL, 0, NULL);
705*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, -ENOENT);
706*d83cc019SAndroid Build Coastguard Worker crtc = drmModeGetCrtc(lease.fd, bad_crtc_id);
707*d83cc019SAndroid Build Coastguard Worker igt_assert(!crtc);
708*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(errno, ENOENT);
709*d83cc019SAndroid Build Coastguard Worker drmModeFreeCrtc(crtc);
710*d83cc019SAndroid Build Coastguard Worker
711*d83cc019SAndroid Build Coastguard Worker terminate_lease(&lease);
712*d83cc019SAndroid Build Coastguard Worker }
713*d83cc019SAndroid Build Coastguard Worker
lease_unleased_connector(data_t * data)714*d83cc019SAndroid Build Coastguard Worker static void lease_unleased_connector(data_t *data)
715*d83cc019SAndroid Build Coastguard Worker {
716*d83cc019SAndroid Build Coastguard Worker lease_t lease;
717*d83cc019SAndroid Build Coastguard Worker int o;
718*d83cc019SAndroid Build Coastguard Worker uint32_t bad_connector_id;
719*d83cc019SAndroid Build Coastguard Worker drmModeConnector *c;
720*d83cc019SAndroid Build Coastguard Worker
721*d83cc019SAndroid Build Coastguard Worker /* Create a valid lease */
722*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease), 0);
723*d83cc019SAndroid Build Coastguard Worker
724*d83cc019SAndroid Build Coastguard Worker igt_display_require(&lease.display, lease.fd);
725*d83cc019SAndroid Build Coastguard Worker
726*d83cc019SAndroid Build Coastguard Worker /* Find another connector that we don't control */
727*d83cc019SAndroid Build Coastguard Worker bad_connector_id = 0;
728*d83cc019SAndroid Build Coastguard Worker for (o = 0; bad_connector_id == 0 && o < data->master.display.n_outputs; o++) {
729*d83cc019SAndroid Build Coastguard Worker if (data->master.display.outputs[o].id != data->connector_id)
730*d83cc019SAndroid Build Coastguard Worker bad_connector_id = data->master.display.outputs[o].id;
731*d83cc019SAndroid Build Coastguard Worker }
732*d83cc019SAndroid Build Coastguard Worker
733*d83cc019SAndroid Build Coastguard Worker /* Give up if there isn't another connector */
734*d83cc019SAndroid Build Coastguard Worker igt_skip_on(bad_connector_id == 0);
735*d83cc019SAndroid Build Coastguard Worker
736*d83cc019SAndroid Build Coastguard Worker /* sanity check */
737*d83cc019SAndroid Build Coastguard Worker c = drmModeGetConnector(lease.fd, data->connector_id);
738*d83cc019SAndroid Build Coastguard Worker igt_assert(c);
739*d83cc019SAndroid Build Coastguard Worker
740*d83cc019SAndroid Build Coastguard Worker /* Attempt to use the unleased connector id. Note that the
741*d83cc019SAndroid Build Coastguard Worker */
742*d83cc019SAndroid Build Coastguard Worker c = drmModeGetConnector(lease.fd, bad_connector_id);
743*d83cc019SAndroid Build Coastguard Worker igt_assert(!c);
744*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(errno, ENOENT);
745*d83cc019SAndroid Build Coastguard Worker
746*d83cc019SAndroid Build Coastguard Worker terminate_lease(&lease);
747*d83cc019SAndroid Build Coastguard Worker }
748*d83cc019SAndroid Build Coastguard Worker
749*d83cc019SAndroid Build Coastguard Worker /* Test revocation of lease */
lease_revoke(data_t * data)750*d83cc019SAndroid Build Coastguard Worker static void lease_revoke(data_t *data)
751*d83cc019SAndroid Build Coastguard Worker {
752*d83cc019SAndroid Build Coastguard Worker lease_t lease;
753*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_revoke_lease mrl;
754*d83cc019SAndroid Build Coastguard Worker int ret;
755*d83cc019SAndroid Build Coastguard Worker
756*d83cc019SAndroid Build Coastguard Worker /* Create a valid lease */
757*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease), 0);
758*d83cc019SAndroid Build Coastguard Worker
759*d83cc019SAndroid Build Coastguard Worker igt_display_require(&lease.display, lease.fd);
760*d83cc019SAndroid Build Coastguard Worker
761*d83cc019SAndroid Build Coastguard Worker /* try to revoke an invalid lease */
762*d83cc019SAndroid Build Coastguard Worker mrl.lessee_id = 0;
763*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(revoke_lease(data->master.fd, &mrl), -ENOENT);
764*d83cc019SAndroid Build Coastguard Worker
765*d83cc019SAndroid Build Coastguard Worker /* try to revoke with the wrong fd */
766*d83cc019SAndroid Build Coastguard Worker mrl.lessee_id = lease.lessee_id;
767*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(revoke_lease(lease.fd, &mrl), -EACCES);
768*d83cc019SAndroid Build Coastguard Worker
769*d83cc019SAndroid Build Coastguard Worker /* Revoke the lease using the master fd */
770*d83cc019SAndroid Build Coastguard Worker mrl.lessee_id = lease.lessee_id;
771*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(revoke_lease(data->master.fd, &mrl), 0);
772*d83cc019SAndroid Build Coastguard Worker
773*d83cc019SAndroid Build Coastguard Worker /* Try to use the leased objects */
774*d83cc019SAndroid Build Coastguard Worker ret = prepare_crtc(&lease, data->connector_id, data->crtc_id);
775*d83cc019SAndroid Build Coastguard Worker
776*d83cc019SAndroid Build Coastguard Worker /* Ensure that the expected error is returned */
777*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, -ENOENT);
778*d83cc019SAndroid Build Coastguard Worker
779*d83cc019SAndroid Build Coastguard Worker terminate_lease(&lease);
780*d83cc019SAndroid Build Coastguard Worker
781*d83cc019SAndroid Build Coastguard Worker /* make sure the lease is gone */
782*d83cc019SAndroid Build Coastguard Worker mrl.lessee_id = lease.lessee_id;
783*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(revoke_lease(data->master.fd, &mrl), -ENOENT);
784*d83cc019SAndroid Build Coastguard Worker }
785*d83cc019SAndroid Build Coastguard Worker
786*d83cc019SAndroid Build Coastguard Worker /* Test leasing objects more than once */
lease_again(data_t * data)787*d83cc019SAndroid Build Coastguard Worker static void lease_again(data_t *data)
788*d83cc019SAndroid Build Coastguard Worker {
789*d83cc019SAndroid Build Coastguard Worker lease_t lease_a, lease_b;
790*d83cc019SAndroid Build Coastguard Worker
791*d83cc019SAndroid Build Coastguard Worker /* Create a valid lease */
792*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease_a), 0);
793*d83cc019SAndroid Build Coastguard Worker
794*d83cc019SAndroid Build Coastguard Worker /* Attempt to re-lease the same objects */
795*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease_b), -EBUSY);
796*d83cc019SAndroid Build Coastguard Worker
797*d83cc019SAndroid Build Coastguard Worker terminate_lease(&lease_a);
798*d83cc019SAndroid Build Coastguard Worker
799*d83cc019SAndroid Build Coastguard Worker /* Now attempt to lease the same objects */
800*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(make_lease(data, &lease_b), 0);
801*d83cc019SAndroid Build Coastguard Worker
802*d83cc019SAndroid Build Coastguard Worker terminate_lease(&lease_b);
803*d83cc019SAndroid Build Coastguard Worker }
804*d83cc019SAndroid Build Coastguard Worker
805*d83cc019SAndroid Build Coastguard Worker #define assert_unleased(ret) \
806*d83cc019SAndroid Build Coastguard Worker igt_assert_f((ret) == -EINVAL || (ret) == -ENOENT, \
807*d83cc019SAndroid Build Coastguard Worker "wrong return code %i, %s\n", ret, \
808*d83cc019SAndroid Build Coastguard Worker strerror(ret))
809*d83cc019SAndroid Build Coastguard Worker /* Test leasing an invalid connector */
lease_invalid_connector(data_t * data)810*d83cc019SAndroid Build Coastguard Worker static void lease_invalid_connector(data_t *data)
811*d83cc019SAndroid Build Coastguard Worker {
812*d83cc019SAndroid Build Coastguard Worker lease_t lease;
813*d83cc019SAndroid Build Coastguard Worker uint32_t save_connector_id;
814*d83cc019SAndroid Build Coastguard Worker int ret;
815*d83cc019SAndroid Build Coastguard Worker
816*d83cc019SAndroid Build Coastguard Worker /* Create an invalid lease */
817*d83cc019SAndroid Build Coastguard Worker save_connector_id = data->connector_id;
818*d83cc019SAndroid Build Coastguard Worker data->connector_id = 0xbaadf00d;
819*d83cc019SAndroid Build Coastguard Worker ret = make_lease(data, &lease);
820*d83cc019SAndroid Build Coastguard Worker data->connector_id = save_connector_id;
821*d83cc019SAndroid Build Coastguard Worker assert_unleased(ret);
822*d83cc019SAndroid Build Coastguard Worker }
823*d83cc019SAndroid Build Coastguard Worker
824*d83cc019SAndroid Build Coastguard Worker /* Test leasing an invalid crtc */
lease_invalid_crtc(data_t * data)825*d83cc019SAndroid Build Coastguard Worker static void lease_invalid_crtc(data_t *data)
826*d83cc019SAndroid Build Coastguard Worker {
827*d83cc019SAndroid Build Coastguard Worker lease_t lease;
828*d83cc019SAndroid Build Coastguard Worker uint32_t save_crtc_id;
829*d83cc019SAndroid Build Coastguard Worker int ret;
830*d83cc019SAndroid Build Coastguard Worker
831*d83cc019SAndroid Build Coastguard Worker /* Create an invalid lease */
832*d83cc019SAndroid Build Coastguard Worker save_crtc_id = data->crtc_id;
833*d83cc019SAndroid Build Coastguard Worker data->crtc_id = 0xbaadf00d;
834*d83cc019SAndroid Build Coastguard Worker ret = make_lease(data, &lease);
835*d83cc019SAndroid Build Coastguard Worker data->crtc_id = save_crtc_id;
836*d83cc019SAndroid Build Coastguard Worker assert_unleased(ret);
837*d83cc019SAndroid Build Coastguard Worker }
838*d83cc019SAndroid Build Coastguard Worker
lease_invalid_plane(data_t * data)839*d83cc019SAndroid Build Coastguard Worker static void lease_invalid_plane(data_t *data)
840*d83cc019SAndroid Build Coastguard Worker {
841*d83cc019SAndroid Build Coastguard Worker lease_t lease;
842*d83cc019SAndroid Build Coastguard Worker uint32_t save_plane_id;
843*d83cc019SAndroid Build Coastguard Worker int ret;
844*d83cc019SAndroid Build Coastguard Worker
845*d83cc019SAndroid Build Coastguard Worker /* Create an invalid lease */
846*d83cc019SAndroid Build Coastguard Worker save_plane_id = data->plane_id;
847*d83cc019SAndroid Build Coastguard Worker data->plane_id = 0xbaadf00d;
848*d83cc019SAndroid Build Coastguard Worker ret = make_lease(data, &lease);
849*d83cc019SAndroid Build Coastguard Worker data->plane_id = save_plane_id;
850*d83cc019SAndroid Build Coastguard Worker assert_unleased(ret);
851*d83cc019SAndroid Build Coastguard Worker }
852*d83cc019SAndroid Build Coastguard Worker
853*d83cc019SAndroid Build Coastguard Worker
run_test(data_t * data,void (* testfunc)(data_t *))854*d83cc019SAndroid Build Coastguard Worker static void run_test(data_t *data, void (*testfunc)(data_t *))
855*d83cc019SAndroid Build Coastguard Worker {
856*d83cc019SAndroid Build Coastguard Worker lease_t *master = &data->master;
857*d83cc019SAndroid Build Coastguard Worker igt_display_t *display = &master->display;
858*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
859*d83cc019SAndroid Build Coastguard Worker enum pipe p;
860*d83cc019SAndroid Build Coastguard Worker unsigned int valid_tests = 0;
861*d83cc019SAndroid Build Coastguard Worker
862*d83cc019SAndroid Build Coastguard Worker for_each_pipe_with_valid_output(display, p, output) {
863*d83cc019SAndroid Build Coastguard Worker igt_info("Beginning %s on pipe %s, connector %s\n",
864*d83cc019SAndroid Build Coastguard Worker igt_subtest_name(),
865*d83cc019SAndroid Build Coastguard Worker kmstest_pipe_name(p),
866*d83cc019SAndroid Build Coastguard Worker igt_output_name(output));
867*d83cc019SAndroid Build Coastguard Worker
868*d83cc019SAndroid Build Coastguard Worker data->pipe = p;
869*d83cc019SAndroid Build Coastguard Worker data->crtc_id = pipe_to_crtc_id(display, p);
870*d83cc019SAndroid Build Coastguard Worker data->connector_id = output->id;
871*d83cc019SAndroid Build Coastguard Worker data->plane_id =
872*d83cc019SAndroid Build Coastguard Worker igt_pipe_get_plane_type(&data->master.display.pipes[data->pipe],
873*d83cc019SAndroid Build Coastguard Worker DRM_PLANE_TYPE_PRIMARY)->drm_plane->plane_id;
874*d83cc019SAndroid Build Coastguard Worker
875*d83cc019SAndroid Build Coastguard Worker testfunc(data);
876*d83cc019SAndroid Build Coastguard Worker
877*d83cc019SAndroid Build Coastguard Worker igt_info("\n%s on pipe %s, connector %s: PASSED\n\n",
878*d83cc019SAndroid Build Coastguard Worker igt_subtest_name(),
879*d83cc019SAndroid Build Coastguard Worker kmstest_pipe_name(p),
880*d83cc019SAndroid Build Coastguard Worker igt_output_name(output));
881*d83cc019SAndroid Build Coastguard Worker
882*d83cc019SAndroid Build Coastguard Worker valid_tests++;
883*d83cc019SAndroid Build Coastguard Worker }
884*d83cc019SAndroid Build Coastguard Worker
885*d83cc019SAndroid Build Coastguard Worker igt_require_f(valid_tests,
886*d83cc019SAndroid Build Coastguard Worker "no valid crtc/connector combinations found\n");
887*d83cc019SAndroid Build Coastguard Worker }
888*d83cc019SAndroid Build Coastguard Worker
889*d83cc019SAndroid Build Coastguard Worker #define assert_double_id_err(ret) \
890*d83cc019SAndroid Build Coastguard Worker igt_assert_f((ret) == -EBUSY || (ret) == -ENOSPC, \
891*d83cc019SAndroid Build Coastguard Worker "wrong return code %i, %s\n", ret, \
892*d83cc019SAndroid Build Coastguard Worker strerror(ret))
invalid_create_leases(data_t * data)893*d83cc019SAndroid Build Coastguard Worker static void invalid_create_leases(data_t *data)
894*d83cc019SAndroid Build Coastguard Worker {
895*d83cc019SAndroid Build Coastguard Worker uint32_t object_ids[4];
896*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
897*d83cc019SAndroid Build Coastguard Worker drmModeRes *resources;
898*d83cc019SAndroid Build Coastguard Worker int tmp_fd, ret;
899*d83cc019SAndroid Build Coastguard Worker
900*d83cc019SAndroid Build Coastguard Worker /* empty lease */
901*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = 0;
902*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 0;
903*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
904*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -EINVAL);
905*d83cc019SAndroid Build Coastguard Worker
906*d83cc019SAndroid Build Coastguard Worker /* NULL array pointer */
907*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 1;
908*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -EFAULT);
909*d83cc019SAndroid Build Coastguard Worker
910*d83cc019SAndroid Build Coastguard Worker /* nil object */
911*d83cc019SAndroid Build Coastguard Worker object_ids[0] = 0;
912*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) object_ids;
913*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 1;
914*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -ENOENT);
915*d83cc019SAndroid Build Coastguard Worker
916*d83cc019SAndroid Build Coastguard Worker /* no crtc, non-universal_plane */
917*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0);
918*d83cc019SAndroid Build Coastguard Worker object_ids[0] = data->master.display.outputs[0].id;
919*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -EINVAL);
920*d83cc019SAndroid Build Coastguard Worker
921*d83cc019SAndroid Build Coastguard Worker /* no connector, non-universal_plane */
922*d83cc019SAndroid Build Coastguard Worker object_ids[0] = data->master.display.pipes[0].crtc_id;
923*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -EINVAL);
924*d83cc019SAndroid Build Coastguard Worker
925*d83cc019SAndroid Build Coastguard Worker /* sanity check */
926*d83cc019SAndroid Build Coastguard Worker object_ids[0] = data->master.display.pipes[0].crtc_id;
927*d83cc019SAndroid Build Coastguard Worker object_ids[1] = data->master.display.outputs[0].id;
928*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 2;
929*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), 0);
930*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
931*d83cc019SAndroid Build Coastguard Worker
932*d83cc019SAndroid Build Coastguard Worker /* no plane, universal planes */
933*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
934*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -EINVAL);
935*d83cc019SAndroid Build Coastguard Worker
936*d83cc019SAndroid Build Coastguard Worker /* sanity check */
937*d83cc019SAndroid Build Coastguard Worker object_ids[2] = igt_pipe_get_plane_type(&data->master.display.pipes[0],
938*d83cc019SAndroid Build Coastguard Worker DRM_PLANE_TYPE_PRIMARY)->drm_plane->plane_id;
939*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 3;
940*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), 0);
941*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
942*d83cc019SAndroid Build Coastguard Worker
943*d83cc019SAndroid Build Coastguard Worker /* array overflow, do a small scan around overflow sizes */
944*d83cc019SAndroid Build Coastguard Worker for (int i = 1; i <= 4; i++) {
945*d83cc019SAndroid Build Coastguard Worker mcl.object_count = UINT32_MAX / sizeof(object_ids[0]) + i;
946*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -ENOMEM);
947*d83cc019SAndroid Build Coastguard Worker }
948*d83cc019SAndroid Build Coastguard Worker
949*d83cc019SAndroid Build Coastguard Worker /* sanity check */
950*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 3;
951*d83cc019SAndroid Build Coastguard Worker mcl.flags = O_CLOEXEC | O_NONBLOCK;
952*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), 0);
953*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
954*d83cc019SAndroid Build Coastguard Worker
955*d83cc019SAndroid Build Coastguard Worker /* invalid flags */
956*d83cc019SAndroid Build Coastguard Worker mcl.flags = -1;
957*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -EINVAL);
958*d83cc019SAndroid Build Coastguard Worker
959*d83cc019SAndroid Build Coastguard Worker /* no subleasing */
960*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 3;
961*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
962*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), 0);
963*d83cc019SAndroid Build Coastguard Worker tmp_fd = mcl.fd;
964*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(tmp_fd, &mcl), -EINVAL);
965*d83cc019SAndroid Build Coastguard Worker close(tmp_fd);
966*d83cc019SAndroid Build Coastguard Worker
967*d83cc019SAndroid Build Coastguard Worker /* no double-leasing */
968*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), 0);
969*d83cc019SAndroid Build Coastguard Worker tmp_fd = mcl.fd;
970*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -EBUSY);
971*d83cc019SAndroid Build Coastguard Worker close(tmp_fd);
972*d83cc019SAndroid Build Coastguard Worker
973*d83cc019SAndroid Build Coastguard Worker /* no double leasing */
974*d83cc019SAndroid Build Coastguard Worker object_ids[3] = object_ids[2];
975*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 4;
976*d83cc019SAndroid Build Coastguard Worker /* Note: the ENOSPC is from idr double-insertion failing */
977*d83cc019SAndroid Build Coastguard Worker ret = create_lease(data->master.fd, &mcl);
978*d83cc019SAndroid Build Coastguard Worker assert_double_id_err(ret);
979*d83cc019SAndroid Build Coastguard Worker
980*d83cc019SAndroid Build Coastguard Worker /* no encoder leasing */
981*d83cc019SAndroid Build Coastguard Worker resources = drmModeGetResources(data->master.fd);
982*d83cc019SAndroid Build Coastguard Worker igt_assert(resources);
983*d83cc019SAndroid Build Coastguard Worker igt_assert(resources->count_encoders > 0);
984*d83cc019SAndroid Build Coastguard Worker object_ids[3] = resources->encoders[0];
985*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), -EINVAL);
986*d83cc019SAndroid Build Coastguard Worker drmModeFreeResources(resources);
987*d83cc019SAndroid Build Coastguard Worker }
988*d83cc019SAndroid Build Coastguard Worker
check_crtc_masks(int master_fd,int lease_fd,uint32_t crtc_mask)989*d83cc019SAndroid Build Coastguard Worker static void check_crtc_masks(int master_fd, int lease_fd, uint32_t crtc_mask)
990*d83cc019SAndroid Build Coastguard Worker {
991*d83cc019SAndroid Build Coastguard Worker drmModeRes *resources;
992*d83cc019SAndroid Build Coastguard Worker drmModePlaneRes *plane_resources;
993*d83cc019SAndroid Build Coastguard Worker int i;
994*d83cc019SAndroid Build Coastguard Worker
995*d83cc019SAndroid Build Coastguard Worker resources = drmModeGetResources(master_fd);
996*d83cc019SAndroid Build Coastguard Worker igt_assert(resources);
997*d83cc019SAndroid Build Coastguard Worker plane_resources = drmModeGetPlaneResources(master_fd);
998*d83cc019SAndroid Build Coastguard Worker igt_assert(plane_resources);
999*d83cc019SAndroid Build Coastguard Worker
1000*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < resources->count_encoders; i++) {
1001*d83cc019SAndroid Build Coastguard Worker drmModeEncoder *master_e, *lease_e;
1002*d83cc019SAndroid Build Coastguard Worker bool possible;
1003*d83cc019SAndroid Build Coastguard Worker
1004*d83cc019SAndroid Build Coastguard Worker master_e = drmModeGetEncoder(master_fd, resources->encoders[i]);
1005*d83cc019SAndroid Build Coastguard Worker igt_assert(master_e);
1006*d83cc019SAndroid Build Coastguard Worker lease_e = drmModeGetEncoder(lease_fd, resources->encoders[i]);
1007*d83cc019SAndroid Build Coastguard Worker igt_assert(lease_e);
1008*d83cc019SAndroid Build Coastguard Worker
1009*d83cc019SAndroid Build Coastguard Worker possible = master_e->possible_crtcs & crtc_mask;
1010*d83cc019SAndroid Build Coastguard Worker
1011*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(lease_e->possible_crtcs,
1012*d83cc019SAndroid Build Coastguard Worker possible ? 1 : 0);
1013*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(master_e->possible_crtcs & crtc_mask,
1014*d83cc019SAndroid Build Coastguard Worker possible ? crtc_mask : 0);
1015*d83cc019SAndroid Build Coastguard Worker drmModeFreeEncoder(master_e);
1016*d83cc019SAndroid Build Coastguard Worker drmModeFreeEncoder(lease_e);
1017*d83cc019SAndroid Build Coastguard Worker }
1018*d83cc019SAndroid Build Coastguard Worker
1019*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < plane_resources->count_planes; i++) {
1020*d83cc019SAndroid Build Coastguard Worker drmModePlane *master_p, *lease_p;
1021*d83cc019SAndroid Build Coastguard Worker bool possible;
1022*d83cc019SAndroid Build Coastguard Worker
1023*d83cc019SAndroid Build Coastguard Worker master_p = drmModeGetPlane(master_fd, plane_resources->planes[i]);
1024*d83cc019SAndroid Build Coastguard Worker igt_assert(master_p);
1025*d83cc019SAndroid Build Coastguard Worker lease_p = drmModeGetPlane(lease_fd, plane_resources->planes[i]);
1026*d83cc019SAndroid Build Coastguard Worker igt_assert(lease_p);
1027*d83cc019SAndroid Build Coastguard Worker
1028*d83cc019SAndroid Build Coastguard Worker possible = master_p->possible_crtcs & crtc_mask;
1029*d83cc019SAndroid Build Coastguard Worker
1030*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(lease_p->possible_crtcs,
1031*d83cc019SAndroid Build Coastguard Worker possible ? 1 : 0);
1032*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(master_p->possible_crtcs & crtc_mask,
1033*d83cc019SAndroid Build Coastguard Worker possible ? crtc_mask : 0);
1034*d83cc019SAndroid Build Coastguard Worker drmModeFreePlane(master_p);
1035*d83cc019SAndroid Build Coastguard Worker drmModeFreePlane(lease_p);
1036*d83cc019SAndroid Build Coastguard Worker }
1037*d83cc019SAndroid Build Coastguard Worker
1038*d83cc019SAndroid Build Coastguard Worker drmModeFreePlaneResources(plane_resources);
1039*d83cc019SAndroid Build Coastguard Worker drmModeFreeResources(resources);
1040*d83cc019SAndroid Build Coastguard Worker }
1041*d83cc019SAndroid Build Coastguard Worker
possible_crtcs_filtering(data_t * data)1042*d83cc019SAndroid Build Coastguard Worker static void possible_crtcs_filtering(data_t *data)
1043*d83cc019SAndroid Build Coastguard Worker {
1044*d83cc019SAndroid Build Coastguard Worker uint32_t *object_ids;
1045*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
1046*d83cc019SAndroid Build Coastguard Worker drmModeRes *resources;
1047*d83cc019SAndroid Build Coastguard Worker drmModePlaneRes *plane_resources;
1048*d83cc019SAndroid Build Coastguard Worker int i;
1049*d83cc019SAndroid Build Coastguard Worker int master_fd = data->master.fd;
1050*d83cc019SAndroid Build Coastguard Worker
1051*d83cc019SAndroid Build Coastguard Worker resources = drmModeGetResources(master_fd);
1052*d83cc019SAndroid Build Coastguard Worker igt_assert(resources);
1053*d83cc019SAndroid Build Coastguard Worker plane_resources = drmModeGetPlaneResources(master_fd);
1054*d83cc019SAndroid Build Coastguard Worker igt_assert(plane_resources);
1055*d83cc019SAndroid Build Coastguard Worker mcl.object_count = resources->count_connectors +
1056*d83cc019SAndroid Build Coastguard Worker plane_resources->count_planes + 1;
1057*d83cc019SAndroid Build Coastguard Worker object_ids = calloc(mcl.object_count, sizeof(*object_ids));
1058*d83cc019SAndroid Build Coastguard Worker igt_assert(object_ids);
1059*d83cc019SAndroid Build Coastguard Worker
1060*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < resources->count_connectors; i++)
1061*d83cc019SAndroid Build Coastguard Worker object_ids[i] = resources->connectors[i];
1062*d83cc019SAndroid Build Coastguard Worker
1063*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < plane_resources->count_planes; i++)
1064*d83cc019SAndroid Build Coastguard Worker object_ids[i + resources->count_connectors] =
1065*d83cc019SAndroid Build Coastguard Worker plane_resources->planes[i];
1066*d83cc019SAndroid Build Coastguard Worker
1067*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) object_ids;
1068*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
1069*d83cc019SAndroid Build Coastguard Worker
1070*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < resources->count_crtcs; i++) {
1071*d83cc019SAndroid Build Coastguard Worker int lease_fd;
1072*d83cc019SAndroid Build Coastguard Worker
1073*d83cc019SAndroid Build Coastguard Worker object_ids[mcl.object_count - 1] =
1074*d83cc019SAndroid Build Coastguard Worker resources->crtcs[i];
1075*d83cc019SAndroid Build Coastguard Worker
1076*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(master_fd, &mcl), 0);
1077*d83cc019SAndroid Build Coastguard Worker lease_fd = mcl.fd;
1078*d83cc019SAndroid Build Coastguard Worker
1079*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(lease_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
1080*d83cc019SAndroid Build Coastguard Worker
1081*d83cc019SAndroid Build Coastguard Worker check_crtc_masks(master_fd, lease_fd, 1 << i);
1082*d83cc019SAndroid Build Coastguard Worker
1083*d83cc019SAndroid Build Coastguard Worker close(lease_fd);
1084*d83cc019SAndroid Build Coastguard Worker }
1085*d83cc019SAndroid Build Coastguard Worker
1086*d83cc019SAndroid Build Coastguard Worker free(object_ids);
1087*d83cc019SAndroid Build Coastguard Worker drmModeFreePlaneResources(plane_resources);
1088*d83cc019SAndroid Build Coastguard Worker drmModeFreeResources(resources);
1089*d83cc019SAndroid Build Coastguard Worker }
1090*d83cc019SAndroid Build Coastguard Worker
is_master(int fd)1091*d83cc019SAndroid Build Coastguard Worker static bool is_master(int fd)
1092*d83cc019SAndroid Build Coastguard Worker {
1093*d83cc019SAndroid Build Coastguard Worker /* FIXME: replace with drmIsMaster once we bumped libdrm version */
1094*d83cc019SAndroid Build Coastguard Worker return drmAuthMagic(fd, 0) != -EACCES;
1095*d83cc019SAndroid Build Coastguard Worker }
1096*d83cc019SAndroid Build Coastguard Worker
_create_simple_lease(int master_fd,data_t * data,int expected_ret)1097*d83cc019SAndroid Build Coastguard Worker static int _create_simple_lease(int master_fd, data_t *data, int expected_ret)
1098*d83cc019SAndroid Build Coastguard Worker {
1099*d83cc019SAndroid Build Coastguard Worker uint32_t object_ids[3];
1100*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
1101*d83cc019SAndroid Build Coastguard Worker
1102*d83cc019SAndroid Build Coastguard Worker object_ids[0] = data->master.display.pipes[0].crtc_id;
1103*d83cc019SAndroid Build Coastguard Worker object_ids[1] = data->master.display.outputs[0].id;
1104*d83cc019SAndroid Build Coastguard Worker object_ids[2] = igt_pipe_get_plane_type(&data->master.display.pipes[0],
1105*d83cc019SAndroid Build Coastguard Worker DRM_PLANE_TYPE_PRIMARY)->drm_plane->plane_id;
1106*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) object_ids;
1107*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 3;
1108*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
1109*d83cc019SAndroid Build Coastguard Worker
1110*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(master_fd, &mcl), expected_ret);
1111*d83cc019SAndroid Build Coastguard Worker
1112*d83cc019SAndroid Build Coastguard Worker return expected_ret == 0 ? mcl.fd : 0;
1113*d83cc019SAndroid Build Coastguard Worker }
1114*d83cc019SAndroid Build Coastguard Worker
create_simple_lease(int master_fd,data_t * data)1115*d83cc019SAndroid Build Coastguard Worker static int create_simple_lease(int master_fd, data_t *data)
1116*d83cc019SAndroid Build Coastguard Worker {
1117*d83cc019SAndroid Build Coastguard Worker return _create_simple_lease(master_fd, data, 0);
1118*d83cc019SAndroid Build Coastguard Worker }
1119*d83cc019SAndroid Build Coastguard Worker
1120*d83cc019SAndroid Build Coastguard Worker /* check lease master status in lockdep with lessors, but can't change it
1121*d83cc019SAndroid Build Coastguard Worker * themselves */
master_vs_lease(data_t * data)1122*d83cc019SAndroid Build Coastguard Worker static void master_vs_lease(data_t *data)
1123*d83cc019SAndroid Build Coastguard Worker {
1124*d83cc019SAndroid Build Coastguard Worker int lease_fd;
1125*d83cc019SAndroid Build Coastguard Worker
1126*d83cc019SAndroid Build Coastguard Worker lease_fd = create_simple_lease(data->master.fd, data);
1127*d83cc019SAndroid Build Coastguard Worker
1128*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(drmDropMaster(lease_fd), -1);
1129*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(errno, EINVAL);
1130*d83cc019SAndroid Build Coastguard Worker
1131*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(data->master.fd));
1132*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(lease_fd));
1133*d83cc019SAndroid Build Coastguard Worker
1134*d83cc019SAndroid Build Coastguard Worker igt_device_drop_master(data->master.fd);
1135*d83cc019SAndroid Build Coastguard Worker
1136*d83cc019SAndroid Build Coastguard Worker igt_assert(!is_master(data->master.fd));
1137*d83cc019SAndroid Build Coastguard Worker igt_assert(!is_master(lease_fd));
1138*d83cc019SAndroid Build Coastguard Worker
1139*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(drmSetMaster(lease_fd), -1);
1140*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(errno, EINVAL);
1141*d83cc019SAndroid Build Coastguard Worker
1142*d83cc019SAndroid Build Coastguard Worker igt_device_set_master(data->master.fd);
1143*d83cc019SAndroid Build Coastguard Worker
1144*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(data->master.fd));
1145*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(lease_fd));
1146*d83cc019SAndroid Build Coastguard Worker
1147*d83cc019SAndroid Build Coastguard Worker close(lease_fd);
1148*d83cc019SAndroid Build Coastguard Worker }
1149*d83cc019SAndroid Build Coastguard Worker
multimaster_lease(data_t * data)1150*d83cc019SAndroid Build Coastguard Worker static void multimaster_lease(data_t *data)
1151*d83cc019SAndroid Build Coastguard Worker {
1152*d83cc019SAndroid Build Coastguard Worker int lease_fd, master2_fd, lease2_fd;
1153*d83cc019SAndroid Build Coastguard Worker
1154*d83cc019SAndroid Build Coastguard Worker lease_fd = create_simple_lease(data->master.fd, data);
1155*d83cc019SAndroid Build Coastguard Worker
1156*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(data->master.fd));
1157*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(lease_fd));
1158*d83cc019SAndroid Build Coastguard Worker
1159*d83cc019SAndroid Build Coastguard Worker master2_fd = drm_open_driver(DRIVER_ANY);
1160*d83cc019SAndroid Build Coastguard Worker
1161*d83cc019SAndroid Build Coastguard Worker igt_assert(!is_master(master2_fd));
1162*d83cc019SAndroid Build Coastguard Worker
1163*d83cc019SAndroid Build Coastguard Worker _create_simple_lease(master2_fd, data, -EACCES);
1164*d83cc019SAndroid Build Coastguard Worker
1165*d83cc019SAndroid Build Coastguard Worker igt_device_drop_master(data->master.fd);
1166*d83cc019SAndroid Build Coastguard Worker igt_device_set_master(master2_fd);
1167*d83cc019SAndroid Build Coastguard Worker
1168*d83cc019SAndroid Build Coastguard Worker igt_assert(!is_master(data->master.fd));
1169*d83cc019SAndroid Build Coastguard Worker igt_assert(!is_master(lease_fd));
1170*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(master2_fd));
1171*d83cc019SAndroid Build Coastguard Worker
1172*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(master2_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
1173*d83cc019SAndroid Build Coastguard Worker lease2_fd = create_simple_lease(master2_fd, data);
1174*d83cc019SAndroid Build Coastguard Worker
1175*d83cc019SAndroid Build Coastguard Worker close(master2_fd); /* close is an implicit DropMaster */
1176*d83cc019SAndroid Build Coastguard Worker igt_assert(!is_master(lease2_fd));
1177*d83cc019SAndroid Build Coastguard Worker
1178*d83cc019SAndroid Build Coastguard Worker igt_device_set_master(data->master.fd);
1179*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(data->master.fd));
1180*d83cc019SAndroid Build Coastguard Worker igt_assert(is_master(lease_fd));
1181*d83cc019SAndroid Build Coastguard Worker
1182*d83cc019SAndroid Build Coastguard Worker close(lease2_fd);
1183*d83cc019SAndroid Build Coastguard Worker close(lease_fd);
1184*d83cc019SAndroid Build Coastguard Worker }
1185*d83cc019SAndroid Build Coastguard Worker
implicit_plane_lease(data_t * data)1186*d83cc019SAndroid Build Coastguard Worker static void implicit_plane_lease(data_t *data)
1187*d83cc019SAndroid Build Coastguard Worker {
1188*d83cc019SAndroid Build Coastguard Worker uint32_t object_ids[3];
1189*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_create_lease mcl;
1190*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_get_lease mgl;
1191*d83cc019SAndroid Build Coastguard Worker int ret;
1192*d83cc019SAndroid Build Coastguard Worker uint32_t cursor_id = igt_pipe_get_plane_type(&data->master.display.pipes[0],
1193*d83cc019SAndroid Build Coastguard Worker DRM_PLANE_TYPE_CURSOR)->drm_plane->plane_id;
1194*d83cc019SAndroid Build Coastguard Worker
1195*d83cc019SAndroid Build Coastguard Worker object_ids[0] = data->master.display.pipes[0].crtc_id;
1196*d83cc019SAndroid Build Coastguard Worker object_ids[1] = data->master.display.outputs[0].id;
1197*d83cc019SAndroid Build Coastguard Worker object_ids[2] = igt_pipe_get_plane_type(&data->master.display.pipes[0],
1198*d83cc019SAndroid Build Coastguard Worker DRM_PLANE_TYPE_PRIMARY)->drm_plane->plane_id;
1199*d83cc019SAndroid Build Coastguard Worker mcl.object_ids = (uint64_t) (uintptr_t) object_ids;
1200*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 3;
1201*d83cc019SAndroid Build Coastguard Worker mcl.flags = 0;
1202*d83cc019SAndroid Build Coastguard Worker
1203*d83cc019SAndroid Build Coastguard Worker /* sanity check */
1204*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), 0);
1205*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
1206*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0);
1207*d83cc019SAndroid Build Coastguard Worker
1208*d83cc019SAndroid Build Coastguard Worker /* non universal plane automatically adds primary/cursor plane */
1209*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 2;
1210*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(create_lease(data->master.fd, &mcl), 0);
1211*d83cc019SAndroid Build Coastguard Worker
1212*d83cc019SAndroid Build Coastguard Worker mgl.pad = 0;
1213*d83cc019SAndroid Build Coastguard Worker mgl.count_objects = 0;
1214*d83cc019SAndroid Build Coastguard Worker mgl.objects_ptr = 0;
1215*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(get_lease(mcl.fd, &mgl), 0);
1216*d83cc019SAndroid Build Coastguard Worker
1217*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mgl.count_objects, 3 + (cursor_id ? 1 : 0));
1218*d83cc019SAndroid Build Coastguard Worker
1219*d83cc019SAndroid Build Coastguard Worker close(mcl.fd);
1220*d83cc019SAndroid Build Coastguard Worker
1221*d83cc019SAndroid Build Coastguard Worker /* check that implicit lease doesn't lead to confusion when
1222*d83cc019SAndroid Build Coastguard Worker * explicitly adding primary plane */
1223*d83cc019SAndroid Build Coastguard Worker mcl.object_count = 3;
1224*d83cc019SAndroid Build Coastguard Worker ret = create_lease(data->master.fd, &mcl);
1225*d83cc019SAndroid Build Coastguard Worker assert_double_id_err(ret);
1226*d83cc019SAndroid Build Coastguard Worker
1227*d83cc019SAndroid Build Coastguard Worker /* same for the cursor */
1228*d83cc019SAndroid Build Coastguard Worker object_ids[2] = cursor_id;
1229*d83cc019SAndroid Build Coastguard Worker ret = create_lease(data->master.fd, &mcl);
1230*d83cc019SAndroid Build Coastguard Worker assert_double_id_err(ret);
1231*d83cc019SAndroid Build Coastguard Worker
1232*d83cc019SAndroid Build Coastguard Worker drmSetClientCap(data->master.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
1233*d83cc019SAndroid Build Coastguard Worker }
1234*d83cc019SAndroid Build Coastguard Worker
lease_uevent(data_t * data)1235*d83cc019SAndroid Build Coastguard Worker static void lease_uevent(data_t *data)
1236*d83cc019SAndroid Build Coastguard Worker {
1237*d83cc019SAndroid Build Coastguard Worker int lease_fd;
1238*d83cc019SAndroid Build Coastguard Worker struct local_drm_mode_list_lessees mll;
1239*d83cc019SAndroid Build Coastguard Worker struct udev_monitor *uevent_monitor;
1240*d83cc019SAndroid Build Coastguard Worker
1241*d83cc019SAndroid Build Coastguard Worker uevent_monitor = igt_watch_hotplug();
1242*d83cc019SAndroid Build Coastguard Worker
1243*d83cc019SAndroid Build Coastguard Worker igt_flush_hotplugs(uevent_monitor);
1244*d83cc019SAndroid Build Coastguard Worker
1245*d83cc019SAndroid Build Coastguard Worker lease_fd = create_simple_lease(data->master.fd, data);
1246*d83cc019SAndroid Build Coastguard Worker
1247*d83cc019SAndroid Build Coastguard Worker igt_assert(!igt_lease_change_detected(uevent_monitor, 1));
1248*d83cc019SAndroid Build Coastguard Worker
1249*d83cc019SAndroid Build Coastguard Worker mll.pad = 0;
1250*d83cc019SAndroid Build Coastguard Worker mll.count_lessees = 0;
1251*d83cc019SAndroid Build Coastguard Worker mll.lessees_ptr = 0;
1252*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(list_lessees(data->master.fd, &mll), 0);
1253*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mll.count_lessees, 1);
1254*d83cc019SAndroid Build Coastguard Worker
1255*d83cc019SAndroid Build Coastguard Worker close(lease_fd);
1256*d83cc019SAndroid Build Coastguard Worker
1257*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_lease_change_detected(uevent_monitor, 1));
1258*d83cc019SAndroid Build Coastguard Worker
1259*d83cc019SAndroid Build Coastguard Worker mll.lessees_ptr = 0;
1260*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(list_lessees(data->master.fd, &mll), 0);
1261*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mll.count_lessees, 0);
1262*d83cc019SAndroid Build Coastguard Worker
1263*d83cc019SAndroid Build Coastguard Worker igt_cleanup_hotplug(uevent_monitor);
1264*d83cc019SAndroid Build Coastguard Worker }
1265*d83cc019SAndroid Build Coastguard Worker
1266*d83cc019SAndroid Build Coastguard Worker igt_main
1267*d83cc019SAndroid Build Coastguard Worker {
1268*d83cc019SAndroid Build Coastguard Worker data_t data;
1269*d83cc019SAndroid Build Coastguard Worker const struct {
1270*d83cc019SAndroid Build Coastguard Worker const char *name;
1271*d83cc019SAndroid Build Coastguard Worker void (*func)(data_t *);
1272*d83cc019SAndroid Build Coastguard Worker } funcs[] = {
1273*d83cc019SAndroid Build Coastguard Worker { "simple_lease", simple_lease },
1274*d83cc019SAndroid Build Coastguard Worker { "lessee_list", lessee_list },
1275*d83cc019SAndroid Build Coastguard Worker { "lease_get", lease_get },
1276*d83cc019SAndroid Build Coastguard Worker { "lease_unleased_connector", lease_unleased_connector },
1277*d83cc019SAndroid Build Coastguard Worker { "lease_unleased_crtc", lease_unleased_crtc },
1278*d83cc019SAndroid Build Coastguard Worker { "lease_revoke", lease_revoke },
1279*d83cc019SAndroid Build Coastguard Worker { "lease_again", lease_again },
1280*d83cc019SAndroid Build Coastguard Worker { "lease_invalid_connector", lease_invalid_connector },
1281*d83cc019SAndroid Build Coastguard Worker { "lease_invalid_crtc", lease_invalid_crtc },
1282*d83cc019SAndroid Build Coastguard Worker { "lease_invalid_plane", lease_invalid_plane },
1283*d83cc019SAndroid Build Coastguard Worker { "page_flip_implicit_plane", page_flip_implicit_plane },
1284*d83cc019SAndroid Build Coastguard Worker { "setcrtc_implicit_plane", setcrtc_implicit_plane },
1285*d83cc019SAndroid Build Coastguard Worker { "cursor_implicit_plane", cursor_implicit_plane },
1286*d83cc019SAndroid Build Coastguard Worker { "atomic_implicit_crtc", atomic_implicit_crtc },
1287*d83cc019SAndroid Build Coastguard Worker { }
1288*d83cc019SAndroid Build Coastguard Worker }, *f;
1289*d83cc019SAndroid Build Coastguard Worker
1290*d83cc019SAndroid Build Coastguard Worker igt_fixture {
1291*d83cc019SAndroid Build Coastguard Worker data.master.fd = drm_open_driver_master(DRIVER_ANY);
1292*d83cc019SAndroid Build Coastguard Worker kmstest_set_vt_graphics_mode();
1293*d83cc019SAndroid Build Coastguard Worker igt_display_require(&data.master.display, data.master.fd);
1294*d83cc019SAndroid Build Coastguard Worker }
1295*d83cc019SAndroid Build Coastguard Worker
1296*d83cc019SAndroid Build Coastguard Worker for (f = funcs; f->name; f++) {
1297*d83cc019SAndroid Build Coastguard Worker
1298*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%s", f->name) {
1299*d83cc019SAndroid Build Coastguard Worker run_test(&data, f->func);
1300*d83cc019SAndroid Build Coastguard Worker }
1301*d83cc019SAndroid Build Coastguard Worker }
1302*d83cc019SAndroid Build Coastguard Worker
1303*d83cc019SAndroid Build Coastguard Worker igt_subtest("invalid-create-leases")
1304*d83cc019SAndroid Build Coastguard Worker invalid_create_leases(&data);
1305*d83cc019SAndroid Build Coastguard Worker
1306*d83cc019SAndroid Build Coastguard Worker igt_subtest("possible-crtcs-filtering")
1307*d83cc019SAndroid Build Coastguard Worker possible_crtcs_filtering(&data);
1308*d83cc019SAndroid Build Coastguard Worker
1309*d83cc019SAndroid Build Coastguard Worker igt_subtest("master-vs-lease")
1310*d83cc019SAndroid Build Coastguard Worker master_vs_lease(&data);
1311*d83cc019SAndroid Build Coastguard Worker
1312*d83cc019SAndroid Build Coastguard Worker igt_subtest("multimaster-lease")
1313*d83cc019SAndroid Build Coastguard Worker multimaster_lease(&data);
1314*d83cc019SAndroid Build Coastguard Worker
1315*d83cc019SAndroid Build Coastguard Worker igt_subtest("implicit-plane-lease")
1316*d83cc019SAndroid Build Coastguard Worker implicit_plane_lease(&data);
1317*d83cc019SAndroid Build Coastguard Worker
1318*d83cc019SAndroid Build Coastguard Worker igt_subtest("lease-uevent")
1319*d83cc019SAndroid Build Coastguard Worker lease_uevent(&data);
1320*d83cc019SAndroid Build Coastguard Worker }
1321