1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2016 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker *
4*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker *
11*d83cc019SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker * Software.
14*d83cc019SAndroid Build Coastguard Worker *
15*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker */
23*d83cc019SAndroid Build Coastguard Worker
24*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
25*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
26*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
27*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
29*d83cc019SAndroid Build Coastguard Worker #include <string.h>
30*d83cc019SAndroid Build Coastguard Worker #include <time.h>
31*d83cc019SAndroid Build Coastguard Worker
32*d83cc019SAndroid Build Coastguard Worker struct additional_test {
33*d83cc019SAndroid Build Coastguard Worker const char *name;
34*d83cc019SAndroid Build Coastguard Worker uint32_t obj_type;
35*d83cc019SAndroid Build Coastguard Worker void (*prop_test)(int fd, uint32_t id, uint32_t type, drmModePropertyPtr prop,
36*d83cc019SAndroid Build Coastguard Worker uint32_t prop_id, uint64_t prop_value, bool atomic);
37*d83cc019SAndroid Build Coastguard Worker };
38*d83cc019SAndroid Build Coastguard Worker
prepare_pipe(igt_display_t * display,enum pipe pipe,igt_output_t * output,struct igt_fb * fb)39*d83cc019SAndroid Build Coastguard Worker static void prepare_pipe(igt_display_t *display, enum pipe pipe, igt_output_t *output, struct igt_fb *fb)
40*d83cc019SAndroid Build Coastguard Worker {
41*d83cc019SAndroid Build Coastguard Worker drmModeModeInfo *mode = igt_output_get_mode(output);
42*d83cc019SAndroid Build Coastguard Worker
43*d83cc019SAndroid Build Coastguard Worker igt_create_pattern_fb(display->drm_fd, mode->hdisplay, mode->vdisplay,
44*d83cc019SAndroid Build Coastguard Worker DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE, fb);
45*d83cc019SAndroid Build Coastguard Worker
46*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output, pipe);
47*d83cc019SAndroid Build Coastguard Worker
48*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY), fb);
49*d83cc019SAndroid Build Coastguard Worker
50*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
51*d83cc019SAndroid Build Coastguard Worker }
52*d83cc019SAndroid Build Coastguard Worker
cleanup_pipe(igt_display_t * display,enum pipe pipe,igt_output_t * output,struct igt_fb * fb)53*d83cc019SAndroid Build Coastguard Worker static void cleanup_pipe(igt_display_t *display, enum pipe pipe, igt_output_t *output, struct igt_fb *fb)
54*d83cc019SAndroid Build Coastguard Worker {
55*d83cc019SAndroid Build Coastguard Worker igt_plane_t *plane;
56*d83cc019SAndroid Build Coastguard Worker
57*d83cc019SAndroid Build Coastguard Worker for_each_plane_on_pipe(display, pipe, plane)
58*d83cc019SAndroid Build Coastguard Worker igt_plane_set_fb(plane, NULL);
59*d83cc019SAndroid Build Coastguard Worker
60*d83cc019SAndroid Build Coastguard Worker igt_output_set_pipe(output, PIPE_NONE);
61*d83cc019SAndroid Build Coastguard Worker
62*d83cc019SAndroid Build Coastguard Worker igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
63*d83cc019SAndroid Build Coastguard Worker
64*d83cc019SAndroid Build Coastguard Worker igt_remove_fb(display->drm_fd, fb);
65*d83cc019SAndroid Build Coastguard Worker }
66*d83cc019SAndroid Build Coastguard Worker
ignore_property(uint32_t obj_type,uint32_t prop_flags,const char * name,bool atomic)67*d83cc019SAndroid Build Coastguard Worker static bool ignore_property(uint32_t obj_type, uint32_t prop_flags,
68*d83cc019SAndroid Build Coastguard Worker const char *name, bool atomic)
69*d83cc019SAndroid Build Coastguard Worker {
70*d83cc019SAndroid Build Coastguard Worker if (prop_flags & DRM_MODE_PROP_IMMUTABLE)
71*d83cc019SAndroid Build Coastguard Worker return true;
72*d83cc019SAndroid Build Coastguard Worker
73*d83cc019SAndroid Build Coastguard Worker switch (obj_type) {
74*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_OBJECT_CONNECTOR:
75*d83cc019SAndroid Build Coastguard Worker if (atomic && !strcmp(name, "DPMS"))
76*d83cc019SAndroid Build Coastguard Worker return true;
77*d83cc019SAndroid Build Coastguard Worker break;
78*d83cc019SAndroid Build Coastguard Worker default:
79*d83cc019SAndroid Build Coastguard Worker break;
80*d83cc019SAndroid Build Coastguard Worker }
81*d83cc019SAndroid Build Coastguard Worker
82*d83cc019SAndroid Build Coastguard Worker return false;
83*d83cc019SAndroid Build Coastguard Worker }
84*d83cc019SAndroid Build Coastguard Worker
max_bpc_prop_test(int fd,uint32_t id,uint32_t type,drmModePropertyPtr prop,uint32_t prop_id,uint64_t prop_value,bool atomic)85*d83cc019SAndroid Build Coastguard Worker static void max_bpc_prop_test(int fd, uint32_t id, uint32_t type, drmModePropertyPtr prop,
86*d83cc019SAndroid Build Coastguard Worker uint32_t prop_id, uint64_t prop_value, bool atomic)
87*d83cc019SAndroid Build Coastguard Worker {
88*d83cc019SAndroid Build Coastguard Worker drmModeAtomicReqPtr req = NULL;
89*d83cc019SAndroid Build Coastguard Worker int i, ret;
90*d83cc019SAndroid Build Coastguard Worker
91*d83cc019SAndroid Build Coastguard Worker if (atomic)
92*d83cc019SAndroid Build Coastguard Worker req = drmModeAtomicAlloc();
93*d83cc019SAndroid Build Coastguard Worker
94*d83cc019SAndroid Build Coastguard Worker for (i = prop->values[0]; i <= prop->values[1]; i++) {
95*d83cc019SAndroid Build Coastguard Worker if (!atomic) {
96*d83cc019SAndroid Build Coastguard Worker ret = drmModeObjectSetProperty(fd, id, type, prop_id, i);
97*d83cc019SAndroid Build Coastguard Worker
98*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, 0);
99*d83cc019SAndroid Build Coastguard Worker } else {
100*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicAddProperty(req, id, prop_id, i);
101*d83cc019SAndroid Build Coastguard Worker igt_assert(ret >= 0);
102*d83cc019SAndroid Build Coastguard Worker
103*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicCommit(fd, req, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
104*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, 0);
105*d83cc019SAndroid Build Coastguard Worker }
106*d83cc019SAndroid Build Coastguard Worker }
107*d83cc019SAndroid Build Coastguard Worker
108*d83cc019SAndroid Build Coastguard Worker if (atomic)
109*d83cc019SAndroid Build Coastguard Worker drmModeAtomicFree(req);
110*d83cc019SAndroid Build Coastguard Worker }
111*d83cc019SAndroid Build Coastguard Worker
112*d83cc019SAndroid Build Coastguard Worker static const struct additional_test property_functional_test[] = {
113*d83cc019SAndroid Build Coastguard Worker {"max bpc", DRM_MODE_OBJECT_CONNECTOR,
114*d83cc019SAndroid Build Coastguard Worker max_bpc_prop_test},
115*d83cc019SAndroid Build Coastguard Worker };
116*d83cc019SAndroid Build Coastguard Worker
has_additional_test_lookup(uint32_t obj_type,const char * name,bool atomic,int * index)117*d83cc019SAndroid Build Coastguard Worker static bool has_additional_test_lookup(uint32_t obj_type, const char *name,
118*d83cc019SAndroid Build Coastguard Worker bool atomic, int *index)
119*d83cc019SAndroid Build Coastguard Worker {
120*d83cc019SAndroid Build Coastguard Worker int i;
121*d83cc019SAndroid Build Coastguard Worker
122*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(property_functional_test); i++)
123*d83cc019SAndroid Build Coastguard Worker if (property_functional_test[i].obj_type == obj_type &&
124*d83cc019SAndroid Build Coastguard Worker !strcmp(name, property_functional_test[i].name)) {
125*d83cc019SAndroid Build Coastguard Worker *index = i;
126*d83cc019SAndroid Build Coastguard Worker return true;
127*d83cc019SAndroid Build Coastguard Worker }
128*d83cc019SAndroid Build Coastguard Worker
129*d83cc019SAndroid Build Coastguard Worker return false;
130*d83cc019SAndroid Build Coastguard Worker }
test_properties(int fd,uint32_t type,uint32_t id,bool atomic)131*d83cc019SAndroid Build Coastguard Worker static void test_properties(int fd, uint32_t type, uint32_t id, bool atomic)
132*d83cc019SAndroid Build Coastguard Worker {
133*d83cc019SAndroid Build Coastguard Worker drmModeObjectPropertiesPtr props =
134*d83cc019SAndroid Build Coastguard Worker drmModeObjectGetProperties(fd, id, type);
135*d83cc019SAndroid Build Coastguard Worker int i, j, ret;
136*d83cc019SAndroid Build Coastguard Worker drmModeAtomicReqPtr req = NULL;
137*d83cc019SAndroid Build Coastguard Worker
138*d83cc019SAndroid Build Coastguard Worker igt_assert(props);
139*d83cc019SAndroid Build Coastguard Worker
140*d83cc019SAndroid Build Coastguard Worker if (atomic)
141*d83cc019SAndroid Build Coastguard Worker req = drmModeAtomicAlloc();
142*d83cc019SAndroid Build Coastguard Worker
143*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < props->count_props; i++) {
144*d83cc019SAndroid Build Coastguard Worker uint32_t prop_id = props->props[i];
145*d83cc019SAndroid Build Coastguard Worker uint64_t prop_value = props->prop_values[i];
146*d83cc019SAndroid Build Coastguard Worker drmModePropertyPtr prop = drmModeGetProperty(fd, prop_id);
147*d83cc019SAndroid Build Coastguard Worker
148*d83cc019SAndroid Build Coastguard Worker igt_assert(prop);
149*d83cc019SAndroid Build Coastguard Worker
150*d83cc019SAndroid Build Coastguard Worker if (ignore_property(type, prop->flags, prop->name, atomic)) {
151*d83cc019SAndroid Build Coastguard Worker igt_debug("Ignoring property \"%s\"\n", prop->name);
152*d83cc019SAndroid Build Coastguard Worker
153*d83cc019SAndroid Build Coastguard Worker continue;
154*d83cc019SAndroid Build Coastguard Worker }
155*d83cc019SAndroid Build Coastguard Worker
156*d83cc019SAndroid Build Coastguard Worker igt_debug("Testing property \"%s\"\n", prop->name);
157*d83cc019SAndroid Build Coastguard Worker
158*d83cc019SAndroid Build Coastguard Worker if (!atomic) {
159*d83cc019SAndroid Build Coastguard Worker ret = drmModeObjectSetProperty(fd, id, type, prop_id, prop_value);
160*d83cc019SAndroid Build Coastguard Worker
161*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, 0);
162*d83cc019SAndroid Build Coastguard Worker } else {
163*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicAddProperty(req, id, prop_id, prop_value);
164*d83cc019SAndroid Build Coastguard Worker igt_assert(ret >= 0);
165*d83cc019SAndroid Build Coastguard Worker
166*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicCommit(fd, req, DRM_MODE_ATOMIC_TEST_ONLY, NULL);
167*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, 0);
168*d83cc019SAndroid Build Coastguard Worker }
169*d83cc019SAndroid Build Coastguard Worker
170*d83cc019SAndroid Build Coastguard Worker if (has_additional_test_lookup(type, prop->name, atomic, &j))
171*d83cc019SAndroid Build Coastguard Worker property_functional_test[j].prop_test(fd, id, type, prop, prop_id, prop_value, atomic);
172*d83cc019SAndroid Build Coastguard Worker
173*d83cc019SAndroid Build Coastguard Worker drmModeFreeProperty(prop);
174*d83cc019SAndroid Build Coastguard Worker }
175*d83cc019SAndroid Build Coastguard Worker
176*d83cc019SAndroid Build Coastguard Worker drmModeFreeObjectProperties(props);
177*d83cc019SAndroid Build Coastguard Worker
178*d83cc019SAndroid Build Coastguard Worker if (atomic) {
179*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicCommit(fd, req, 0, NULL);
180*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, 0);
181*d83cc019SAndroid Build Coastguard Worker
182*d83cc019SAndroid Build Coastguard Worker drmModeAtomicFree(req);
183*d83cc019SAndroid Build Coastguard Worker }
184*d83cc019SAndroid Build Coastguard Worker }
185*d83cc019SAndroid Build Coastguard Worker
run_plane_property_tests(igt_display_t * display,enum pipe pipe,igt_output_t * output,bool atomic)186*d83cc019SAndroid Build Coastguard Worker static void run_plane_property_tests(igt_display_t *display, enum pipe pipe, igt_output_t *output, bool atomic)
187*d83cc019SAndroid Build Coastguard Worker {
188*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb;
189*d83cc019SAndroid Build Coastguard Worker igt_plane_t *plane;
190*d83cc019SAndroid Build Coastguard Worker
191*d83cc019SAndroid Build Coastguard Worker prepare_pipe(display, pipe, output, &fb);
192*d83cc019SAndroid Build Coastguard Worker
193*d83cc019SAndroid Build Coastguard Worker for_each_plane_on_pipe(display, pipe, plane) {
194*d83cc019SAndroid Build Coastguard Worker igt_info("Testing plane properties on %s.#%d-%s (output: %s)\n",
195*d83cc019SAndroid Build Coastguard Worker kmstest_pipe_name(pipe), plane->index, kmstest_plane_type_name(plane->type), output->name);
196*d83cc019SAndroid Build Coastguard Worker
197*d83cc019SAndroid Build Coastguard Worker test_properties(display->drm_fd, DRM_MODE_OBJECT_PLANE, plane->drm_plane->plane_id, atomic);
198*d83cc019SAndroid Build Coastguard Worker }
199*d83cc019SAndroid Build Coastguard Worker
200*d83cc019SAndroid Build Coastguard Worker cleanup_pipe(display, pipe, output, &fb);
201*d83cc019SAndroid Build Coastguard Worker }
202*d83cc019SAndroid Build Coastguard Worker
run_crtc_property_tests(igt_display_t * display,enum pipe pipe,igt_output_t * output,bool atomic)203*d83cc019SAndroid Build Coastguard Worker static void run_crtc_property_tests(igt_display_t *display, enum pipe pipe, igt_output_t *output, bool atomic)
204*d83cc019SAndroid Build Coastguard Worker {
205*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb;
206*d83cc019SAndroid Build Coastguard Worker
207*d83cc019SAndroid Build Coastguard Worker prepare_pipe(display, pipe, output, &fb);
208*d83cc019SAndroid Build Coastguard Worker
209*d83cc019SAndroid Build Coastguard Worker igt_info("Testing crtc properties on %s (output: %s)\n", kmstest_pipe_name(pipe), output->name);
210*d83cc019SAndroid Build Coastguard Worker
211*d83cc019SAndroid Build Coastguard Worker test_properties(display->drm_fd, DRM_MODE_OBJECT_CRTC, display->pipes[pipe].crtc_id, atomic);
212*d83cc019SAndroid Build Coastguard Worker
213*d83cc019SAndroid Build Coastguard Worker cleanup_pipe(display, pipe, output, &fb);
214*d83cc019SAndroid Build Coastguard Worker }
215*d83cc019SAndroid Build Coastguard Worker
run_connector_property_tests(igt_display_t * display,enum pipe pipe,igt_output_t * output,bool atomic)216*d83cc019SAndroid Build Coastguard Worker static void run_connector_property_tests(igt_display_t *display, enum pipe pipe, igt_output_t *output, bool atomic)
217*d83cc019SAndroid Build Coastguard Worker {
218*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb;
219*d83cc019SAndroid Build Coastguard Worker
220*d83cc019SAndroid Build Coastguard Worker if (pipe != PIPE_NONE)
221*d83cc019SAndroid Build Coastguard Worker prepare_pipe(display, pipe, output, &fb);
222*d83cc019SAndroid Build Coastguard Worker
223*d83cc019SAndroid Build Coastguard Worker igt_info("Testing connector properties on output %s (pipe: %s)\n", output->name, kmstest_pipe_name(pipe));
224*d83cc019SAndroid Build Coastguard Worker
225*d83cc019SAndroid Build Coastguard Worker test_properties(display->drm_fd, DRM_MODE_OBJECT_CONNECTOR, output->id, atomic);
226*d83cc019SAndroid Build Coastguard Worker
227*d83cc019SAndroid Build Coastguard Worker if (pipe != PIPE_NONE)
228*d83cc019SAndroid Build Coastguard Worker cleanup_pipe(display, pipe, output, &fb);
229*d83cc019SAndroid Build Coastguard Worker }
230*d83cc019SAndroid Build Coastguard Worker
plane_properties(igt_display_t * display,bool atomic)231*d83cc019SAndroid Build Coastguard Worker static void plane_properties(igt_display_t *display, bool atomic)
232*d83cc019SAndroid Build Coastguard Worker {
233*d83cc019SAndroid Build Coastguard Worker bool found_any = false, found;
234*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
235*d83cc019SAndroid Build Coastguard Worker enum pipe pipe;
236*d83cc019SAndroid Build Coastguard Worker
237*d83cc019SAndroid Build Coastguard Worker if (atomic)
238*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!display->is_atomic);
239*d83cc019SAndroid Build Coastguard Worker
240*d83cc019SAndroid Build Coastguard Worker for_each_pipe(display, pipe) {
241*d83cc019SAndroid Build Coastguard Worker found = false;
242*d83cc019SAndroid Build Coastguard Worker
243*d83cc019SAndroid Build Coastguard Worker for_each_valid_output_on_pipe(display, pipe, output) {
244*d83cc019SAndroid Build Coastguard Worker found_any = found = true;
245*d83cc019SAndroid Build Coastguard Worker
246*d83cc019SAndroid Build Coastguard Worker run_plane_property_tests(display, pipe, output, atomic);
247*d83cc019SAndroid Build Coastguard Worker break;
248*d83cc019SAndroid Build Coastguard Worker }
249*d83cc019SAndroid Build Coastguard Worker }
250*d83cc019SAndroid Build Coastguard Worker
251*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!found_any);
252*d83cc019SAndroid Build Coastguard Worker }
253*d83cc019SAndroid Build Coastguard Worker
crtc_properties(igt_display_t * display,bool atomic)254*d83cc019SAndroid Build Coastguard Worker static void crtc_properties(igt_display_t *display, bool atomic)
255*d83cc019SAndroid Build Coastguard Worker {
256*d83cc019SAndroid Build Coastguard Worker bool found_any_valid_pipe = false, found;
257*d83cc019SAndroid Build Coastguard Worker enum pipe pipe;
258*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
259*d83cc019SAndroid Build Coastguard Worker
260*d83cc019SAndroid Build Coastguard Worker if (atomic)
261*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!display->is_atomic);
262*d83cc019SAndroid Build Coastguard Worker
263*d83cc019SAndroid Build Coastguard Worker for_each_pipe(display, pipe) {
264*d83cc019SAndroid Build Coastguard Worker found = false;
265*d83cc019SAndroid Build Coastguard Worker
266*d83cc019SAndroid Build Coastguard Worker for_each_valid_output_on_pipe(display, pipe, output) {
267*d83cc019SAndroid Build Coastguard Worker found_any_valid_pipe = found = true;
268*d83cc019SAndroid Build Coastguard Worker
269*d83cc019SAndroid Build Coastguard Worker run_crtc_property_tests(display, pipe, output, atomic);
270*d83cc019SAndroid Build Coastguard Worker break;
271*d83cc019SAndroid Build Coastguard Worker }
272*d83cc019SAndroid Build Coastguard Worker }
273*d83cc019SAndroid Build Coastguard Worker
274*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!found_any_valid_pipe);
275*d83cc019SAndroid Build Coastguard Worker }
276*d83cc019SAndroid Build Coastguard Worker
connector_properties(igt_display_t * display,bool atomic)277*d83cc019SAndroid Build Coastguard Worker static void connector_properties(igt_display_t *display, bool atomic)
278*d83cc019SAndroid Build Coastguard Worker {
279*d83cc019SAndroid Build Coastguard Worker int i;
280*d83cc019SAndroid Build Coastguard Worker enum pipe pipe;
281*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
282*d83cc019SAndroid Build Coastguard Worker
283*d83cc019SAndroid Build Coastguard Worker if (atomic)
284*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!display->is_atomic);
285*d83cc019SAndroid Build Coastguard Worker
286*d83cc019SAndroid Build Coastguard Worker for_each_connected_output(display, output) {
287*d83cc019SAndroid Build Coastguard Worker bool found = false;
288*d83cc019SAndroid Build Coastguard Worker
289*d83cc019SAndroid Build Coastguard Worker for_each_pipe(display, pipe) {
290*d83cc019SAndroid Build Coastguard Worker if (!igt_pipe_connector_valid(pipe, output))
291*d83cc019SAndroid Build Coastguard Worker continue;
292*d83cc019SAndroid Build Coastguard Worker
293*d83cc019SAndroid Build Coastguard Worker found = true;
294*d83cc019SAndroid Build Coastguard Worker run_connector_property_tests(display, pipe, output, atomic);
295*d83cc019SAndroid Build Coastguard Worker break;
296*d83cc019SAndroid Build Coastguard Worker }
297*d83cc019SAndroid Build Coastguard Worker
298*d83cc019SAndroid Build Coastguard Worker igt_assert_f(found, "Connected output should have at least 1 valid crtc\n");
299*d83cc019SAndroid Build Coastguard Worker }
300*d83cc019SAndroid Build Coastguard Worker
301*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < display->n_outputs; i++)
302*d83cc019SAndroid Build Coastguard Worker if (!igt_output_is_connected(&display->outputs[i]))
303*d83cc019SAndroid Build Coastguard Worker run_connector_property_tests(display, PIPE_NONE, &display->outputs[i], atomic);
304*d83cc019SAndroid Build Coastguard Worker }
305*d83cc019SAndroid Build Coastguard Worker
test_invalid_properties(int fd,uint32_t id1,uint32_t type1,uint32_t id2,uint32_t type2,bool atomic)306*d83cc019SAndroid Build Coastguard Worker static void test_invalid_properties(int fd,
307*d83cc019SAndroid Build Coastguard Worker uint32_t id1,
308*d83cc019SAndroid Build Coastguard Worker uint32_t type1,
309*d83cc019SAndroid Build Coastguard Worker uint32_t id2,
310*d83cc019SAndroid Build Coastguard Worker uint32_t type2,
311*d83cc019SAndroid Build Coastguard Worker bool atomic)
312*d83cc019SAndroid Build Coastguard Worker {
313*d83cc019SAndroid Build Coastguard Worker drmModeObjectPropertiesPtr props1 =
314*d83cc019SAndroid Build Coastguard Worker drmModeObjectGetProperties(fd, id1, type1);
315*d83cc019SAndroid Build Coastguard Worker drmModeObjectPropertiesPtr props2 =
316*d83cc019SAndroid Build Coastguard Worker drmModeObjectGetProperties(fd, id2, type2);
317*d83cc019SAndroid Build Coastguard Worker
318*d83cc019SAndroid Build Coastguard Worker int i, j, ret;
319*d83cc019SAndroid Build Coastguard Worker drmModeAtomicReqPtr req;
320*d83cc019SAndroid Build Coastguard Worker
321*d83cc019SAndroid Build Coastguard Worker igt_assert(props1 && props2);
322*d83cc019SAndroid Build Coastguard Worker
323*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < props2->count_props; i++) {
324*d83cc019SAndroid Build Coastguard Worker uint32_t prop_id = props2->props[i];
325*d83cc019SAndroid Build Coastguard Worker uint64_t prop_value = props2->prop_values[i];
326*d83cc019SAndroid Build Coastguard Worker drmModePropertyPtr prop = drmModeGetProperty(fd, prop_id);
327*d83cc019SAndroid Build Coastguard Worker bool found = false;
328*d83cc019SAndroid Build Coastguard Worker
329*d83cc019SAndroid Build Coastguard Worker igt_assert(prop);
330*d83cc019SAndroid Build Coastguard Worker
331*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < props1->count_props; j++)
332*d83cc019SAndroid Build Coastguard Worker if (props1->props[j] == prop_id) {
333*d83cc019SAndroid Build Coastguard Worker found = true;
334*d83cc019SAndroid Build Coastguard Worker break;
335*d83cc019SAndroid Build Coastguard Worker }
336*d83cc019SAndroid Build Coastguard Worker
337*d83cc019SAndroid Build Coastguard Worker if (found)
338*d83cc019SAndroid Build Coastguard Worker continue;
339*d83cc019SAndroid Build Coastguard Worker
340*d83cc019SAndroid Build Coastguard Worker igt_debug("Testing property \"%s\" on [%x:%u]\n", prop->name, type1, id1);
341*d83cc019SAndroid Build Coastguard Worker
342*d83cc019SAndroid Build Coastguard Worker if (!atomic) {
343*d83cc019SAndroid Build Coastguard Worker ret = drmModeObjectSetProperty(fd, id1, type1, prop_id, prop_value);
344*d83cc019SAndroid Build Coastguard Worker
345*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, -EINVAL);
346*d83cc019SAndroid Build Coastguard Worker } else {
347*d83cc019SAndroid Build Coastguard Worker req = drmModeAtomicAlloc();
348*d83cc019SAndroid Build Coastguard Worker igt_assert(req);
349*d83cc019SAndroid Build Coastguard Worker
350*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicAddProperty(req, id1, prop_id, prop_value);
351*d83cc019SAndroid Build Coastguard Worker igt_assert(ret >= 0);
352*d83cc019SAndroid Build Coastguard Worker
353*d83cc019SAndroid Build Coastguard Worker ret = drmModeAtomicCommit(fd, req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
354*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, -ENOENT);
355*d83cc019SAndroid Build Coastguard Worker
356*d83cc019SAndroid Build Coastguard Worker drmModeAtomicFree(req);
357*d83cc019SAndroid Build Coastguard Worker }
358*d83cc019SAndroid Build Coastguard Worker
359*d83cc019SAndroid Build Coastguard Worker drmModeFreeProperty(prop);
360*d83cc019SAndroid Build Coastguard Worker }
361*d83cc019SAndroid Build Coastguard Worker
362*d83cc019SAndroid Build Coastguard Worker drmModeFreeObjectProperties(props1);
363*d83cc019SAndroid Build Coastguard Worker drmModeFreeObjectProperties(props2);
364*d83cc019SAndroid Build Coastguard Worker }
test_object_invalid_properties(igt_display_t * display,uint32_t id,uint32_t type,bool atomic)365*d83cc019SAndroid Build Coastguard Worker static void test_object_invalid_properties(igt_display_t *display,
366*d83cc019SAndroid Build Coastguard Worker uint32_t id, uint32_t type, bool atomic)
367*d83cc019SAndroid Build Coastguard Worker {
368*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
369*d83cc019SAndroid Build Coastguard Worker igt_plane_t *plane;
370*d83cc019SAndroid Build Coastguard Worker enum pipe pipe;
371*d83cc019SAndroid Build Coastguard Worker int i;
372*d83cc019SAndroid Build Coastguard Worker
373*d83cc019SAndroid Build Coastguard Worker for_each_pipe(display, pipe)
374*d83cc019SAndroid Build Coastguard Worker test_invalid_properties(display->drm_fd, id, type, display->pipes[pipe].crtc_id, DRM_MODE_OBJECT_CRTC, atomic);
375*d83cc019SAndroid Build Coastguard Worker
376*d83cc019SAndroid Build Coastguard Worker for_each_pipe(display, pipe)
377*d83cc019SAndroid Build Coastguard Worker for_each_plane_on_pipe(display, pipe, plane)
378*d83cc019SAndroid Build Coastguard Worker test_invalid_properties(display->drm_fd, id, type, plane->drm_plane->plane_id, DRM_MODE_OBJECT_PLANE, atomic);
379*d83cc019SAndroid Build Coastguard Worker
380*d83cc019SAndroid Build Coastguard Worker for (i = 0, output = &display->outputs[0]; i < display->n_outputs; output = &display->outputs[++i])
381*d83cc019SAndroid Build Coastguard Worker test_invalid_properties(display->drm_fd, id, type, output->id, DRM_MODE_OBJECT_CONNECTOR, atomic);
382*d83cc019SAndroid Build Coastguard Worker }
383*d83cc019SAndroid Build Coastguard Worker
validate_range_prop(const struct drm_mode_get_property * prop,uint64_t value)384*d83cc019SAndroid Build Coastguard Worker static void validate_range_prop(const struct drm_mode_get_property *prop,
385*d83cc019SAndroid Build Coastguard Worker uint64_t value)
386*d83cc019SAndroid Build Coastguard Worker {
387*d83cc019SAndroid Build Coastguard Worker const uint64_t *values = from_user_pointer(prop->values_ptr);
388*d83cc019SAndroid Build Coastguard Worker bool is_unsigned = prop->flags & DRM_MODE_PROP_RANGE;
389*d83cc019SAndroid Build Coastguard Worker bool immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
390*d83cc019SAndroid Build Coastguard Worker
391*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(prop->count_values, 2);
392*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(prop->count_enum_blobs, 0);
393*d83cc019SAndroid Build Coastguard Worker igt_assert(values[0] != values[1] || immutable);
394*d83cc019SAndroid Build Coastguard Worker
395*d83cc019SAndroid Build Coastguard Worker if (is_unsigned) {
396*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_u64(values[0], values[1]);
397*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_u64(values[0], value);
398*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_u64(value, values[1]);
399*d83cc019SAndroid Build Coastguard Worker } else {
400*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_s64(values[0], values[1]);
401*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_s64(values[0], value);
402*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_s64(value, values[1]);
403*d83cc019SAndroid Build Coastguard Worker }
404*d83cc019SAndroid Build Coastguard Worker
405*d83cc019SAndroid Build Coastguard Worker }
406*d83cc019SAndroid Build Coastguard Worker
validate_enums(const struct drm_mode_get_property * prop)407*d83cc019SAndroid Build Coastguard Worker static void validate_enums(const struct drm_mode_get_property *prop)
408*d83cc019SAndroid Build Coastguard Worker {
409*d83cc019SAndroid Build Coastguard Worker const uint64_t *values = from_user_pointer(prop->values_ptr);
410*d83cc019SAndroid Build Coastguard Worker const struct drm_mode_property_enum *enums =
411*d83cc019SAndroid Build Coastguard Worker from_user_pointer(prop->enum_blob_ptr);
412*d83cc019SAndroid Build Coastguard Worker
413*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < prop->count_enum_blobs; i++) {
414*d83cc019SAndroid Build Coastguard Worker int name_len = strnlen(enums[i].name,
415*d83cc019SAndroid Build Coastguard Worker sizeof(enums[i].name));
416*d83cc019SAndroid Build Coastguard Worker
417*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(1, name_len);
418*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(name_len, sizeof(enums[i].name) - 1);
419*d83cc019SAndroid Build Coastguard Worker
420*d83cc019SAndroid Build Coastguard Worker /* no idea why we have this duplicated */
421*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(values[i], enums[i].value);
422*d83cc019SAndroid Build Coastguard Worker }
423*d83cc019SAndroid Build Coastguard Worker }
424*d83cc019SAndroid Build Coastguard Worker
validate_enum_prop(const struct drm_mode_get_property * prop,uint64_t value)425*d83cc019SAndroid Build Coastguard Worker static void validate_enum_prop(const struct drm_mode_get_property *prop,
426*d83cc019SAndroid Build Coastguard Worker uint64_t value)
427*d83cc019SAndroid Build Coastguard Worker {
428*d83cc019SAndroid Build Coastguard Worker const uint64_t *values = from_user_pointer(prop->values_ptr);
429*d83cc019SAndroid Build Coastguard Worker bool immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
430*d83cc019SAndroid Build Coastguard Worker int i;
431*d83cc019SAndroid Build Coastguard Worker
432*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(1, prop->count_values);
433*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(prop->count_enum_blobs, prop->count_values);
434*d83cc019SAndroid Build Coastguard Worker igt_assert(prop->count_values != 1 || immutable);
435*d83cc019SAndroid Build Coastguard Worker
436*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < prop->count_values; i++) {
437*d83cc019SAndroid Build Coastguard Worker if (value == values[i])
438*d83cc019SAndroid Build Coastguard Worker break;
439*d83cc019SAndroid Build Coastguard Worker }
440*d83cc019SAndroid Build Coastguard Worker igt_assert(i != prop->count_values);
441*d83cc019SAndroid Build Coastguard Worker
442*d83cc019SAndroid Build Coastguard Worker validate_enums(prop);
443*d83cc019SAndroid Build Coastguard Worker }
444*d83cc019SAndroid Build Coastguard Worker
validate_bitmask_prop(const struct drm_mode_get_property * prop,uint64_t value)445*d83cc019SAndroid Build Coastguard Worker static void validate_bitmask_prop(const struct drm_mode_get_property *prop,
446*d83cc019SAndroid Build Coastguard Worker uint64_t value)
447*d83cc019SAndroid Build Coastguard Worker {
448*d83cc019SAndroid Build Coastguard Worker const uint64_t *values = from_user_pointer(prop->values_ptr);
449*d83cc019SAndroid Build Coastguard Worker bool immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
450*d83cc019SAndroid Build Coastguard Worker uint64_t mask = 0;
451*d83cc019SAndroid Build Coastguard Worker
452*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(1, prop->count_values);
453*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(prop->count_enum_blobs, prop->count_values);
454*d83cc019SAndroid Build Coastguard Worker igt_assert(prop->count_values != 1 || immutable);
455*d83cc019SAndroid Build Coastguard Worker
456*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < prop->count_values; i++) {
457*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_u64(values[i], 63);
458*d83cc019SAndroid Build Coastguard Worker mask |= 1ULL << values[i];
459*d83cc019SAndroid Build Coastguard Worker }
460*d83cc019SAndroid Build Coastguard Worker
461*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(value & ~mask, 0);
462*d83cc019SAndroid Build Coastguard Worker igt_assert_neq_u64(value & mask, 0);
463*d83cc019SAndroid Build Coastguard Worker
464*d83cc019SAndroid Build Coastguard Worker validate_enums(prop);
465*d83cc019SAndroid Build Coastguard Worker }
466*d83cc019SAndroid Build Coastguard Worker
validate_blob_prop(int fd,const struct drm_mode_get_property * prop,uint64_t value)467*d83cc019SAndroid Build Coastguard Worker static void validate_blob_prop(int fd,
468*d83cc019SAndroid Build Coastguard Worker const struct drm_mode_get_property *prop,
469*d83cc019SAndroid Build Coastguard Worker uint64_t value)
470*d83cc019SAndroid Build Coastguard Worker {
471*d83cc019SAndroid Build Coastguard Worker struct drm_mode_get_blob blob;
472*d83cc019SAndroid Build Coastguard Worker
473*d83cc019SAndroid Build Coastguard Worker /*
474*d83cc019SAndroid Build Coastguard Worker * Despite what libdrm makes you believe, we never supply
475*d83cc019SAndroid Build Coastguard Worker * additional information for BLOB properties, only for enums
476*d83cc019SAndroid Build Coastguard Worker * and bitmasks
477*d83cc019SAndroid Build Coastguard Worker */
478*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(prop->count_values, 0);
479*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(prop->count_enum_blobs, 0);
480*d83cc019SAndroid Build Coastguard Worker
481*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_u64(value, 0xffffffff);
482*d83cc019SAndroid Build Coastguard Worker
483*d83cc019SAndroid Build Coastguard Worker /*
484*d83cc019SAndroid Build Coastguard Worker * Immutable blob properties can have value==0.
485*d83cc019SAndroid Build Coastguard Worker * Happens for example with the "EDID" property
486*d83cc019SAndroid Build Coastguard Worker * when there is nothing hooked up to the connector.
487*d83cc019SAndroid Build Coastguard Worker */
488*d83cc019SAndroid Build Coastguard Worker
489*d83cc019SAndroid Build Coastguard Worker if (!value)
490*d83cc019SAndroid Build Coastguard Worker return;
491*d83cc019SAndroid Build Coastguard Worker
492*d83cc019SAndroid Build Coastguard Worker memset(&blob, 0, sizeof(blob));
493*d83cc019SAndroid Build Coastguard Worker blob.blob_id = value;
494*d83cc019SAndroid Build Coastguard Worker
495*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob);
496*d83cc019SAndroid Build Coastguard Worker }
497*d83cc019SAndroid Build Coastguard Worker
validate_object_prop(int fd,const struct drm_mode_get_property * prop,uint64_t value)498*d83cc019SAndroid Build Coastguard Worker static void validate_object_prop(int fd,
499*d83cc019SAndroid Build Coastguard Worker const struct drm_mode_get_property *prop,
500*d83cc019SAndroid Build Coastguard Worker uint64_t value)
501*d83cc019SAndroid Build Coastguard Worker {
502*d83cc019SAndroid Build Coastguard Worker const uint64_t *values = from_user_pointer(prop->values_ptr);
503*d83cc019SAndroid Build Coastguard Worker bool immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
504*d83cc019SAndroid Build Coastguard Worker struct drm_mode_crtc crtc;
505*d83cc019SAndroid Build Coastguard Worker struct drm_mode_fb_cmd fb;
506*d83cc019SAndroid Build Coastguard Worker
507*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(prop->count_values, 1);
508*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(prop->count_enum_blobs, 0);
509*d83cc019SAndroid Build Coastguard Worker
510*d83cc019SAndroid Build Coastguard Worker igt_assert_lte_u64(value, 0xffffffff);
511*d83cc019SAndroid Build Coastguard Worker igt_assert(!immutable || value != 0);
512*d83cc019SAndroid Build Coastguard Worker
513*d83cc019SAndroid Build Coastguard Worker switch (values[0]) {
514*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_OBJECT_CRTC:
515*d83cc019SAndroid Build Coastguard Worker if (!value)
516*d83cc019SAndroid Build Coastguard Worker break;
517*d83cc019SAndroid Build Coastguard Worker memset(&crtc, 0, sizeof(crtc));
518*d83cc019SAndroid Build Coastguard Worker crtc.crtc_id = value;
519*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc);
520*d83cc019SAndroid Build Coastguard Worker break;
521*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_OBJECT_FB:
522*d83cc019SAndroid Build Coastguard Worker if (!value)
523*d83cc019SAndroid Build Coastguard Worker break;
524*d83cc019SAndroid Build Coastguard Worker memset(&fb, 0, sizeof(fb));
525*d83cc019SAndroid Build Coastguard Worker fb.fb_id = value;
526*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_MODE_GETFB, &fb);
527*d83cc019SAndroid Build Coastguard Worker break;
528*d83cc019SAndroid Build Coastguard Worker default:
529*d83cc019SAndroid Build Coastguard Worker /* These are the only types we have so far */
530*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
531*d83cc019SAndroid Build Coastguard Worker }
532*d83cc019SAndroid Build Coastguard Worker }
533*d83cc019SAndroid Build Coastguard Worker
validate_property(int fd,const struct drm_mode_get_property * prop,uint64_t value,bool atomic)534*d83cc019SAndroid Build Coastguard Worker static void validate_property(int fd,
535*d83cc019SAndroid Build Coastguard Worker const struct drm_mode_get_property *prop,
536*d83cc019SAndroid Build Coastguard Worker uint64_t value, bool atomic)
537*d83cc019SAndroid Build Coastguard Worker {
538*d83cc019SAndroid Build Coastguard Worker uint32_t flags = prop->flags;
539*d83cc019SAndroid Build Coastguard Worker uint32_t legacy_type = flags & DRM_MODE_PROP_LEGACY_TYPE;
540*d83cc019SAndroid Build Coastguard Worker uint32_t ext_type = flags & DRM_MODE_PROP_EXTENDED_TYPE;
541*d83cc019SAndroid Build Coastguard Worker
542*d83cc019SAndroid Build Coastguard Worker igt_assert_eq((flags & ~(DRM_MODE_PROP_LEGACY_TYPE |
543*d83cc019SAndroid Build Coastguard Worker DRM_MODE_PROP_EXTENDED_TYPE |
544*d83cc019SAndroid Build Coastguard Worker DRM_MODE_PROP_IMMUTABLE |
545*d83cc019SAndroid Build Coastguard Worker DRM_MODE_PROP_ATOMIC)), 0);
546*d83cc019SAndroid Build Coastguard Worker
547*d83cc019SAndroid Build Coastguard Worker igt_assert(atomic ||
548*d83cc019SAndroid Build Coastguard Worker (flags & DRM_MODE_PROP_ATOMIC) == 0);
549*d83cc019SAndroid Build Coastguard Worker
550*d83cc019SAndroid Build Coastguard Worker igt_assert_neq(!legacy_type, !ext_type);
551*d83cc019SAndroid Build Coastguard Worker
552*d83cc019SAndroid Build Coastguard Worker igt_assert(legacy_type == 0 ||
553*d83cc019SAndroid Build Coastguard Worker is_power_of_two(legacy_type));
554*d83cc019SAndroid Build Coastguard Worker
555*d83cc019SAndroid Build Coastguard Worker switch (legacy_type) {
556*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_PROP_RANGE:
557*d83cc019SAndroid Build Coastguard Worker validate_range_prop(prop, value);
558*d83cc019SAndroid Build Coastguard Worker break;
559*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_PROP_ENUM:
560*d83cc019SAndroid Build Coastguard Worker validate_enum_prop(prop, value);
561*d83cc019SAndroid Build Coastguard Worker break;
562*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_PROP_BITMASK:
563*d83cc019SAndroid Build Coastguard Worker validate_bitmask_prop(prop, value);
564*d83cc019SAndroid Build Coastguard Worker break;
565*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_PROP_BLOB:
566*d83cc019SAndroid Build Coastguard Worker validate_blob_prop(fd, prop, value);
567*d83cc019SAndroid Build Coastguard Worker break;
568*d83cc019SAndroid Build Coastguard Worker default:
569*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(legacy_type, 0);
570*d83cc019SAndroid Build Coastguard Worker }
571*d83cc019SAndroid Build Coastguard Worker
572*d83cc019SAndroid Build Coastguard Worker switch (ext_type) {
573*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_PROP_OBJECT:
574*d83cc019SAndroid Build Coastguard Worker validate_object_prop(fd, prop, value);
575*d83cc019SAndroid Build Coastguard Worker break;
576*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_PROP_SIGNED_RANGE:
577*d83cc019SAndroid Build Coastguard Worker validate_range_prop(prop, value);
578*d83cc019SAndroid Build Coastguard Worker break;
579*d83cc019SAndroid Build Coastguard Worker default:
580*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ext_type, 0);
581*d83cc019SAndroid Build Coastguard Worker }
582*d83cc019SAndroid Build Coastguard Worker }
583*d83cc019SAndroid Build Coastguard Worker
validate_prop(int fd,uint32_t prop_id,uint64_t value,bool atomic)584*d83cc019SAndroid Build Coastguard Worker static void validate_prop(int fd, uint32_t prop_id, uint64_t value, bool atomic)
585*d83cc019SAndroid Build Coastguard Worker {
586*d83cc019SAndroid Build Coastguard Worker struct drm_mode_get_property prop;
587*d83cc019SAndroid Build Coastguard Worker struct drm_mode_property_enum *enums = NULL;
588*d83cc019SAndroid Build Coastguard Worker uint64_t *values = NULL;
589*d83cc019SAndroid Build Coastguard Worker
590*d83cc019SAndroid Build Coastguard Worker memset(&prop, 0, sizeof(prop));
591*d83cc019SAndroid Build Coastguard Worker prop.prop_id = prop_id;
592*d83cc019SAndroid Build Coastguard Worker
593*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop);
594*d83cc019SAndroid Build Coastguard Worker
595*d83cc019SAndroid Build Coastguard Worker if (prop.count_values) {
596*d83cc019SAndroid Build Coastguard Worker values = calloc(prop.count_values, sizeof(values[0]));
597*d83cc019SAndroid Build Coastguard Worker igt_assert(values);
598*d83cc019SAndroid Build Coastguard Worker memset(values, 0x5c, sizeof(values[0])*prop.count_values);
599*d83cc019SAndroid Build Coastguard Worker prop.values_ptr = to_user_pointer(values);
600*d83cc019SAndroid Build Coastguard Worker }
601*d83cc019SAndroid Build Coastguard Worker
602*d83cc019SAndroid Build Coastguard Worker if (prop.count_enum_blobs) {
603*d83cc019SAndroid Build Coastguard Worker enums = calloc(prop.count_enum_blobs, sizeof(enums[0]));
604*d83cc019SAndroid Build Coastguard Worker memset(enums, 0x5c, sizeof(enums[0])*prop.count_enum_blobs);
605*d83cc019SAndroid Build Coastguard Worker igt_assert(enums);
606*d83cc019SAndroid Build Coastguard Worker prop.enum_blob_ptr = to_user_pointer(enums);
607*d83cc019SAndroid Build Coastguard Worker }
608*d83cc019SAndroid Build Coastguard Worker
609*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop);
610*d83cc019SAndroid Build Coastguard Worker
611*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < prop.count_values; i++)
612*d83cc019SAndroid Build Coastguard Worker igt_assert_neq_u64(values[i], 0x5c5c5c5c5c5c5c5cULL);
613*d83cc019SAndroid Build Coastguard Worker
614*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < prop.count_enum_blobs; i++)
615*d83cc019SAndroid Build Coastguard Worker igt_assert_neq_u64(enums[i].value, 0x5c5c5c5c5c5c5c5cULL);
616*d83cc019SAndroid Build Coastguard Worker
617*d83cc019SAndroid Build Coastguard Worker validate_property(fd, &prop, value, atomic);
618*d83cc019SAndroid Build Coastguard Worker
619*d83cc019SAndroid Build Coastguard Worker free(values);
620*d83cc019SAndroid Build Coastguard Worker free(enums);
621*d83cc019SAndroid Build Coastguard Worker }
622*d83cc019SAndroid Build Coastguard Worker
validate_props(int fd,uint32_t obj_type,uint32_t obj_id,bool atomic)623*d83cc019SAndroid Build Coastguard Worker static void validate_props(int fd, uint32_t obj_type, uint32_t obj_id, bool atomic)
624*d83cc019SAndroid Build Coastguard Worker {
625*d83cc019SAndroid Build Coastguard Worker struct drm_mode_obj_get_properties properties;
626*d83cc019SAndroid Build Coastguard Worker uint32_t *props = NULL;
627*d83cc019SAndroid Build Coastguard Worker uint64_t *values = NULL;
628*d83cc019SAndroid Build Coastguard Worker uint32_t count;
629*d83cc019SAndroid Build Coastguard Worker
630*d83cc019SAndroid Build Coastguard Worker memset(&properties, 0, sizeof(properties));
631*d83cc019SAndroid Build Coastguard Worker properties.obj_type = obj_type;
632*d83cc019SAndroid Build Coastguard Worker properties.obj_id = obj_id;
633*d83cc019SAndroid Build Coastguard Worker
634*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties);
635*d83cc019SAndroid Build Coastguard Worker
636*d83cc019SAndroid Build Coastguard Worker count = properties.count_props;
637*d83cc019SAndroid Build Coastguard Worker
638*d83cc019SAndroid Build Coastguard Worker if (count) {
639*d83cc019SAndroid Build Coastguard Worker props = calloc(count, sizeof(props[0]));
640*d83cc019SAndroid Build Coastguard Worker memset(props, 0x5c, sizeof(props[0])*count);
641*d83cc019SAndroid Build Coastguard Worker igt_assert(props);
642*d83cc019SAndroid Build Coastguard Worker properties.props_ptr = to_user_pointer(props);
643*d83cc019SAndroid Build Coastguard Worker
644*d83cc019SAndroid Build Coastguard Worker values = calloc(count, sizeof(values[0]));
645*d83cc019SAndroid Build Coastguard Worker memset(values, 0x5c, sizeof(values[0])*count);
646*d83cc019SAndroid Build Coastguard Worker igt_assert(values);
647*d83cc019SAndroid Build Coastguard Worker properties.prop_values_ptr = to_user_pointer(values);
648*d83cc019SAndroid Build Coastguard Worker }
649*d83cc019SAndroid Build Coastguard Worker
650*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties);
651*d83cc019SAndroid Build Coastguard Worker
652*d83cc019SAndroid Build Coastguard Worker igt_assert(properties.count_props == count);
653*d83cc019SAndroid Build Coastguard Worker
654*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < count; i++)
655*d83cc019SAndroid Build Coastguard Worker validate_prop(fd, props[i], values[i], atomic);
656*d83cc019SAndroid Build Coastguard Worker
657*d83cc019SAndroid Build Coastguard Worker free(values);
658*d83cc019SAndroid Build Coastguard Worker free(props);
659*d83cc019SAndroid Build Coastguard Worker }
660*d83cc019SAndroid Build Coastguard Worker
expect_no_props(int fd,uint32_t obj_type,uint32_t obj_id)661*d83cc019SAndroid Build Coastguard Worker static void expect_no_props(int fd, uint32_t obj_type, uint32_t obj_id)
662*d83cc019SAndroid Build Coastguard Worker {
663*d83cc019SAndroid Build Coastguard Worker struct drm_mode_obj_get_properties properties;
664*d83cc019SAndroid Build Coastguard Worker
665*d83cc019SAndroid Build Coastguard Worker memset(&properties, 0, sizeof(properties));
666*d83cc019SAndroid Build Coastguard Worker properties.obj_type = obj_type;
667*d83cc019SAndroid Build Coastguard Worker properties.obj_id = obj_id;
668*d83cc019SAndroid Build Coastguard Worker
669*d83cc019SAndroid Build Coastguard Worker igt_assert_neq(drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties), 0);
670*d83cc019SAndroid Build Coastguard Worker }
671*d83cc019SAndroid Build Coastguard Worker
get_prop_sanity(igt_display_t * display,bool atomic)672*d83cc019SAndroid Build Coastguard Worker static void get_prop_sanity(igt_display_t *display, bool atomic)
673*d83cc019SAndroid Build Coastguard Worker {
674*d83cc019SAndroid Build Coastguard Worker int fd = display->drm_fd;
675*d83cc019SAndroid Build Coastguard Worker drmModePlaneResPtr plane_res;
676*d83cc019SAndroid Build Coastguard Worker drmModeResPtr res;
677*d83cc019SAndroid Build Coastguard Worker
678*d83cc019SAndroid Build Coastguard Worker res = drmModeGetResources(fd);
679*d83cc019SAndroid Build Coastguard Worker plane_res = drmModeGetPlaneResources(fd);
680*d83cc019SAndroid Build Coastguard Worker
681*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < plane_res->count_planes; i++) {
682*d83cc019SAndroid Build Coastguard Worker validate_props(fd, DRM_MODE_OBJECT_PLANE,
683*d83cc019SAndroid Build Coastguard Worker plane_res->planes[i], atomic);
684*d83cc019SAndroid Build Coastguard Worker }
685*d83cc019SAndroid Build Coastguard Worker
686*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < res->count_crtcs; i++) {
687*d83cc019SAndroid Build Coastguard Worker validate_props(fd, DRM_MODE_OBJECT_CRTC,
688*d83cc019SAndroid Build Coastguard Worker res->crtcs[i], atomic);
689*d83cc019SAndroid Build Coastguard Worker }
690*d83cc019SAndroid Build Coastguard Worker
691*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < res->count_connectors; i++) {
692*d83cc019SAndroid Build Coastguard Worker validate_props(fd, DRM_MODE_OBJECT_CONNECTOR,
693*d83cc019SAndroid Build Coastguard Worker res->connectors[i], atomic);
694*d83cc019SAndroid Build Coastguard Worker }
695*d83cc019SAndroid Build Coastguard Worker
696*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < res->count_encoders; i++) {
697*d83cc019SAndroid Build Coastguard Worker expect_no_props(fd, DRM_MODE_OBJECT_ENCODER,
698*d83cc019SAndroid Build Coastguard Worker res->encoders[i]);
699*d83cc019SAndroid Build Coastguard Worker }
700*d83cc019SAndroid Build Coastguard Worker
701*d83cc019SAndroid Build Coastguard Worker drmModeFreePlaneResources(plane_res);
702*d83cc019SAndroid Build Coastguard Worker drmModeFreeResources(res);
703*d83cc019SAndroid Build Coastguard Worker }
704*d83cc019SAndroid Build Coastguard Worker
invalid_properties(igt_display_t * display,bool atomic)705*d83cc019SAndroid Build Coastguard Worker static void invalid_properties(igt_display_t *display, bool atomic)
706*d83cc019SAndroid Build Coastguard Worker {
707*d83cc019SAndroid Build Coastguard Worker igt_output_t *output;
708*d83cc019SAndroid Build Coastguard Worker igt_plane_t *plane;
709*d83cc019SAndroid Build Coastguard Worker enum pipe pipe;
710*d83cc019SAndroid Build Coastguard Worker int i;
711*d83cc019SAndroid Build Coastguard Worker
712*d83cc019SAndroid Build Coastguard Worker if (atomic)
713*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!display->is_atomic);
714*d83cc019SAndroid Build Coastguard Worker
715*d83cc019SAndroid Build Coastguard Worker for_each_pipe(display, pipe)
716*d83cc019SAndroid Build Coastguard Worker test_object_invalid_properties(display, display->pipes[pipe].crtc_id, DRM_MODE_OBJECT_CRTC, atomic);
717*d83cc019SAndroid Build Coastguard Worker
718*d83cc019SAndroid Build Coastguard Worker for_each_pipe(display, pipe)
719*d83cc019SAndroid Build Coastguard Worker for_each_plane_on_pipe(display, pipe, plane)
720*d83cc019SAndroid Build Coastguard Worker test_object_invalid_properties(display, plane->drm_plane->plane_id, DRM_MODE_OBJECT_PLANE, atomic);
721*d83cc019SAndroid Build Coastguard Worker
722*d83cc019SAndroid Build Coastguard Worker for (i = 0, output = &display->outputs[0]; i < display->n_outputs; output = &display->outputs[++i])
723*d83cc019SAndroid Build Coastguard Worker test_object_invalid_properties(display, output->id, DRM_MODE_OBJECT_CONNECTOR, atomic);
724*d83cc019SAndroid Build Coastguard Worker }
725*d83cc019SAndroid Build Coastguard Worker
726*d83cc019SAndroid Build Coastguard Worker igt_main
727*d83cc019SAndroid Build Coastguard Worker {
728*d83cc019SAndroid Build Coastguard Worker igt_display_t display;
729*d83cc019SAndroid Build Coastguard Worker
730*d83cc019SAndroid Build Coastguard Worker igt_skip_on_simulation();
731*d83cc019SAndroid Build Coastguard Worker
732*d83cc019SAndroid Build Coastguard Worker igt_fixture {
733*d83cc019SAndroid Build Coastguard Worker display.drm_fd = drm_open_driver_master(DRIVER_ANY);
734*d83cc019SAndroid Build Coastguard Worker
735*d83cc019SAndroid Build Coastguard Worker kmstest_set_vt_graphics_mode();
736*d83cc019SAndroid Build Coastguard Worker
737*d83cc019SAndroid Build Coastguard Worker igt_display_require(&display, display.drm_fd);
738*d83cc019SAndroid Build Coastguard Worker }
739*d83cc019SAndroid Build Coastguard Worker
740*d83cc019SAndroid Build Coastguard Worker igt_subtest("plane-properties-legacy")
741*d83cc019SAndroid Build Coastguard Worker plane_properties(&display, false);
742*d83cc019SAndroid Build Coastguard Worker
743*d83cc019SAndroid Build Coastguard Worker igt_subtest("plane-properties-atomic")
744*d83cc019SAndroid Build Coastguard Worker plane_properties(&display, true);
745*d83cc019SAndroid Build Coastguard Worker
746*d83cc019SAndroid Build Coastguard Worker igt_subtest("crtc-properties-legacy")
747*d83cc019SAndroid Build Coastguard Worker crtc_properties(&display, false);
748*d83cc019SAndroid Build Coastguard Worker
749*d83cc019SAndroid Build Coastguard Worker igt_subtest("crtc-properties-atomic")
750*d83cc019SAndroid Build Coastguard Worker crtc_properties(&display, true);
751*d83cc019SAndroid Build Coastguard Worker
752*d83cc019SAndroid Build Coastguard Worker igt_subtest("connector-properties-legacy")
753*d83cc019SAndroid Build Coastguard Worker connector_properties(&display, false);
754*d83cc019SAndroid Build Coastguard Worker
755*d83cc019SAndroid Build Coastguard Worker igt_subtest("connector-properties-atomic")
756*d83cc019SAndroid Build Coastguard Worker connector_properties(&display, true);
757*d83cc019SAndroid Build Coastguard Worker
758*d83cc019SAndroid Build Coastguard Worker igt_subtest("invalid-properties-legacy")
759*d83cc019SAndroid Build Coastguard Worker invalid_properties(&display, false);
760*d83cc019SAndroid Build Coastguard Worker
761*d83cc019SAndroid Build Coastguard Worker igt_subtest("invalid-properties-atomic")
762*d83cc019SAndroid Build Coastguard Worker invalid_properties(&display, true);
763*d83cc019SAndroid Build Coastguard Worker
764*d83cc019SAndroid Build Coastguard Worker igt_subtest("get_properties-sanity-atomic") {
765*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!display.is_atomic);
766*d83cc019SAndroid Build Coastguard Worker get_prop_sanity(&display, true);
767*d83cc019SAndroid Build Coastguard Worker }
768*d83cc019SAndroid Build Coastguard Worker
769*d83cc019SAndroid Build Coastguard Worker igt_subtest("get_properties-sanity-non-atomic") {
770*d83cc019SAndroid Build Coastguard Worker if (display.is_atomic)
771*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(drmSetClientCap(display.drm_fd, DRM_CLIENT_CAP_ATOMIC, 0), 0);
772*d83cc019SAndroid Build Coastguard Worker
773*d83cc019SAndroid Build Coastguard Worker get_prop_sanity(&display, false);
774*d83cc019SAndroid Build Coastguard Worker
775*d83cc019SAndroid Build Coastguard Worker if (display.is_atomic)
776*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(drmSetClientCap(display.drm_fd, DRM_CLIENT_CAP_ATOMIC, 1), 0);
777*d83cc019SAndroid Build Coastguard Worker }
778*d83cc019SAndroid Build Coastguard Worker
779*d83cc019SAndroid Build Coastguard Worker igt_fixture {
780*d83cc019SAndroid Build Coastguard Worker igt_display_fini(&display);
781*d83cc019SAndroid Build Coastguard Worker }
782*d83cc019SAndroid Build Coastguard Worker }
783