xref: /aosp_15_r20/external/igt-gpu-tools/lib/igt_kms.h (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1 /*
2  * Copyright © 2013 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  * 	Daniel Vetter <[email protected]>
25  * 	Damien Lespiau <[email protected]>
26  */
27 
28 #ifndef __IGT_KMS_H__
29 #define __IGT_KMS_H__
30 
31 #include <stdbool.h>
32 #include <stdint.h>
33 #include <stddef.h>
34 #include <assert.h>
35 
36 #include <xf86drmMode.h>
37 
38 #include "igt_fb.h"
39 #include "ioctl_wrappers.h"
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /* Low-level helpers with kmstest_ prefix */
46 
47 /**
48  * pipe:
49  * @PIPE_NONE: Invalid pipe, used for disconnecting a output from a pipe.
50  * @PIPE_ANY: Deprecated alias for @PIPE_NONE.
51  * @PIPE_A: First crtc.
52  * @PIPE_B: Second crtc.
53  * @PIPE_C: Third crtc.
54  * @PIPE_D: Fourth crtc.
55  * @PIPE_E: Fifth crtc.
56  * @PIPE_F: Sixth crtc.
57  * @IGT_MAX_PIPES: Max number of pipes allowed.
58  */
59 enum pipe
60 #ifdef __cplusplus
61 : int
62 #endif
63 {
64         PIPE_NONE = -1,
65         PIPE_ANY = PIPE_NONE,
66         PIPE_A = 0,
67         PIPE_B,
68         PIPE_C,
69         PIPE_D,
70         PIPE_E,
71         PIPE_F,
72         IGT_MAX_PIPES
73 };
74 const char *kmstest_pipe_name(enum pipe pipe);
75 int kmstest_pipe_to_index(char pipe);
76 const char *kmstest_plane_type_name(int plane_type);
77 
78 enum port {
79         PORT_A = 0,
80         PORT_B,
81         PORT_C,
82         PORT_D,
83         PORT_E,
84         I915_MAX_PORTS
85 };
86 
87 /**
88  * kmstest_port_name:
89  * @port: display plane
90  *
91  * Returns: String representing @port, e.g. "A".
92  */
93 #define kmstest_port_name(port) ((port) + 'A')
94 
95 const char *kmstest_encoder_type_str(int type);
96 const char *kmstest_connector_status_str(int status);
97 const char *kmstest_connector_type_str(int type);
98 
99 void kmstest_dump_mode(drmModeModeInfo *mode);
100 
101 int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id);
102 void kmstest_set_vt_graphics_mode(void);
103 void kmstest_restore_vt_mode(void);
104 
105 enum igt_atomic_crtc_properties {
106        IGT_CRTC_BACKGROUND = 0,
107        IGT_CRTC_CTM,
108        IGT_CRTC_GAMMA_LUT,
109        IGT_CRTC_GAMMA_LUT_SIZE,
110        IGT_CRTC_DEGAMMA_LUT,
111        IGT_CRTC_DEGAMMA_LUT_SIZE,
112        IGT_CRTC_MODE_ID,
113        IGT_CRTC_ACTIVE,
114        IGT_CRTC_OUT_FENCE_PTR,
115        IGT_CRTC_VRR_ENABLED,
116        IGT_NUM_CRTC_PROPS
117 };
118 
119 /**
120  * igt_crtc_prop_names
121  *
122  * igt_crtc_prop_names contains a list of crtc property names,
123  * as indexed by the igt_atomic_crtc_properties enum.
124  */
125 extern const char * const igt_crtc_prop_names[];
126 
127 enum igt_atomic_connector_properties {
128        IGT_CONNECTOR_SCALING_MODE = 0,
129        IGT_CONNECTOR_CRTC_ID,
130        IGT_CONNECTOR_DPMS,
131        IGT_CONNECTOR_BROADCAST_RGB,
132        IGT_CONNECTOR_CONTENT_PROTECTION,
133        IGT_CONNECTOR_VRR_CAPABLE,
134        IGT_CONNECTOR_HDCP_CONTENT_TYPE,
135        IGT_CONNECTOR_LINK_STATUS,
136        IGT_NUM_CONNECTOR_PROPS
137 };
138 
139 /**
140  * igt_connector_prop_names
141  *
142  * igt_connector_prop_names contains a list of crtc property names,
143  * as indexed by the igt_atomic_connector_properties enum.
144  */
145 extern const char * const igt_connector_prop_names[];
146 
147 struct kmstest_connector_config {
148 	drmModeCrtc *crtc;
149 	drmModeConnector *connector;
150 	drmModeEncoder *encoder;
151 	drmModeModeInfo default_mode;
152 
153 	int pipe;
154 	unsigned valid_crtc_idx_mask;
155 };
156 
157 struct kmstest_plane {
158 	int id;
159 	int index;
160 	int type;
161 	int pos_x;
162 	int pos_y;
163 	int width;
164 	int height;
165 };
166 
167 struct kmstest_crtc {
168 	int id;
169 	int pipe;
170 	bool active;
171 	int width;
172 	int height;
173 	int n_planes;
174 	struct kmstest_plane *planes;
175 };
176 
177 /**
178  * kmstest_force_connector_state:
179  * @FORCE_CONNECTOR_UNSPECIFIED: Unspecified
180  * @FORCE_CONNECTOR_ON: On
181  * @FORCE_CONNECTOR_DIGITAL: Digital
182  * @FORCE_CONNECTOR_OFF: Off
183  */
184 enum kmstest_force_connector_state {
185 	FORCE_CONNECTOR_UNSPECIFIED,
186 	FORCE_CONNECTOR_ON,
187 	FORCE_CONNECTOR_DIGITAL,
188 	FORCE_CONNECTOR_OFF
189 };
190 
191 /**
192  * intel_broadcast_rgb_mode:
193  * @BROADCAST_RGB_AUTO: Choose the color range to use automatically
194  * @BROADCAST_RGB_FULL: Force the connector to use full color range
195  * @BROADCAST_RGB_16_235: Force the connector to use a limited 16:235 color
196  * range
197  */
198 enum intel_broadcast_rgb_mode {
199 	BROADCAST_RGB_AUTO = 0,
200 	BROADCAST_RGB_FULL,
201 	BROADCAST_RGB_16_235
202 };
203 
204 struct edid;
205 
206 bool kmstest_force_connector(int fd, drmModeConnector *connector,
207 			     enum kmstest_force_connector_state state);
208 void kmstest_force_edid(int drm_fd, drmModeConnector *connector,
209 			const struct edid *edid);
210 
211 bool kmstest_get_connector_default_mode(int drm_fd, drmModeConnector *connector,
212 					drmModeModeInfo *mode);
213 bool kmstest_get_connector_config(int drm_fd, uint32_t connector_id,
214 				  unsigned long crtc_idx_mask,
215 				  struct kmstest_connector_config *config);
216 bool kmstest_probe_connector_config(int drm_fd, uint32_t connector_id,
217 				    unsigned long crtc_idx_mask,
218 				    struct kmstest_connector_config *config);
219 void kmstest_free_connector_config(struct kmstest_connector_config *config);
220 
221 void kmstest_set_connector_dpms(int fd, drmModeConnector *connector, int mode);
222 bool kmstest_get_property(int drm_fd, uint32_t object_id, uint32_t object_type,
223 			  const char *name, uint32_t *prop_id, uint64_t *value,
224 			  drmModePropertyPtr *prop);
225 void kmstest_unset_all_crtcs(int drm_fd, drmModeResPtr resources);
226 int kmstest_get_crtc_idx(drmModeRes *res, uint32_t crtc_id);
227 uint32_t kmstest_find_crtc_for_connector(int fd, drmModeRes *res,
228 					 drmModeConnector *connector,
229 					 uint32_t crtc_blacklist_idx_mask);
230 
231 uint32_t kmstest_dumb_create(int fd, int width, int height, int bpp,
232 			     unsigned *stride, uint64_t *size);
233 
234 void *kmstest_dumb_map_buffer(int fd, uint32_t handle, uint64_t size,
235 			      unsigned prot);
236 void kmstest_dumb_destroy(int fd, uint32_t handle);
237 void kmstest_wait_for_pageflip(int fd);
238 unsigned int kmstest_get_vblank(int fd, int pipe, unsigned int flags);
239 void igt_assert_plane_visible(int fd, enum pipe pipe, int plane_index, bool visibility);
240 
241 bool kms_has_vblank(int fd);
242 
243 /*
244  * A small modeset API
245  */
246 
247 /* High-level kms api with igt_ prefix */
248 
249 /**
250  * igt_commit_style:
251  * @COMMIT_LEGACY: Changes will be committed using the legacy API.
252  * @COMMIT_UNIVERSAL: Changes will be committed with the universal plane API, no modesets are allowed.
253  * @COMMIT_ATOMIC: Changes will be committed using the atomic API.
254  */
255 enum igt_commit_style {
256 	COMMIT_LEGACY = 0,
257 	COMMIT_UNIVERSAL,
258 	COMMIT_ATOMIC,
259 };
260 
261 enum igt_atomic_plane_properties {
262        IGT_PLANE_SRC_X = 0,
263        IGT_PLANE_SRC_Y,
264        IGT_PLANE_SRC_W,
265        IGT_PLANE_SRC_H,
266 
267        IGT_PLANE_CRTC_X,
268        IGT_PLANE_CRTC_Y,
269        IGT_PLANE_CRTC_W,
270        IGT_PLANE_CRTC_H,
271 
272 /* Append new properties after IGT_PLANE_COORD_CHANGED_MASK */
273 #define IGT_PLANE_COORD_CHANGED_MASK 0xff
274 
275        IGT_PLANE_FB_ID,
276        IGT_PLANE_CRTC_ID,
277        IGT_PLANE_IN_FENCE_FD,
278        IGT_PLANE_TYPE,
279        IGT_PLANE_ROTATION,
280        IGT_PLANE_IN_FORMATS,
281        IGT_PLANE_COLOR_ENCODING,
282        IGT_PLANE_COLOR_RANGE,
283        IGT_PLANE_PIXEL_BLEND_MODE,
284        IGT_PLANE_ALPHA,
285        IGT_PLANE_ZPOS,
286        IGT_NUM_PLANE_PROPS
287 };
288 
289 /**
290  * igt_plane_prop_names
291  *
292  * igt_plane_prop_names contains a list of crtc property names,
293  * as indexed by the igt_atomic_plane_properties enum.
294  */
295 extern const char * const igt_plane_prop_names[];
296 
297 typedef struct igt_display igt_display_t;
298 typedef struct igt_pipe igt_pipe_t;
299 typedef uint32_t igt_fixed_t;			/* 16.16 fixed point */
300 
301 typedef enum {
302 	/* this maps to the kernel API */
303 	IGT_ROTATION_0   = 1 << 0,
304 	IGT_ROTATION_90  = 1 << 1,
305 	IGT_ROTATION_180 = 1 << 2,
306 	IGT_ROTATION_270 = 1 << 3,
307 	IGT_REFLECT_X    = 1 << 4,
308 	IGT_REFLECT_Y    = 1 << 5,
309 } igt_rotation_t;
310 
311 #define IGT_ROTATION_MASK \
312 	(IGT_ROTATION_0 | IGT_ROTATION_90 | IGT_ROTATION_180 | IGT_ROTATION_270)
313 
314 typedef struct igt_plane {
315 	/*< private >*/
316 	igt_pipe_t *pipe;
317 	struct igt_plane *ref;
318 	int index;
319 	/* capabilities */
320 	int type;
321 
322 	/*
323 	 * drm_plane can be NULL for primary and cursor planes (when not
324 	 * using the atomic modeset API)
325 	 */
326 	drmModePlane *drm_plane;
327 
328 	/* gem handle for fb */
329 	uint32_t gem_handle;
330 
331 	struct {
332 		uint64_t values[IGT_NUM_COLOR_ENCODINGS];
333 	} color_encoding;
334 	struct {
335 		uint64_t values[IGT_NUM_COLOR_RANGES];
336 	} color_range;
337 
338 	uint64_t changed;
339 	uint32_t props[IGT_NUM_PLANE_PROPS];
340 	uint64_t values[IGT_NUM_PLANE_PROPS];
341 
342 	uint64_t *modifiers;
343 	uint32_t *formats;
344 	int format_mod_count;
345 } igt_plane_t;
346 
347 struct igt_pipe {
348 	igt_display_t *display;
349 	enum pipe pipe;
350 
351 	int n_planes;
352 	int plane_cursor;
353 	int plane_primary;
354 	igt_plane_t *planes;
355 
356 	uint64_t changed;
357 	uint32_t props[IGT_NUM_CRTC_PROPS];
358 	uint64_t values[IGT_NUM_CRTC_PROPS];
359 
360 	uint32_t crtc_id;
361 
362 	int32_t out_fence_fd;
363 };
364 
365 typedef struct {
366 	/*< private >*/
367 	igt_display_t *display;
368 	uint32_t id;					/* KMS id */
369 	struct kmstest_connector_config config;
370 	char *name;
371 	bool force_reprobe;
372 	enum pipe pending_pipe;
373 	bool use_override_mode;
374 	drmModeModeInfo override_mode;
375 
376 	/* bitmask of changed properties */
377 	uint64_t changed;
378 
379 	uint32_t props[IGT_NUM_CONNECTOR_PROPS];
380 	uint64_t values[IGT_NUM_CONNECTOR_PROPS];
381 } igt_output_t;
382 
383 struct igt_display {
384 	int drm_fd;
385 	int log_shift;
386 	int n_pipes;
387 	int n_planes;
388 	int n_outputs;
389 	igt_output_t *outputs;
390 	igt_plane_t *planes;
391 	igt_pipe_t *pipes;
392 	bool has_cursor_plane;
393 	bool is_atomic;
394 	bool first_commit;
395 
396 	uint64_t *modifiers;
397 	uint32_t *formats;
398 	int format_mod_count;
399 };
400 
401 void igt_display_require(igt_display_t *display, int drm_fd);
402 void igt_display_fini(igt_display_t *display);
403 void igt_display_reset(igt_display_t *display);
404 int  igt_display_commit2(igt_display_t *display, enum igt_commit_style s);
405 int  igt_display_commit(igt_display_t *display);
406 int  igt_display_try_commit_atomic(igt_display_t *display, uint32_t flags, void *user_data);
407 void igt_display_commit_atomic(igt_display_t *display, uint32_t flags, void *user_data);
408 int  igt_display_try_commit2(igt_display_t *display, enum igt_commit_style s);
409 int  igt_display_drop_events(igt_display_t *display);
410 int  igt_display_get_n_pipes(igt_display_t *display);
411 void igt_display_require_output(igt_display_t *display);
412 void igt_display_require_output_on_pipe(igt_display_t *display, enum pipe pipe);
413 
414 const char *igt_output_name(igt_output_t *output);
415 drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
416 void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
417 void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
418 igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
419 igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
420 int igt_output_count_plane_type(igt_output_t *output, int plane_type);
421 igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
422 					     int plane_type, int index);
423 igt_output_t *igt_output_from_connector(igt_display_t *display,
424     drmModeConnector *connector);
425 const drmModeModeInfo *igt_std_1024_mode_get(void);
426 
427 igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
428 int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
429 igt_plane_t *igt_pipe_get_plane_type_index(igt_pipe_t *pipe, int plane_type,
430 					   int index);
431 igt_output_t *igt_get_single_output_for_pipe(igt_display_t *display, enum pipe pipe);
432 
433 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
434 
435 void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb);
436 void igt_plane_set_fence_fd(igt_plane_t *plane, int fence_fd);
437 void igt_plane_set_pipe(igt_plane_t *plane, igt_pipe_t *pipe);
438 void igt_plane_set_position(igt_plane_t *plane, int x, int y);
439 void igt_plane_set_size(igt_plane_t *plane, int w, int h);
440 void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation);
441 void igt_fb_set_position(struct igt_fb *fb, igt_plane_t *plane,
442 	uint32_t x, uint32_t y);
443 void igt_fb_set_size(struct igt_fb *fb, igt_plane_t *plane,
444 	uint32_t w, uint32_t h);
445 
446 void igt_wait_for_vblank(int drm_fd, enum pipe pipe);
447 void igt_wait_for_vblank_count(int drm_fd, enum pipe pipe, int count);
448 
igt_output_is_connected(igt_output_t * output)449 static inline bool igt_output_is_connected(igt_output_t *output)
450 {
451 	/* Something went wrong during probe? */
452 	if (!output->config.connector ||
453 	    !output->config.connector->count_modes)
454 		return false;
455 
456 	if (output->config.connector->connection == DRM_MODE_CONNECTED)
457 		return true;
458 
459 	return false;
460 }
461 
462 /**
463  * igt_pipe_connector_valid:
464  * @pipe: pipe to check.
465  * @output: #igt_output_t to check.
466  *
467  * Checks whether the given pipe and output can be used together.
468  */
469 #define igt_pipe_connector_valid(pipe, output) \
470 	(igt_output_is_connected((output)) && \
471 	       (output->config.valid_crtc_idx_mask & (1 << (pipe))))
472 
473 #define for_each_if(condition) if (!(condition)) {} else
474 
475 /**
476  * for_each_connected_output:
477  * @display: a pointer to an #igt_display_t structure
478  * @output: The output to iterate.
479  *
480  * This for loop iterates over all outputs.
481  */
482 #define for_each_connected_output(display, output)		\
483 	for (int i__ = 0;  assert(igt_can_fail()), i__ < (display)->n_outputs; i__++)	\
484 		for_each_if ((((output) = &(display)->outputs[i__]), \
485 			      igt_output_is_connected((output))))
486 
487 /**
488  * for_each_pipe_static:
489  * @pipe: The pipe to iterate.
490  *
491  * This for loop iterates over all pipes supported by IGT libraries.
492  *
493  * This should be used to enumerate per-pipe subtests since it has no runtime
494  * depencies.
495  */
496 #define for_each_pipe_static(pipe) \
497 	for (pipe = 0; pipe < IGT_MAX_PIPES; pipe++)
498 
499 /**
500  * for_each_pipe:
501  * @display: a pointer to an #igt_display_t structure
502  * @pipe: The pipe to iterate.
503  *
504  * This for loop iterates over all pipes.
505  *
506  * Note that this cannot be used to enumerate per-pipe subtest names since it
507  * depends upon runtime probing of the actual kms driver that is being tested.
508  * Use #for_each_pipe_static instead.
509  */
510 #ifdef __cplusplus
511 #define for_each_pipe(display, pipe_i)					\
512 	for (pipe_i = (enum pipe)0; assert(igt_can_fail()), pipe_i < igt_display_get_n_pipes(display); pipe_i = (enum pipe)((int)pipe_i + 1))
513 #else
514 #define for_each_pipe(display, pipe)					\
515 	for (pipe = 0; assert(igt_can_fail()), pipe < igt_display_get_n_pipes(display); pipe++)
516 #endif
517 
518 /**
519  * for_each_pipe_with_valid_output:
520  * @display: a pointer to an #igt_display_t structure
521  * @pipe: The pipe for which this @pipe / @output combination is valid.
522  * @output: The output for which this @pipe / @output combination is valid.
523  *
524  * This for loop is called over all connected outputs. This function
525  * will try every combination of @pipe and @output.
526  *
527  * If you only need to test a single output for each pipe, use
528  * for_each_pipe_with_single_output(), if you only need an
529  * output for a single pipe, use igt_get_single_output_for_pipe().
530  */
531 #define for_each_pipe_with_valid_output(display, pipe, output) \
532 	for (int con__ = (pipe) = 0; \
533 	     assert(igt_can_fail()), (pipe) < igt_display_get_n_pipes((display)) && con__ < (display)->n_outputs; \
534 	     con__ = (con__ + 1 < (display)->n_outputs) ? con__ + 1 : (pipe = pipe + 1, 0)) \
535 		for_each_if ((((output) = &(display)->outputs[con__]), \
536 			     igt_pipe_connector_valid((pipe), (output))))
537 
538 igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display,
539 					   igt_output_t **chosen_outputs);
540 
541 /**
542  * for_each_pipe_with_single_output:
543  * @display: a pointer to an #igt_display_t structure
544  * @pipe: The pipe for which this @pipe / @output combination is valid.
545  * @output: The output for which this @pipe / @output combination is valid.
546  *
547  * This loop is called over all pipes, and will try to find a compatible output
548  * for each pipe. Unlike for_each_pipe_with_valid_output(), this function will
549  * be called at most once for each pipe.
550  */
551 #define for_each_pipe_with_single_output(display, pipe, output) \
552 	for (igt_output_t *__outputs[(display)->n_pipes], \
553 	     **__output = __igt_pipe_populate_outputs((display), __outputs); \
554 	     __output < &__outputs[(display)->n_pipes]; __output++) \
555 		for_each_if (*__output && \
556 			     ((pipe) = (__output - __outputs), (output) = *__output, 1))
557 
558 /**
559  * for_each_valid_output_on_pipe:
560  * @display: a pointer to an #igt_display_t structure
561  * @pipe: Pipe to enumerate valid outputs over
562  * @output: The enumerated output.
563  *
564  * This for loop is called over all connected @output that can be used
565  * on this @pipe . If there are no valid outputs for this pipe, nothing
566  * happens.
567  */
568 #define for_each_valid_output_on_pipe(display, pipe, output) \
569 	for_each_connected_output((display), (output)) \
570 		for_each_if (igt_pipe_connector_valid((pipe), (output)))
571 
572 #define for_each_plane_on_pipe(display, pipe, plane)			\
573 	for (int j__ = 0; assert(igt_can_fail()), (plane) = &(display)->pipes[(pipe)].planes[j__], \
574 		     j__ < (display)->pipes[(pipe)].n_planes; j__++)
575 
576 #define IGT_FIXED(i,f)	((i) << 16 | (f))
577 
578 /**
579  * igt_plane_has_prop:
580  * @plane: Plane to check.
581  * @prop: Property to check.
582  *
583  * Check whether plane supports a given property.
584  *
585  * Returns: True if the property is supported, otherwise false.
586  */
587 static inline bool
igt_plane_has_prop(igt_plane_t * plane,enum igt_atomic_plane_properties prop)588 igt_plane_has_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
589 {
590 	return plane->props[prop];
591 }
592 
593 uint64_t igt_plane_get_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
594 
595 #define igt_plane_is_prop_changed(plane, prop) \
596 	(!!((plane)->changed & (1 << (prop))))
597 
598 #define igt_plane_set_prop_changed(plane, prop) \
599 	(plane)->changed |= 1 << (prop)
600 
601 #define igt_plane_clear_prop_changed(plane, prop) \
602 	(plane)->changed &= ~(1 << (prop))
603 
604 #define igt_plane_set_prop_value(plane, prop, value) \
605 	do { \
606 		plane->values[prop] = value; \
607 		igt_plane_set_prop_changed(plane, prop); \
608 	} while (0)
609 
610 extern bool igt_plane_try_prop_enum(igt_plane_t *plane,
611 				    enum igt_atomic_plane_properties prop,
612 				    const char *val);
613 
614 extern void igt_plane_set_prop_enum(igt_plane_t *plane,
615 				    enum igt_atomic_plane_properties prop,
616 				    const char *val);
617 
618 extern void igt_plane_replace_prop_blob(igt_plane_t *plane,
619 					enum igt_atomic_plane_properties prop,
620 					const void *ptr, size_t length);
621 
622 /**
623  * igt_output_has_prop:
624  * @output: Output to check.
625  * @prop: Property to check.
626  *
627  * Check whether output supports a given property.
628  *
629  * Returns: True if the property is supported, otherwise false.
630  */
631 static inline bool
igt_output_has_prop(igt_output_t * output,enum igt_atomic_connector_properties prop)632 igt_output_has_prop(igt_output_t *output, enum igt_atomic_connector_properties prop)
633 {
634 	return output->props[prop];
635 }
636 
637 uint64_t igt_output_get_prop(igt_output_t *output, enum igt_atomic_connector_properties prop);
638 
639 #define igt_output_is_prop_changed(output, prop) \
640 	(!!((output)->changed & (1 << (prop))))
641 #define igt_output_set_prop_changed(output, prop) \
642 	(output)->changed |= 1 << (prop)
643 
644 #define igt_output_clear_prop_changed(output, prop) \
645 	(output)->changed &= ~(1 << (prop))
646 
647 #define igt_output_set_prop_value(output, prop, value) \
648 	do { \
649 		(output)->values[prop] = (value); \
650 		igt_output_set_prop_changed(output, prop); \
651 	} while (0)
652 
653 extern bool igt_output_try_prop_enum(igt_output_t *output,
654 				     enum igt_atomic_connector_properties prop,
655 				     const char *val);
656 
657 extern void igt_output_set_prop_enum(igt_output_t *output,
658 				     enum igt_atomic_connector_properties prop,
659 				     const char *val);
660 
661 extern void igt_output_replace_prop_blob(igt_output_t *output,
662 					 enum igt_atomic_connector_properties prop,
663 					 const void *ptr, size_t length);
664 /**
665  * igt_pipe_obj_has_prop:
666  * @pipe: Pipe to check.
667  * @prop: Property to check.
668  *
669  * Check whether pipe supports a given property.
670  *
671  * Returns: True if the property is supported, otherwise false.
672  */
673 static inline bool
igt_pipe_obj_has_prop(igt_pipe_t * pipe,enum igt_atomic_crtc_properties prop)674 igt_pipe_obj_has_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
675 {
676 	return pipe->props[prop];
677 }
678 
679 uint64_t igt_pipe_obj_get_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
680 
681 /**
682  * igt_pipe_get_prop:
683  * @display: Pointer to display.
684  * @pipe: Target pipe.
685  * @prop: Property to return.
686  *
687  * Return current value on a pipe for a given property.
688  *
689  * Returns: The value the property is set to, if this
690  * is a blob, the blob id is returned. This can be passed
691  * to drmModeGetPropertyBlob() to get the contents of the blob.
692  */
693 static inline uint64_t
igt_pipe_get_prop(igt_display_t * display,enum pipe pipe,enum igt_atomic_crtc_properties prop)694 igt_pipe_get_prop(igt_display_t *display, enum pipe pipe,
695 		  enum igt_atomic_crtc_properties prop)
696 {
697 	return igt_pipe_obj_get_prop(&display->pipes[pipe], prop);
698 }
699 
700 /**
701  * igt_pipe_has_prop:
702  * @display: Pointer to display.
703  * @pipe: Pipe to check.
704  * @prop: Property to check.
705  *
706  * Check whether pipe supports a given property.
707  *
708  * Returns: True if the property is supported, otherwise false.
709  */
710 static inline bool
igt_pipe_has_prop(igt_display_t * display,enum pipe pipe,enum igt_atomic_crtc_properties prop)711 igt_pipe_has_prop(igt_display_t *display, enum pipe pipe,
712 		  enum igt_atomic_crtc_properties prop)
713 {
714 	return display->pipes[pipe].props[prop];
715 }
716 
717 #define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
718 	(!!((pipe_obj)->changed & (1 << (prop))))
719 
720 #define igt_pipe_is_prop_changed(display, pipe, prop) \
721 	igt_pipe_obj_is_prop_changed(&(display)->pipes[(pipe)], prop)
722 
723 #define igt_pipe_obj_set_prop_changed(pipe_obj, prop) \
724 	(pipe_obj)->changed |= 1 << (prop)
725 
726 #define igt_pipe_set_prop_changed(display, pipe, prop) \
727 	igt_pipe_obj_set_prop_changed(&(display)->pipes[(pipe)], prop)
728 
729 #define igt_pipe_obj_clear_prop_changed(pipe_obj, prop) \
730 	(pipe_obj)->changed &= ~(1 << (prop))
731 
732 #define igt_pipe_clear_prop_changed(display, pipe, prop) \
733 	igt_pipe_obj_clear_prop_changed(&(display)->pipes[(pipe)], prop)
734 
735 #define igt_pipe_obj_set_prop_value(pipe_obj, prop, value) \
736 	do { \
737 		(pipe_obj)->values[prop] = (value); \
738 		igt_pipe_obj_set_prop_changed(pipe_obj, prop); \
739 	} while (0)
740 
741 #define igt_pipe_set_prop_value(display, pipe, prop, value) \
742 	igt_pipe_obj_set_prop_value(&(display)->pipes[(pipe)], prop, value)
743 
744 extern bool igt_pipe_obj_try_prop_enum(igt_pipe_t *pipe,
745 				       enum igt_atomic_crtc_properties prop,
746 				       const char *val);
747 
748 extern void igt_pipe_obj_set_prop_enum(igt_pipe_t *pipe,
749 				       enum igt_atomic_crtc_properties prop,
750 				       const char *val);
751 
752 #define igt_pipe_try_prop_enum(display, pipe, prop, val) \
753 	igt_pipe_obj_try_prop_enum(&(display)->pipes[(pipe)], prop, val)
754 
755 #define igt_pipe_set_prop_enum(display, pipe, prop, val) \
756 	igt_pipe_obj_set_prop_enum(&(display)->pipes[(pipe)], prop, val)
757 
758 extern void igt_pipe_obj_replace_prop_blob(igt_pipe_t *pipe,
759 					   enum igt_atomic_crtc_properties prop,
760 					   const void *ptr, size_t length);
761 
762 #define igt_pipe_replace_prop_blob(display, pipe, prop, ptr, length) \
763 	igt_pipe_obj_replace_prop_blob(&(display)->pipes[(pipe)], prop, ptr, length)
764 
765 void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force);
766 
767 void igt_enable_connectors(int drm_fd);
768 void igt_reset_connectors(void);
769 
770 uint32_t kmstest_get_vbl_flag(uint32_t pipe_id);
771 
772 const struct edid *igt_kms_get_base_edid(void);
773 const struct edid *igt_kms_get_alt_edid(void);
774 const struct edid *igt_kms_get_hdmi_audio_edid(void);
775 const struct edid *igt_kms_get_dp_audio_edid(void);
776 const struct edid *igt_kms_get_4k_edid(void);
777 const struct edid *igt_kms_get_3d_edid(void);
778 
779 struct udev_monitor *igt_watch_hotplug(void);
780 bool igt_hotplug_detected(struct udev_monitor *mon,
781 			  int timeout_secs);
782 bool igt_lease_change_detected(struct udev_monitor *mon,
783 			       int timeout_secs);
784 void igt_flush_hotplugs(struct udev_monitor *mon);
785 void igt_cleanup_hotplug(struct udev_monitor *mon);
786 
787 bool igt_display_has_format_mod(igt_display_t *display, uint32_t format, uint64_t modifier);
788 bool igt_plane_has_format_mod(igt_plane_t *plane, uint32_t format, uint64_t modifier);
789 
790 /**
791  * igt_vblank_after_eq:
792  * @a: First vblank sequence number.
793  * @b: Second vblank sequence number.
794  *
795  * Compare vblank sequence numbers,
796  * handling wraparound correctly.
797  *
798  * Returns: @a >= @b
799  */
igt_vblank_after_eq(uint32_t a,uint32_t b)800 static inline bool igt_vblank_after_eq(uint32_t a, uint32_t b)
801 {
802 	return (int32_t)(a - b) >= 0;
803 }
804 
805 /**
806  * igt_vblank_before_eq:
807  * @a: First vblank sequence number.
808  * @b: Second vblank sequence number.
809  *
810  * Compare vblank sequence numbers,
811  * handling wraparound correctly.
812  *
813  * Returns: @a <= @b
814  */
igt_vblank_before_eq(uint32_t a,uint32_t b)815 static inline bool igt_vblank_before_eq(uint32_t a, uint32_t b)
816 {
817 	return igt_vblank_after_eq(b, a);
818 }
819 
820 /**
821  * igt_vblank_after:
822  * @a: First vblank sequence number.
823  * @b: Second vblank sequence number.
824  *
825  * Compare vblank sequence numbers,
826  * handling wraparound correctly.
827  *
828  * Returns: @a > @b
829  */
igt_vblank_after(uint32_t a,uint32_t b)830 static inline bool igt_vblank_after(uint32_t a, uint32_t b)
831 {
832 	return (int32_t)(b - a) < 0;
833 }
834 
835 /**
836  * igt_vblank_before:
837  * @a: First vblank sequence number.
838  * @b: Second vblank sequence number.
839  *
840  * Compare vblank sequence numbers,
841  * handling wraparound correctly.
842  *
843  * Returns: @a < @b
844  */
igt_vblank_before(uint32_t a,uint32_t b)845 static inline bool igt_vblank_before(uint32_t a, uint32_t b)
846 {
847 	return igt_vblank_after(b, a);
848 }
849 
850 #ifdef __cplusplus
851 }
852 #endif
853 
854 #endif /* __IGT_KMS_H__ */
855