xref: /aosp_15_r20/external/igt-gpu-tools/lib/igt_kms.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2013 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  * Authors:
24*d83cc019SAndroid Build Coastguard Worker  * 	Daniel Vetter <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker  * 	Damien Lespiau <[email protected]>
26*d83cc019SAndroid Build Coastguard Worker  */
27*d83cc019SAndroid Build Coastguard Worker 
28*d83cc019SAndroid Build Coastguard Worker #include "config.h"
29*d83cc019SAndroid Build Coastguard Worker 
30*d83cc019SAndroid Build Coastguard Worker #include <assert.h>
31*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
32*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
33*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
34*d83cc019SAndroid Build Coastguard Worker #include <stdarg.h>
35*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
36*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
37*d83cc019SAndroid Build Coastguard Worker #include <string.h>
38*d83cc019SAndroid Build Coastguard Worker #include <strings.h>
39*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
40*d83cc019SAndroid Build Coastguard Worker #ifdef HAVE_LINUX_KD_H
41*d83cc019SAndroid Build Coastguard Worker #include <linux/kd.h>
42*d83cc019SAndroid Build Coastguard Worker #elif HAVE_SYS_KD_H
43*d83cc019SAndroid Build Coastguard Worker #include <sys/kd.h>
44*d83cc019SAndroid Build Coastguard Worker #endif
45*d83cc019SAndroid Build Coastguard Worker 
46*d83cc019SAndroid Build Coastguard Worker #if !defined(ANDROID)
47*d83cc019SAndroid Build Coastguard Worker #include <libudev.h>
48*d83cc019SAndroid Build Coastguard Worker #endif
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker #include <poll.h>
51*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
52*d83cc019SAndroid Build Coastguard Worker #include <time.h>
53*d83cc019SAndroid Build Coastguard Worker 
54*d83cc019SAndroid Build Coastguard Worker #include <i915_drm.h>
55*d83cc019SAndroid Build Coastguard Worker 
56*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
57*d83cc019SAndroid Build Coastguard Worker #include "igt_kms.h"
58*d83cc019SAndroid Build Coastguard Worker #include "igt_aux.h"
59*d83cc019SAndroid Build Coastguard Worker #include "igt_edid.h"
60*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
61*d83cc019SAndroid Build Coastguard Worker #include "igt_debugfs.h"
62*d83cc019SAndroid Build Coastguard Worker #include "igt_device.h"
63*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
64*d83cc019SAndroid Build Coastguard Worker #include "sw_sync.h"
65*d83cc019SAndroid Build Coastguard Worker 
66*d83cc019SAndroid Build Coastguard Worker /**
67*d83cc019SAndroid Build Coastguard Worker  * SECTION:igt_kms
68*d83cc019SAndroid Build Coastguard Worker  * @short_description: Kernel modesetting support library
69*d83cc019SAndroid Build Coastguard Worker  * @title: KMS
70*d83cc019SAndroid Build Coastguard Worker  * @include: igt.h
71*d83cc019SAndroid Build Coastguard Worker  *
72*d83cc019SAndroid Build Coastguard Worker  * This library provides support to enumerate and set modeset configurations.
73*d83cc019SAndroid Build Coastguard Worker  *
74*d83cc019SAndroid Build Coastguard Worker  * There are two parts in this library: First the low level helper function
75*d83cc019SAndroid Build Coastguard Worker  * which directly build on top of raw ioctls or the interfaces provided by
76*d83cc019SAndroid Build Coastguard Worker  * libdrm. Those functions all have a kmstest_ prefix.
77*d83cc019SAndroid Build Coastguard Worker  *
78*d83cc019SAndroid Build Coastguard Worker  * The second part is a high-level library to manage modeset configurations
79*d83cc019SAndroid Build Coastguard Worker  * which abstracts away some of the low-level details like the difference
80*d83cc019SAndroid Build Coastguard Worker  * between legacy and universal plane support for setting cursors or in the
81*d83cc019SAndroid Build Coastguard Worker  * future the difference between legacy and atomic commit. These high-level
82*d83cc019SAndroid Build Coastguard Worker  * functions have all igt_ prefixes. This part is still very much work in
83*d83cc019SAndroid Build Coastguard Worker  * progress and so also lacks a bit documentation for the individual functions.
84*d83cc019SAndroid Build Coastguard Worker  *
85*d83cc019SAndroid Build Coastguard Worker  * Note that this library's header pulls in the [i-g-t framebuffer](igt-gpu-tools-i-g-t-framebuffer.html)
86*d83cc019SAndroid Build Coastguard Worker  * library as a dependency.
87*d83cc019SAndroid Build Coastguard Worker  */
88*d83cc019SAndroid Build Coastguard Worker 
89*d83cc019SAndroid Build Coastguard Worker /* list of connectors that need resetting on exit */
90*d83cc019SAndroid Build Coastguard Worker #define MAX_CONNECTORS 32
91*d83cc019SAndroid Build Coastguard Worker static char *forced_connectors[MAX_CONNECTORS + 1];
92*d83cc019SAndroid Build Coastguard Worker static int forced_connectors_device[MAX_CONNECTORS + 1];
93*d83cc019SAndroid Build Coastguard Worker 
94*d83cc019SAndroid Build Coastguard Worker /**
95*d83cc019SAndroid Build Coastguard Worker  * igt_kms_get_base_edid:
96*d83cc019SAndroid Build Coastguard Worker  *
97*d83cc019SAndroid Build Coastguard Worker  * Get the base edid block, which includes the following modes:
98*d83cc019SAndroid Build Coastguard Worker  *
99*d83cc019SAndroid Build Coastguard Worker  *  - 1920x1080 60Hz
100*d83cc019SAndroid Build Coastguard Worker  *  - 1280x720 60Hz
101*d83cc019SAndroid Build Coastguard Worker  *  - 1024x768 60Hz
102*d83cc019SAndroid Build Coastguard Worker  *  - 800x600 60Hz
103*d83cc019SAndroid Build Coastguard Worker  *  - 640x480 60Hz
104*d83cc019SAndroid Build Coastguard Worker  *
105*d83cc019SAndroid Build Coastguard Worker  * Returns: a basic edid block
106*d83cc019SAndroid Build Coastguard Worker  */
igt_kms_get_base_edid(void)107*d83cc019SAndroid Build Coastguard Worker const struct edid *igt_kms_get_base_edid(void)
108*d83cc019SAndroid Build Coastguard Worker {
109*d83cc019SAndroid Build Coastguard Worker 	static struct edid edid;
110*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo mode = {};
111*d83cc019SAndroid Build Coastguard Worker 
112*d83cc019SAndroid Build Coastguard Worker 	mode.clock = 148500;
113*d83cc019SAndroid Build Coastguard Worker 	mode.hdisplay = 1920;
114*d83cc019SAndroid Build Coastguard Worker 	mode.hsync_start = 2008;
115*d83cc019SAndroid Build Coastguard Worker 	mode.hsync_end = 2052;
116*d83cc019SAndroid Build Coastguard Worker 	mode.htotal = 2200;
117*d83cc019SAndroid Build Coastguard Worker 	mode.vdisplay = 1080;
118*d83cc019SAndroid Build Coastguard Worker 	mode.vsync_start = 1084;
119*d83cc019SAndroid Build Coastguard Worker 	mode.vsync_end = 1089;
120*d83cc019SAndroid Build Coastguard Worker 	mode.vtotal = 1125;
121*d83cc019SAndroid Build Coastguard Worker 	mode.vrefresh = 60;
122*d83cc019SAndroid Build Coastguard Worker 
123*d83cc019SAndroid Build Coastguard Worker 	edid_init_with_mode(&edid, &mode);
124*d83cc019SAndroid Build Coastguard Worker 	edid_update_checksum(&edid);
125*d83cc019SAndroid Build Coastguard Worker 
126*d83cc019SAndroid Build Coastguard Worker 	return &edid;
127*d83cc019SAndroid Build Coastguard Worker }
128*d83cc019SAndroid Build Coastguard Worker 
129*d83cc019SAndroid Build Coastguard Worker /**
130*d83cc019SAndroid Build Coastguard Worker  * igt_kms_get_alt_edid:
131*d83cc019SAndroid Build Coastguard Worker  *
132*d83cc019SAndroid Build Coastguard Worker  * Get an alternate edid block, which includes the following modes:
133*d83cc019SAndroid Build Coastguard Worker  *
134*d83cc019SAndroid Build Coastguard Worker  *  - 1400x1050 60Hz
135*d83cc019SAndroid Build Coastguard Worker  *  - 1920x1080 60Hz
136*d83cc019SAndroid Build Coastguard Worker  *  - 1280x720 60Hz
137*d83cc019SAndroid Build Coastguard Worker  *  - 1024x768 60Hz
138*d83cc019SAndroid Build Coastguard Worker  *  - 800x600 60Hz
139*d83cc019SAndroid Build Coastguard Worker  *  - 640x480 60Hz
140*d83cc019SAndroid Build Coastguard Worker  *
141*d83cc019SAndroid Build Coastguard Worker  * Returns: an alternate edid block
142*d83cc019SAndroid Build Coastguard Worker  */
igt_kms_get_alt_edid(void)143*d83cc019SAndroid Build Coastguard Worker const struct edid *igt_kms_get_alt_edid(void)
144*d83cc019SAndroid Build Coastguard Worker {
145*d83cc019SAndroid Build Coastguard Worker 	static struct edid edid;
146*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo mode = {};
147*d83cc019SAndroid Build Coastguard Worker 
148*d83cc019SAndroid Build Coastguard Worker 	mode.clock = 101000;
149*d83cc019SAndroid Build Coastguard Worker 	mode.hdisplay = 1400;
150*d83cc019SAndroid Build Coastguard Worker 	mode.hsync_start = 1448;
151*d83cc019SAndroid Build Coastguard Worker 	mode.hsync_end = 1480;
152*d83cc019SAndroid Build Coastguard Worker 	mode.htotal = 1560;
153*d83cc019SAndroid Build Coastguard Worker 	mode.vdisplay = 1050;
154*d83cc019SAndroid Build Coastguard Worker 	mode.vsync_start = 1053;
155*d83cc019SAndroid Build Coastguard Worker 	mode.vsync_end = 1057;
156*d83cc019SAndroid Build Coastguard Worker 	mode.vtotal = 1080;
157*d83cc019SAndroid Build Coastguard Worker 	mode.vrefresh = 60;
158*d83cc019SAndroid Build Coastguard Worker 
159*d83cc019SAndroid Build Coastguard Worker 	edid_init_with_mode(&edid, &mode);
160*d83cc019SAndroid Build Coastguard Worker 	edid_update_checksum(&edid);
161*d83cc019SAndroid Build Coastguard Worker 
162*d83cc019SAndroid Build Coastguard Worker 	return &edid;
163*d83cc019SAndroid Build Coastguard Worker }
164*d83cc019SAndroid Build Coastguard Worker 
165*d83cc019SAndroid Build Coastguard Worker #define AUDIO_EDID_SIZE (2 * EDID_BLOCK_SIZE)
166*d83cc019SAndroid Build Coastguard Worker 
167*d83cc019SAndroid Build Coastguard Worker static const struct edid *
generate_audio_edid(unsigned char raw_edid[static AUDIO_EDID_SIZE],bool with_vsdb,struct cea_sad * sad,struct cea_speaker_alloc * speaker_alloc)168*d83cc019SAndroid Build Coastguard Worker generate_audio_edid(unsigned char raw_edid[static AUDIO_EDID_SIZE],
169*d83cc019SAndroid Build Coastguard Worker 		    bool with_vsdb, struct cea_sad *sad,
170*d83cc019SAndroid Build Coastguard Worker 		    struct cea_speaker_alloc *speaker_alloc)
171*d83cc019SAndroid Build Coastguard Worker {
172*d83cc019SAndroid Build Coastguard Worker 	struct edid *edid;
173*d83cc019SAndroid Build Coastguard Worker 	struct edid_ext *edid_ext;
174*d83cc019SAndroid Build Coastguard Worker 	struct edid_cea *edid_cea;
175*d83cc019SAndroid Build Coastguard Worker 	char *cea_data;
176*d83cc019SAndroid Build Coastguard Worker 	struct edid_cea_data_block *block;
177*d83cc019SAndroid Build Coastguard Worker 	const struct cea_vsdb *vsdb;
178*d83cc019SAndroid Build Coastguard Worker 	size_t cea_data_size, vsdb_size;
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 	/* Create a new EDID from the base IGT EDID, and add an
181*d83cc019SAndroid Build Coastguard Worker 	 * extension that advertises audio support. */
182*d83cc019SAndroid Build Coastguard Worker 	edid = (struct edid *) raw_edid;
183*d83cc019SAndroid Build Coastguard Worker 	memcpy(edid, igt_kms_get_base_edid(), sizeof(struct edid));
184*d83cc019SAndroid Build Coastguard Worker 	edid->extensions_len = 1;
185*d83cc019SAndroid Build Coastguard Worker 	edid_ext = &edid->extensions[0];
186*d83cc019SAndroid Build Coastguard Worker 	edid_cea = &edid_ext->data.cea;
187*d83cc019SAndroid Build Coastguard Worker 	cea_data = edid_cea->data;
188*d83cc019SAndroid Build Coastguard Worker 	cea_data_size = 0;
189*d83cc019SAndroid Build Coastguard Worker 
190*d83cc019SAndroid Build Coastguard Worker 	/* Short Audio Descriptor block */
191*d83cc019SAndroid Build Coastguard Worker 	block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
192*d83cc019SAndroid Build Coastguard Worker 	cea_data_size += edid_cea_data_block_set_sad(block, sad, 1);
193*d83cc019SAndroid Build Coastguard Worker 
194*d83cc019SAndroid Build Coastguard Worker 	/* A Vendor Specific Data block is needed for HDMI audio */
195*d83cc019SAndroid Build Coastguard Worker 	if (with_vsdb) {
196*d83cc019SAndroid Build Coastguard Worker 		block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
197*d83cc019SAndroid Build Coastguard Worker 		vsdb = cea_vsdb_get_hdmi_default(&vsdb_size);
198*d83cc019SAndroid Build Coastguard Worker 		cea_data_size += edid_cea_data_block_set_vsdb(block, vsdb,
199*d83cc019SAndroid Build Coastguard Worker 							      vsdb_size);
200*d83cc019SAndroid Build Coastguard Worker 	}
201*d83cc019SAndroid Build Coastguard Worker 
202*d83cc019SAndroid Build Coastguard Worker 	/* Speaker Allocation Data block */
203*d83cc019SAndroid Build Coastguard Worker 	block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
204*d83cc019SAndroid Build Coastguard Worker 	cea_data_size += edid_cea_data_block_set_speaker_alloc(block,
205*d83cc019SAndroid Build Coastguard Worker 							       speaker_alloc);
206*d83cc019SAndroid Build Coastguard Worker 
207*d83cc019SAndroid Build Coastguard Worker 	assert(cea_data_size <= sizeof(edid_cea->data));
208*d83cc019SAndroid Build Coastguard Worker 
209*d83cc019SAndroid Build Coastguard Worker 	edid_ext_set_cea(edid_ext, cea_data_size, 0, EDID_CEA_BASIC_AUDIO);
210*d83cc019SAndroid Build Coastguard Worker 
211*d83cc019SAndroid Build Coastguard Worker 	edid_update_checksum(edid);
212*d83cc019SAndroid Build Coastguard Worker 
213*d83cc019SAndroid Build Coastguard Worker 	return edid;
214*d83cc019SAndroid Build Coastguard Worker }
215*d83cc019SAndroid Build Coastguard Worker 
igt_kms_get_hdmi_audio_edid(void)216*d83cc019SAndroid Build Coastguard Worker const struct edid *igt_kms_get_hdmi_audio_edid(void)
217*d83cc019SAndroid Build Coastguard Worker {
218*d83cc019SAndroid Build Coastguard Worker 	int channels;
219*d83cc019SAndroid Build Coastguard Worker 	uint8_t sampling_rates, sample_sizes;
220*d83cc019SAndroid Build Coastguard Worker 	static unsigned char raw_edid[AUDIO_EDID_SIZE] = {0};
221*d83cc019SAndroid Build Coastguard Worker 	struct cea_sad sad = {0};
222*d83cc019SAndroid Build Coastguard Worker 	struct cea_speaker_alloc speaker_alloc = {0};
223*d83cc019SAndroid Build Coastguard Worker 
224*d83cc019SAndroid Build Coastguard Worker 	/* Initialize the Short Audio Descriptor for PCM */
225*d83cc019SAndroid Build Coastguard Worker 	channels = 2;
226*d83cc019SAndroid Build Coastguard Worker 	sampling_rates = CEA_SAD_SAMPLING_RATE_32KHZ |
227*d83cc019SAndroid Build Coastguard Worker 			 CEA_SAD_SAMPLING_RATE_44KHZ |
228*d83cc019SAndroid Build Coastguard Worker 			 CEA_SAD_SAMPLING_RATE_48KHZ;
229*d83cc019SAndroid Build Coastguard Worker 	sample_sizes = CEA_SAD_SAMPLE_SIZE_16 |
230*d83cc019SAndroid Build Coastguard Worker 		       CEA_SAD_SAMPLE_SIZE_20 |
231*d83cc019SAndroid Build Coastguard Worker 		       CEA_SAD_SAMPLE_SIZE_24;
232*d83cc019SAndroid Build Coastguard Worker 	cea_sad_init_pcm(&sad, channels, sampling_rates, sample_sizes);
233*d83cc019SAndroid Build Coastguard Worker 
234*d83cc019SAndroid Build Coastguard Worker 	/* Initialize the Speaker Allocation Data */
235*d83cc019SAndroid Build Coastguard Worker 	speaker_alloc.speakers = CEA_SPEAKER_FRONT_LEFT_RIGHT_CENTER;
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 	return generate_audio_edid(raw_edid, true, &sad, &speaker_alloc);
238*d83cc019SAndroid Build Coastguard Worker }
239*d83cc019SAndroid Build Coastguard Worker 
igt_kms_get_dp_audio_edid(void)240*d83cc019SAndroid Build Coastguard Worker const struct edid *igt_kms_get_dp_audio_edid(void)
241*d83cc019SAndroid Build Coastguard Worker {
242*d83cc019SAndroid Build Coastguard Worker 	int channels;
243*d83cc019SAndroid Build Coastguard Worker 	uint8_t sampling_rates, sample_sizes;
244*d83cc019SAndroid Build Coastguard Worker 	static unsigned char raw_edid[AUDIO_EDID_SIZE] = {0};
245*d83cc019SAndroid Build Coastguard Worker 	struct cea_sad sad = {0};
246*d83cc019SAndroid Build Coastguard Worker 	struct cea_speaker_alloc speaker_alloc = {0};
247*d83cc019SAndroid Build Coastguard Worker 
248*d83cc019SAndroid Build Coastguard Worker 	/* Initialize the Short Audio Descriptor for PCM */
249*d83cc019SAndroid Build Coastguard Worker 	channels = 2;
250*d83cc019SAndroid Build Coastguard Worker 	sampling_rates = CEA_SAD_SAMPLING_RATE_32KHZ |
251*d83cc019SAndroid Build Coastguard Worker 			 CEA_SAD_SAMPLING_RATE_44KHZ |
252*d83cc019SAndroid Build Coastguard Worker 			 CEA_SAD_SAMPLING_RATE_48KHZ;
253*d83cc019SAndroid Build Coastguard Worker 	sample_sizes = CEA_SAD_SAMPLE_SIZE_16 |
254*d83cc019SAndroid Build Coastguard Worker 		       CEA_SAD_SAMPLE_SIZE_20 |
255*d83cc019SAndroid Build Coastguard Worker 		       CEA_SAD_SAMPLE_SIZE_24;
256*d83cc019SAndroid Build Coastguard Worker 	cea_sad_init_pcm(&sad, channels, sampling_rates, sample_sizes);
257*d83cc019SAndroid Build Coastguard Worker 
258*d83cc019SAndroid Build Coastguard Worker 	/* Initialize the Speaker Allocation Data */
259*d83cc019SAndroid Build Coastguard Worker 	speaker_alloc.speakers = CEA_SPEAKER_FRONT_LEFT_RIGHT_CENTER;
260*d83cc019SAndroid Build Coastguard Worker 
261*d83cc019SAndroid Build Coastguard Worker 	return generate_audio_edid(raw_edid, false, &sad, &speaker_alloc);
262*d83cc019SAndroid Build Coastguard Worker }
263*d83cc019SAndroid Build Coastguard Worker 
264*d83cc019SAndroid Build Coastguard Worker static const uint8_t edid_4k_svds[] = {
265*d83cc019SAndroid Build Coastguard Worker 	32 | CEA_SVD_NATIVE, /* 1080p @ 24Hz (native) */
266*d83cc019SAndroid Build Coastguard Worker 	5,                   /* 1080i @ 60Hz */
267*d83cc019SAndroid Build Coastguard Worker 	20,                  /* 1080i @ 50Hz */
268*d83cc019SAndroid Build Coastguard Worker 	4,                   /* 720p @ 60Hz */
269*d83cc019SAndroid Build Coastguard Worker 	19,                  /* 720p @ 50Hz */
270*d83cc019SAndroid Build Coastguard Worker };
271*d83cc019SAndroid Build Coastguard Worker 
igt_kms_get_4k_edid(void)272*d83cc019SAndroid Build Coastguard Worker const struct edid *igt_kms_get_4k_edid(void)
273*d83cc019SAndroid Build Coastguard Worker {
274*d83cc019SAndroid Build Coastguard Worker 	static unsigned char raw_edid[256] = {0};
275*d83cc019SAndroid Build Coastguard Worker 	struct edid *edid;
276*d83cc019SAndroid Build Coastguard Worker 	struct edid_ext *edid_ext;
277*d83cc019SAndroid Build Coastguard Worker 	struct edid_cea *edid_cea;
278*d83cc019SAndroid Build Coastguard Worker 	char *cea_data;
279*d83cc019SAndroid Build Coastguard Worker 	struct edid_cea_data_block *block;
280*d83cc019SAndroid Build Coastguard Worker 	/* We'll add 6 extension fields to the HDMI VSDB. */
281*d83cc019SAndroid Build Coastguard Worker 	char raw_hdmi[HDMI_VSDB_MIN_SIZE + 6] = {0};
282*d83cc019SAndroid Build Coastguard Worker 	struct hdmi_vsdb *hdmi;
283*d83cc019SAndroid Build Coastguard Worker 	size_t cea_data_size = 0;
284*d83cc019SAndroid Build Coastguard Worker 
285*d83cc019SAndroid Build Coastguard Worker 	/* Create a new EDID from the base IGT EDID, and add an
286*d83cc019SAndroid Build Coastguard Worker 	 * extension that advertises 4K support. */
287*d83cc019SAndroid Build Coastguard Worker 	edid = (struct edid *) raw_edid;
288*d83cc019SAndroid Build Coastguard Worker 	memcpy(edid, igt_kms_get_base_edid(), sizeof(struct edid));
289*d83cc019SAndroid Build Coastguard Worker 	edid->extensions_len = 1;
290*d83cc019SAndroid Build Coastguard Worker 	edid_ext = &edid->extensions[0];
291*d83cc019SAndroid Build Coastguard Worker 	edid_cea = &edid_ext->data.cea;
292*d83cc019SAndroid Build Coastguard Worker 	cea_data = edid_cea->data;
293*d83cc019SAndroid Build Coastguard Worker 
294*d83cc019SAndroid Build Coastguard Worker 	/* Short Video Descriptor */
295*d83cc019SAndroid Build Coastguard Worker 	block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
296*d83cc019SAndroid Build Coastguard Worker 	cea_data_size += edid_cea_data_block_set_svd(block, edid_4k_svds,
297*d83cc019SAndroid Build Coastguard Worker 						     sizeof(edid_4k_svds));
298*d83cc019SAndroid Build Coastguard Worker 
299*d83cc019SAndroid Build Coastguard Worker 	/* Vendor-Specific Data Block */
300*d83cc019SAndroid Build Coastguard Worker 	hdmi = (struct hdmi_vsdb *) raw_hdmi;
301*d83cc019SAndroid Build Coastguard Worker 	hdmi->src_phy_addr[0] = 0x10;
302*d83cc019SAndroid Build Coastguard Worker 	hdmi->src_phy_addr[1] = 0x00;
303*d83cc019SAndroid Build Coastguard Worker 	/* 6 extension fields */
304*d83cc019SAndroid Build Coastguard Worker 	hdmi->flags1 = 0;
305*d83cc019SAndroid Build Coastguard Worker 	hdmi->max_tdms_clock = 0;
306*d83cc019SAndroid Build Coastguard Worker 	hdmi->flags2 = HDMI_VSDB_VIDEO_PRESENT;
307*d83cc019SAndroid Build Coastguard Worker 	hdmi->data[0] = 0x00; /* HDMI video flags */
308*d83cc019SAndroid Build Coastguard Worker 	hdmi->data[1] = 1 << 5; /* 1 VIC entry, 0 3D entries */
309*d83cc019SAndroid Build Coastguard Worker 	hdmi->data[2] = 0x01; /* 2160p, specified as short descriptor */
310*d83cc019SAndroid Build Coastguard Worker 
311*d83cc019SAndroid Build Coastguard Worker 	block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
312*d83cc019SAndroid Build Coastguard Worker 	cea_data_size += edid_cea_data_block_set_hdmi_vsdb(block, hdmi,
313*d83cc019SAndroid Build Coastguard Worker 							   sizeof(raw_hdmi));
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker 	assert(cea_data_size <= sizeof(edid_cea->data));
316*d83cc019SAndroid Build Coastguard Worker 
317*d83cc019SAndroid Build Coastguard Worker 	edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
318*d83cc019SAndroid Build Coastguard Worker 
319*d83cc019SAndroid Build Coastguard Worker 	edid_update_checksum(edid);
320*d83cc019SAndroid Build Coastguard Worker 
321*d83cc019SAndroid Build Coastguard Worker 	return edid;
322*d83cc019SAndroid Build Coastguard Worker }
323*d83cc019SAndroid Build Coastguard Worker 
igt_kms_get_3d_edid(void)324*d83cc019SAndroid Build Coastguard Worker const struct edid *igt_kms_get_3d_edid(void)
325*d83cc019SAndroid Build Coastguard Worker {
326*d83cc019SAndroid Build Coastguard Worker 	static unsigned char raw_edid[256] = {0};
327*d83cc019SAndroid Build Coastguard Worker 	struct edid *edid;
328*d83cc019SAndroid Build Coastguard Worker 	struct edid_ext *edid_ext;
329*d83cc019SAndroid Build Coastguard Worker 	struct edid_cea *edid_cea;
330*d83cc019SAndroid Build Coastguard Worker 	char *cea_data;
331*d83cc019SAndroid Build Coastguard Worker 	struct edid_cea_data_block *block;
332*d83cc019SAndroid Build Coastguard Worker 	/* We'll add 5 extension fields to the HDMI VSDB. */
333*d83cc019SAndroid Build Coastguard Worker 	char raw_hdmi[HDMI_VSDB_MIN_SIZE + 5] = {0};
334*d83cc019SAndroid Build Coastguard Worker 	struct hdmi_vsdb *hdmi;
335*d83cc019SAndroid Build Coastguard Worker 	size_t cea_data_size = 0;
336*d83cc019SAndroid Build Coastguard Worker 
337*d83cc019SAndroid Build Coastguard Worker 	/* Create a new EDID from the base IGT EDID, and add an
338*d83cc019SAndroid Build Coastguard Worker 	 * extension that advertises 3D support. */
339*d83cc019SAndroid Build Coastguard Worker 	edid = (struct edid *) raw_edid;
340*d83cc019SAndroid Build Coastguard Worker 	memcpy(edid, igt_kms_get_base_edid(), sizeof(struct edid));
341*d83cc019SAndroid Build Coastguard Worker 	edid->extensions_len = 1;
342*d83cc019SAndroid Build Coastguard Worker 	edid_ext = &edid->extensions[0];
343*d83cc019SAndroid Build Coastguard Worker 	edid_cea = &edid_ext->data.cea;
344*d83cc019SAndroid Build Coastguard Worker 	cea_data = edid_cea->data;
345*d83cc019SAndroid Build Coastguard Worker 
346*d83cc019SAndroid Build Coastguard Worker 	/* Short Video Descriptor */
347*d83cc019SAndroid Build Coastguard Worker 	block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
348*d83cc019SAndroid Build Coastguard Worker 	cea_data_size += edid_cea_data_block_set_svd(block, edid_4k_svds,
349*d83cc019SAndroid Build Coastguard Worker 						     sizeof(edid_4k_svds));
350*d83cc019SAndroid Build Coastguard Worker 
351*d83cc019SAndroid Build Coastguard Worker 	/* Vendor-Specific Data Block */
352*d83cc019SAndroid Build Coastguard Worker 	hdmi = (struct hdmi_vsdb *) raw_hdmi;
353*d83cc019SAndroid Build Coastguard Worker 	hdmi->src_phy_addr[0] = 0x10;
354*d83cc019SAndroid Build Coastguard Worker 	hdmi->src_phy_addr[1] = 0x00;
355*d83cc019SAndroid Build Coastguard Worker 	/* 5 extension fields */
356*d83cc019SAndroid Build Coastguard Worker 	hdmi->flags1 = 0;
357*d83cc019SAndroid Build Coastguard Worker 	hdmi->max_tdms_clock = 0;
358*d83cc019SAndroid Build Coastguard Worker 	hdmi->flags2 = HDMI_VSDB_VIDEO_PRESENT;
359*d83cc019SAndroid Build Coastguard Worker 	hdmi->data[0] = HDMI_VSDB_VIDEO_3D_PRESENT; /* HDMI video flags */
360*d83cc019SAndroid Build Coastguard Worker 	hdmi->data[1] = 0; /* 0 VIC entries, 0 3D entries */
361*d83cc019SAndroid Build Coastguard Worker 
362*d83cc019SAndroid Build Coastguard Worker 	block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
363*d83cc019SAndroid Build Coastguard Worker 	cea_data_size += edid_cea_data_block_set_hdmi_vsdb(block, hdmi,
364*d83cc019SAndroid Build Coastguard Worker 							   sizeof(raw_hdmi));
365*d83cc019SAndroid Build Coastguard Worker 
366*d83cc019SAndroid Build Coastguard Worker 	assert(cea_data_size <= sizeof(edid_cea->data));
367*d83cc019SAndroid Build Coastguard Worker 
368*d83cc019SAndroid Build Coastguard Worker 	edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
369*d83cc019SAndroid Build Coastguard Worker 
370*d83cc019SAndroid Build Coastguard Worker 	edid_update_checksum(edid);
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker 	return edid;
373*d83cc019SAndroid Build Coastguard Worker }
374*d83cc019SAndroid Build Coastguard Worker 
375*d83cc019SAndroid Build Coastguard Worker const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
376*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_SRC_X] = "SRC_X",
377*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_SRC_Y] = "SRC_Y",
378*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_SRC_W] = "SRC_W",
379*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_SRC_H] = "SRC_H",
380*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_CRTC_X] = "CRTC_X",
381*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_CRTC_Y] = "CRTC_Y",
382*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_CRTC_W] = "CRTC_W",
383*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_CRTC_H] = "CRTC_H",
384*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_FB_ID] = "FB_ID",
385*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_CRTC_ID] = "CRTC_ID",
386*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_IN_FENCE_FD] = "IN_FENCE_FD",
387*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_TYPE] = "type",
388*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_ROTATION] = "rotation",
389*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_IN_FORMATS] = "IN_FORMATS",
390*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_COLOR_ENCODING] = "COLOR_ENCODING",
391*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_COLOR_RANGE] = "COLOR_RANGE",
392*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_PIXEL_BLEND_MODE] = "pixel blend mode",
393*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_ALPHA] = "alpha",
394*d83cc019SAndroid Build Coastguard Worker 	[IGT_PLANE_ZPOS] = "zpos",
395*d83cc019SAndroid Build Coastguard Worker };
396*d83cc019SAndroid Build Coastguard Worker 
397*d83cc019SAndroid Build Coastguard Worker const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
398*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_BACKGROUND] = "background_color",
399*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_CTM] = "CTM",
400*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
401*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
402*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_DEGAMMA_LUT] = "DEGAMMA_LUT",
403*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_DEGAMMA_LUT_SIZE] = "DEGAMMA_LUT_SIZE",
404*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_MODE_ID] = "MODE_ID",
405*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_ACTIVE] = "ACTIVE",
406*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_OUT_FENCE_PTR] = "OUT_FENCE_PTR",
407*d83cc019SAndroid Build Coastguard Worker 	[IGT_CRTC_VRR_ENABLED] = "VRR_ENABLED",
408*d83cc019SAndroid Build Coastguard Worker };
409*d83cc019SAndroid Build Coastguard Worker 
410*d83cc019SAndroid Build Coastguard Worker const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
411*d83cc019SAndroid Build Coastguard Worker 	[IGT_CONNECTOR_SCALING_MODE] = "scaling mode",
412*d83cc019SAndroid Build Coastguard Worker 	[IGT_CONNECTOR_CRTC_ID] = "CRTC_ID",
413*d83cc019SAndroid Build Coastguard Worker 	[IGT_CONNECTOR_DPMS] = "DPMS",
414*d83cc019SAndroid Build Coastguard Worker 	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
415*d83cc019SAndroid Build Coastguard Worker 	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
416*d83cc019SAndroid Build Coastguard Worker 	[IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
417*d83cc019SAndroid Build Coastguard Worker 	[IGT_CONNECTOR_HDCP_CONTENT_TYPE] = "HDCP Content Type",
418*d83cc019SAndroid Build Coastguard Worker 	[IGT_CONNECTOR_LINK_STATUS] = "link-status",
419*d83cc019SAndroid Build Coastguard Worker };
420*d83cc019SAndroid Build Coastguard Worker 
421*d83cc019SAndroid Build Coastguard Worker /*
422*d83cc019SAndroid Build Coastguard Worker  * Retrieve all the properies specified in props_name and store them into
423*d83cc019SAndroid Build Coastguard Worker  * plane->props.
424*d83cc019SAndroid Build Coastguard Worker  */
425*d83cc019SAndroid Build Coastguard Worker static void
igt_fill_plane_props(igt_display_t * display,igt_plane_t * plane,int num_props,const char * const prop_names[])426*d83cc019SAndroid Build Coastguard Worker igt_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
427*d83cc019SAndroid Build Coastguard Worker 		     int num_props, const char * const prop_names[])
428*d83cc019SAndroid Build Coastguard Worker {
429*d83cc019SAndroid Build Coastguard Worker 	drmModeObjectPropertiesPtr props;
430*d83cc019SAndroid Build Coastguard Worker 	int i, j, fd;
431*d83cc019SAndroid Build Coastguard Worker 
432*d83cc019SAndroid Build Coastguard Worker 	fd = display->drm_fd;
433*d83cc019SAndroid Build Coastguard Worker 
434*d83cc019SAndroid Build Coastguard Worker 	props = drmModeObjectGetProperties(fd, plane->drm_plane->plane_id, DRM_MODE_OBJECT_PLANE);
435*d83cc019SAndroid Build Coastguard Worker 	igt_assert(props);
436*d83cc019SAndroid Build Coastguard Worker 
437*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < props->count_props; i++) {
438*d83cc019SAndroid Build Coastguard Worker 		drmModePropertyPtr prop =
439*d83cc019SAndroid Build Coastguard Worker 			drmModeGetProperty(fd, props->props[i]);
440*d83cc019SAndroid Build Coastguard Worker 
441*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < num_props; j++) {
442*d83cc019SAndroid Build Coastguard Worker 			if (strcmp(prop->name, prop_names[j]) != 0)
443*d83cc019SAndroid Build Coastguard Worker 				continue;
444*d83cc019SAndroid Build Coastguard Worker 
445*d83cc019SAndroid Build Coastguard Worker 			plane->props[j] = props->props[i];
446*d83cc019SAndroid Build Coastguard Worker 			break;
447*d83cc019SAndroid Build Coastguard Worker 		}
448*d83cc019SAndroid Build Coastguard Worker 
449*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeProperty(prop);
450*d83cc019SAndroid Build Coastguard Worker 	}
451*d83cc019SAndroid Build Coastguard Worker 
452*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeObjectProperties(props);
453*d83cc019SAndroid Build Coastguard Worker }
454*d83cc019SAndroid Build Coastguard Worker 
455*d83cc019SAndroid Build Coastguard Worker /*
456*d83cc019SAndroid Build Coastguard Worker  * Retrieve all the properies specified in props_name and store them into
457*d83cc019SAndroid Build Coastguard Worker  * config->atomic_props_crtc and config->atomic_props_connector.
458*d83cc019SAndroid Build Coastguard Worker  */
459*d83cc019SAndroid Build Coastguard Worker static void
igt_atomic_fill_connector_props(igt_display_t * display,igt_output_t * output,int num_connector_props,const char * const conn_prop_names[])460*d83cc019SAndroid Build Coastguard Worker igt_atomic_fill_connector_props(igt_display_t *display, igt_output_t *output,
461*d83cc019SAndroid Build Coastguard Worker 			int num_connector_props, const char * const conn_prop_names[])
462*d83cc019SAndroid Build Coastguard Worker {
463*d83cc019SAndroid Build Coastguard Worker 	drmModeObjectPropertiesPtr props;
464*d83cc019SAndroid Build Coastguard Worker 	int i, j, fd;
465*d83cc019SAndroid Build Coastguard Worker 
466*d83cc019SAndroid Build Coastguard Worker 	fd = display->drm_fd;
467*d83cc019SAndroid Build Coastguard Worker 
468*d83cc019SAndroid Build Coastguard Worker 	props = drmModeObjectGetProperties(fd, output->config.connector->connector_id, DRM_MODE_OBJECT_CONNECTOR);
469*d83cc019SAndroid Build Coastguard Worker 	igt_assert(props);
470*d83cc019SAndroid Build Coastguard Worker 
471*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < props->count_props; i++) {
472*d83cc019SAndroid Build Coastguard Worker 		drmModePropertyPtr prop =
473*d83cc019SAndroid Build Coastguard Worker 			drmModeGetProperty(fd, props->props[i]);
474*d83cc019SAndroid Build Coastguard Worker 
475*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < num_connector_props; j++) {
476*d83cc019SAndroid Build Coastguard Worker 			if (strcmp(prop->name, conn_prop_names[j]) != 0)
477*d83cc019SAndroid Build Coastguard Worker 				continue;
478*d83cc019SAndroid Build Coastguard Worker 
479*d83cc019SAndroid Build Coastguard Worker 			output->props[j] = props->props[i];
480*d83cc019SAndroid Build Coastguard Worker 			break;
481*d83cc019SAndroid Build Coastguard Worker 		}
482*d83cc019SAndroid Build Coastguard Worker 
483*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeProperty(prop);
484*d83cc019SAndroid Build Coastguard Worker 	}
485*d83cc019SAndroid Build Coastguard Worker 
486*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeObjectProperties(props);
487*d83cc019SAndroid Build Coastguard Worker }
488*d83cc019SAndroid Build Coastguard Worker 
489*d83cc019SAndroid Build Coastguard Worker static void
igt_fill_pipe_props(igt_display_t * display,igt_pipe_t * pipe,int num_crtc_props,const char * const crtc_prop_names[])490*d83cc019SAndroid Build Coastguard Worker igt_fill_pipe_props(igt_display_t *display, igt_pipe_t *pipe,
491*d83cc019SAndroid Build Coastguard Worker 		    int num_crtc_props, const char * const crtc_prop_names[])
492*d83cc019SAndroid Build Coastguard Worker {
493*d83cc019SAndroid Build Coastguard Worker 	drmModeObjectPropertiesPtr props;
494*d83cc019SAndroid Build Coastguard Worker 	int i, j, fd;
495*d83cc019SAndroid Build Coastguard Worker 
496*d83cc019SAndroid Build Coastguard Worker 	fd = display->drm_fd;
497*d83cc019SAndroid Build Coastguard Worker 
498*d83cc019SAndroid Build Coastguard Worker 	props = drmModeObjectGetProperties(fd, pipe->crtc_id, DRM_MODE_OBJECT_CRTC);
499*d83cc019SAndroid Build Coastguard Worker 	igt_assert(props);
500*d83cc019SAndroid Build Coastguard Worker 
501*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < props->count_props; i++) {
502*d83cc019SAndroid Build Coastguard Worker 		drmModePropertyPtr prop =
503*d83cc019SAndroid Build Coastguard Worker 			drmModeGetProperty(fd, props->props[i]);
504*d83cc019SAndroid Build Coastguard Worker 
505*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < num_crtc_props; j++) {
506*d83cc019SAndroid Build Coastguard Worker 			if (strcmp(prop->name, crtc_prop_names[j]) != 0)
507*d83cc019SAndroid Build Coastguard Worker 				continue;
508*d83cc019SAndroid Build Coastguard Worker 
509*d83cc019SAndroid Build Coastguard Worker 			pipe->props[j] = props->props[i];
510*d83cc019SAndroid Build Coastguard Worker 			break;
511*d83cc019SAndroid Build Coastguard Worker 		}
512*d83cc019SAndroid Build Coastguard Worker 
513*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeProperty(prop);
514*d83cc019SAndroid Build Coastguard Worker 	}
515*d83cc019SAndroid Build Coastguard Worker 
516*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeObjectProperties(props);
517*d83cc019SAndroid Build Coastguard Worker }
518*d83cc019SAndroid Build Coastguard Worker 
519*d83cc019SAndroid Build Coastguard Worker /**
520*d83cc019SAndroid Build Coastguard Worker  * kmstest_pipe_name:
521*d83cc019SAndroid Build Coastguard Worker  * @pipe: display pipe
522*d83cc019SAndroid Build Coastguard Worker  *
523*d83cc019SAndroid Build Coastguard Worker  * Returns: String representing @pipe, e.g. "A".
524*d83cc019SAndroid Build Coastguard Worker  */
kmstest_pipe_name(enum pipe pipe)525*d83cc019SAndroid Build Coastguard Worker const char *kmstest_pipe_name(enum pipe pipe)
526*d83cc019SAndroid Build Coastguard Worker {
527*d83cc019SAndroid Build Coastguard Worker 	static const char str[] = "A\0B\0C\0D\0E\0F";
528*d83cc019SAndroid Build Coastguard Worker 
529*d83cc019SAndroid Build Coastguard Worker 	_Static_assert(sizeof(str) == IGT_MAX_PIPES * 2,
530*d83cc019SAndroid Build Coastguard Worker 		       "Missing pipe name");
531*d83cc019SAndroid Build Coastguard Worker 
532*d83cc019SAndroid Build Coastguard Worker 	if (pipe == PIPE_NONE)
533*d83cc019SAndroid Build Coastguard Worker 		return "None";
534*d83cc019SAndroid Build Coastguard Worker 
535*d83cc019SAndroid Build Coastguard Worker 	if (pipe >= IGT_MAX_PIPES)
536*d83cc019SAndroid Build Coastguard Worker 		return "invalid";
537*d83cc019SAndroid Build Coastguard Worker 
538*d83cc019SAndroid Build Coastguard Worker 	return str + (pipe * 2);
539*d83cc019SAndroid Build Coastguard Worker }
540*d83cc019SAndroid Build Coastguard Worker 
541*d83cc019SAndroid Build Coastguard Worker /**
542*d83cc019SAndroid Build Coastguard Worker  * kmstest_pipe_to_index:
543*d83cc019SAndroid Build Coastguard Worker  *@pipe: display pipe in string format
544*d83cc019SAndroid Build Coastguard Worker  *
545*d83cc019SAndroid Build Coastguard Worker  * Returns: index to corresponding pipe
546*d83cc019SAndroid Build Coastguard Worker  */
kmstest_pipe_to_index(char pipe)547*d83cc019SAndroid Build Coastguard Worker int kmstest_pipe_to_index(char pipe)
548*d83cc019SAndroid Build Coastguard Worker {
549*d83cc019SAndroid Build Coastguard Worker 	int r = pipe - 'A';
550*d83cc019SAndroid Build Coastguard Worker 
551*d83cc019SAndroid Build Coastguard Worker 	if (r < 0 || r >= IGT_MAX_PIPES)
552*d83cc019SAndroid Build Coastguard Worker 		return -EINVAL;
553*d83cc019SAndroid Build Coastguard Worker 
554*d83cc019SAndroid Build Coastguard Worker 	return r;
555*d83cc019SAndroid Build Coastguard Worker }
556*d83cc019SAndroid Build Coastguard Worker 
557*d83cc019SAndroid Build Coastguard Worker /**
558*d83cc019SAndroid Build Coastguard Worker  * kmstest_plane_type_name:
559*d83cc019SAndroid Build Coastguard Worker  * @plane_type: display plane type
560*d83cc019SAndroid Build Coastguard Worker  *
561*d83cc019SAndroid Build Coastguard Worker  * Returns: String representing @plane_type, e.g. "overlay".
562*d83cc019SAndroid Build Coastguard Worker  */
kmstest_plane_type_name(int plane_type)563*d83cc019SAndroid Build Coastguard Worker const char *kmstest_plane_type_name(int plane_type)
564*d83cc019SAndroid Build Coastguard Worker {
565*d83cc019SAndroid Build Coastguard Worker 	static const char * const names[] = {
566*d83cc019SAndroid Build Coastguard Worker 		[DRM_PLANE_TYPE_OVERLAY] = "overlay",
567*d83cc019SAndroid Build Coastguard Worker 		[DRM_PLANE_TYPE_PRIMARY] = "primary",
568*d83cc019SAndroid Build Coastguard Worker 		[DRM_PLANE_TYPE_CURSOR] = "cursor",
569*d83cc019SAndroid Build Coastguard Worker 	};
570*d83cc019SAndroid Build Coastguard Worker 
571*d83cc019SAndroid Build Coastguard Worker 	igt_assert(plane_type < ARRAY_SIZE(names) && names[plane_type]);
572*d83cc019SAndroid Build Coastguard Worker 
573*d83cc019SAndroid Build Coastguard Worker 	return names[plane_type];
574*d83cc019SAndroid Build Coastguard Worker }
575*d83cc019SAndroid Build Coastguard Worker 
576*d83cc019SAndroid Build Coastguard Worker struct type_name {
577*d83cc019SAndroid Build Coastguard Worker 	int type;
578*d83cc019SAndroid Build Coastguard Worker 	const char *name;
579*d83cc019SAndroid Build Coastguard Worker };
580*d83cc019SAndroid Build Coastguard Worker 
find_type_name(const struct type_name * names,int type)581*d83cc019SAndroid Build Coastguard Worker static const char *find_type_name(const struct type_name *names, int type)
582*d83cc019SAndroid Build Coastguard Worker {
583*d83cc019SAndroid Build Coastguard Worker 	for (; names->name; names++) {
584*d83cc019SAndroid Build Coastguard Worker 		if (names->type == type)
585*d83cc019SAndroid Build Coastguard Worker 			return names->name;
586*d83cc019SAndroid Build Coastguard Worker 	}
587*d83cc019SAndroid Build Coastguard Worker 
588*d83cc019SAndroid Build Coastguard Worker 	return "(invalid)";
589*d83cc019SAndroid Build Coastguard Worker }
590*d83cc019SAndroid Build Coastguard Worker 
591*d83cc019SAndroid Build Coastguard Worker static const struct type_name encoder_type_names[] = {
592*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_ENCODER_NONE, "none" },
593*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_ENCODER_DAC, "DAC" },
594*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
595*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
596*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_ENCODER_TVDAC, "TVDAC" },
597*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
598*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_ENCODER_DSI, "DSI" },
599*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_ENCODER_DPMST, "DP MST" },
600*d83cc019SAndroid Build Coastguard Worker 	{}
601*d83cc019SAndroid Build Coastguard Worker };
602*d83cc019SAndroid Build Coastguard Worker 
603*d83cc019SAndroid Build Coastguard Worker /**
604*d83cc019SAndroid Build Coastguard Worker  * kmstest_encoder_type_str:
605*d83cc019SAndroid Build Coastguard Worker  * @type: DRM_MODE_ENCODER_* enumeration value
606*d83cc019SAndroid Build Coastguard Worker  *
607*d83cc019SAndroid Build Coastguard Worker  * Returns: A string representing the drm encoder @type.
608*d83cc019SAndroid Build Coastguard Worker  */
kmstest_encoder_type_str(int type)609*d83cc019SAndroid Build Coastguard Worker const char *kmstest_encoder_type_str(int type)
610*d83cc019SAndroid Build Coastguard Worker {
611*d83cc019SAndroid Build Coastguard Worker 	return find_type_name(encoder_type_names, type);
612*d83cc019SAndroid Build Coastguard Worker }
613*d83cc019SAndroid Build Coastguard Worker 
614*d83cc019SAndroid Build Coastguard Worker static const struct type_name connector_status_names[] = {
615*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTED, "connected" },
616*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_DISCONNECTED, "disconnected" },
617*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_UNKNOWNCONNECTION, "unknown" },
618*d83cc019SAndroid Build Coastguard Worker 	{}
619*d83cc019SAndroid Build Coastguard Worker };
620*d83cc019SAndroid Build Coastguard Worker 
621*d83cc019SAndroid Build Coastguard Worker /**
622*d83cc019SAndroid Build Coastguard Worker  * kmstest_connector_status_str:
623*d83cc019SAndroid Build Coastguard Worker  * @status: DRM_MODE_* connector status value
624*d83cc019SAndroid Build Coastguard Worker  *
625*d83cc019SAndroid Build Coastguard Worker  * Returns: A string representing the drm connector status @status.
626*d83cc019SAndroid Build Coastguard Worker  */
kmstest_connector_status_str(int status)627*d83cc019SAndroid Build Coastguard Worker const char *kmstest_connector_status_str(int status)
628*d83cc019SAndroid Build Coastguard Worker {
629*d83cc019SAndroid Build Coastguard Worker 	return find_type_name(connector_status_names, status);
630*d83cc019SAndroid Build Coastguard Worker }
631*d83cc019SAndroid Build Coastguard Worker 
632*d83cc019SAndroid Build Coastguard Worker static const struct type_name connector_type_names[] = {
633*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_Unknown, "Unknown" },
634*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_VGA, "VGA" },
635*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
636*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
637*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
638*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_Composite, "Composite" },
639*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },
640*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
641*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_Component, "Component" },
642*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_9PinDIN, "DIN" },
643*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_DisplayPort, "DP" },
644*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
645*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
646*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_TV, "TV" },
647*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_eDP, "eDP" },
648*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
649*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
650*d83cc019SAndroid Build Coastguard Worker 	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
651*d83cc019SAndroid Build Coastguard Worker 	{}
652*d83cc019SAndroid Build Coastguard Worker };
653*d83cc019SAndroid Build Coastguard Worker 
654*d83cc019SAndroid Build Coastguard Worker /**
655*d83cc019SAndroid Build Coastguard Worker  * kmstest_connector_type_str:
656*d83cc019SAndroid Build Coastguard Worker  * @type: DRM_MODE_CONNECTOR_* enumeration value
657*d83cc019SAndroid Build Coastguard Worker  *
658*d83cc019SAndroid Build Coastguard Worker  * Returns: A string representing the drm connector @type.
659*d83cc019SAndroid Build Coastguard Worker  */
kmstest_connector_type_str(int type)660*d83cc019SAndroid Build Coastguard Worker const char *kmstest_connector_type_str(int type)
661*d83cc019SAndroid Build Coastguard Worker {
662*d83cc019SAndroid Build Coastguard Worker 	return find_type_name(connector_type_names, type);
663*d83cc019SAndroid Build Coastguard Worker }
664*d83cc019SAndroid Build Coastguard Worker 
mode_stereo_name(const drmModeModeInfo * mode)665*d83cc019SAndroid Build Coastguard Worker static const char *mode_stereo_name(const drmModeModeInfo *mode)
666*d83cc019SAndroid Build Coastguard Worker {
667*d83cc019SAndroid Build Coastguard Worker 	switch (mode->flags & DRM_MODE_FLAG_3D_MASK) {
668*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_3D_FRAME_PACKING:
669*d83cc019SAndroid Build Coastguard Worker 		return "FP";
670*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:
671*d83cc019SAndroid Build Coastguard Worker 		return "FA";
672*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:
673*d83cc019SAndroid Build Coastguard Worker 		return "LA";
674*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
675*d83cc019SAndroid Build Coastguard Worker 		return "SBSF";
676*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_3D_L_DEPTH:
677*d83cc019SAndroid Build Coastguard Worker 		return "LD";
678*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:
679*d83cc019SAndroid Build Coastguard Worker 		return "LDGFX";
680*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
681*d83cc019SAndroid Build Coastguard Worker 		return "TB";
682*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
683*d83cc019SAndroid Build Coastguard Worker 		return "SBSH";
684*d83cc019SAndroid Build Coastguard Worker 	default:
685*d83cc019SAndroid Build Coastguard Worker 		return NULL;
686*d83cc019SAndroid Build Coastguard Worker 	}
687*d83cc019SAndroid Build Coastguard Worker }
688*d83cc019SAndroid Build Coastguard Worker 
mode_picture_aspect_name(const drmModeModeInfo * mode)689*d83cc019SAndroid Build Coastguard Worker static const char *mode_picture_aspect_name(const drmModeModeInfo *mode)
690*d83cc019SAndroid Build Coastguard Worker {
691*d83cc019SAndroid Build Coastguard Worker 	switch (mode->flags & DRM_MODE_FLAG_PIC_AR_MASK) {
692*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_PIC_AR_NONE:
693*d83cc019SAndroid Build Coastguard Worker 		return NULL;
694*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_PIC_AR_4_3:
695*d83cc019SAndroid Build Coastguard Worker 		return "4:3";
696*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_PIC_AR_16_9:
697*d83cc019SAndroid Build Coastguard Worker 		return "16:9";
698*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_PIC_AR_64_27:
699*d83cc019SAndroid Build Coastguard Worker 		return "64:27";
700*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_FLAG_PIC_AR_256_135:
701*d83cc019SAndroid Build Coastguard Worker 		return "256:135";
702*d83cc019SAndroid Build Coastguard Worker 	default:
703*d83cc019SAndroid Build Coastguard Worker 		return "invalid";
704*d83cc019SAndroid Build Coastguard Worker 	}
705*d83cc019SAndroid Build Coastguard Worker }
706*d83cc019SAndroid Build Coastguard Worker 
707*d83cc019SAndroid Build Coastguard Worker /**
708*d83cc019SAndroid Build Coastguard Worker  * kmstest_dump_mode:
709*d83cc019SAndroid Build Coastguard Worker  * @mode: libdrm mode structure
710*d83cc019SAndroid Build Coastguard Worker  *
711*d83cc019SAndroid Build Coastguard Worker  * Prints @mode to stdout in a human-readable form.
712*d83cc019SAndroid Build Coastguard Worker  */
kmstest_dump_mode(drmModeModeInfo * mode)713*d83cc019SAndroid Build Coastguard Worker void kmstest_dump_mode(drmModeModeInfo *mode)
714*d83cc019SAndroid Build Coastguard Worker {
715*d83cc019SAndroid Build Coastguard Worker 	const char *stereo = mode_stereo_name(mode);
716*d83cc019SAndroid Build Coastguard Worker 	const char *aspect = mode_picture_aspect_name(mode);
717*d83cc019SAndroid Build Coastguard Worker 
718*d83cc019SAndroid Build Coastguard Worker 	igt_info("  %s %d %d %d %d %d %d %d %d %d 0x%x 0x%x %d%s%s%s%s%s%s\n",
719*d83cc019SAndroid Build Coastguard Worker 		 mode->name, mode->vrefresh,
720*d83cc019SAndroid Build Coastguard Worker 		 mode->hdisplay, mode->hsync_start,
721*d83cc019SAndroid Build Coastguard Worker 		 mode->hsync_end, mode->htotal,
722*d83cc019SAndroid Build Coastguard Worker 		 mode->vdisplay, mode->vsync_start,
723*d83cc019SAndroid Build Coastguard Worker 		 mode->vsync_end, mode->vtotal,
724*d83cc019SAndroid Build Coastguard Worker 		 mode->flags, mode->type, mode->clock,
725*d83cc019SAndroid Build Coastguard Worker 		 stereo ? " (3D:" : "",
726*d83cc019SAndroid Build Coastguard Worker 		 stereo ? stereo : "", stereo ? ")" : "",
727*d83cc019SAndroid Build Coastguard Worker 		 aspect ? " (PAR:" : "",
728*d83cc019SAndroid Build Coastguard Worker 		 aspect ? aspect : "", aspect ? ")" : "");
729*d83cc019SAndroid Build Coastguard Worker }
730*d83cc019SAndroid Build Coastguard Worker 
731*d83cc019SAndroid Build Coastguard Worker /**
732*d83cc019SAndroid Build Coastguard Worker  * kmstest_get_pipe_from_crtc_id:
733*d83cc019SAndroid Build Coastguard Worker  * @fd: DRM fd
734*d83cc019SAndroid Build Coastguard Worker  * @crtc_id: DRM CRTC id
735*d83cc019SAndroid Build Coastguard Worker  *
736*d83cc019SAndroid Build Coastguard Worker  * Returns: The crtc index for the given DRM CRTC ID @crtc_id. The crtc index
737*d83cc019SAndroid Build Coastguard Worker  * is the equivalent of the pipe id.  This value maps directly to an enum pipe
738*d83cc019SAndroid Build Coastguard Worker  * value used in other helper functions.  Returns 0 if the index could not be
739*d83cc019SAndroid Build Coastguard Worker  * determined.
740*d83cc019SAndroid Build Coastguard Worker  */
741*d83cc019SAndroid Build Coastguard Worker 
kmstest_get_pipe_from_crtc_id(int fd,int crtc_id)742*d83cc019SAndroid Build Coastguard Worker int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id)
743*d83cc019SAndroid Build Coastguard Worker {
744*d83cc019SAndroid Build Coastguard Worker 	drmModeRes *res;
745*d83cc019SAndroid Build Coastguard Worker 	drmModeCrtc *crtc;
746*d83cc019SAndroid Build Coastguard Worker 	int i, cur_id;
747*d83cc019SAndroid Build Coastguard Worker 
748*d83cc019SAndroid Build Coastguard Worker 	res = drmModeGetResources(fd);
749*d83cc019SAndroid Build Coastguard Worker 	igt_assert(res);
750*d83cc019SAndroid Build Coastguard Worker 
751*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < res->count_crtcs; i++) {
752*d83cc019SAndroid Build Coastguard Worker 		crtc = drmModeGetCrtc(fd, res->crtcs[i]);
753*d83cc019SAndroid Build Coastguard Worker 		igt_assert(crtc);
754*d83cc019SAndroid Build Coastguard Worker 		cur_id = crtc->crtc_id;
755*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeCrtc(crtc);
756*d83cc019SAndroid Build Coastguard Worker 		if (cur_id == crtc_id)
757*d83cc019SAndroid Build Coastguard Worker 			break;
758*d83cc019SAndroid Build Coastguard Worker 	}
759*d83cc019SAndroid Build Coastguard Worker 
760*d83cc019SAndroid Build Coastguard Worker 	igt_assert(i < res->count_crtcs);
761*d83cc019SAndroid Build Coastguard Worker 
762*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeResources(res);
763*d83cc019SAndroid Build Coastguard Worker 
764*d83cc019SAndroid Build Coastguard Worker 	return i;
765*d83cc019SAndroid Build Coastguard Worker }
766*d83cc019SAndroid Build Coastguard Worker 
767*d83cc019SAndroid Build Coastguard Worker /**
768*d83cc019SAndroid Build Coastguard Worker  * kmstest_find_crtc_for_connector:
769*d83cc019SAndroid Build Coastguard Worker  * @fd: DRM fd
770*d83cc019SAndroid Build Coastguard Worker  * @res: libdrm resources pointer
771*d83cc019SAndroid Build Coastguard Worker  * @connector: libdrm connector pointer
772*d83cc019SAndroid Build Coastguard Worker  * @crtc_blacklist_idx_mask: a mask of CRTC indexes that we can't return
773*d83cc019SAndroid Build Coastguard Worker  *
774*d83cc019SAndroid Build Coastguard Worker  * Returns: the CRTC ID for a CRTC that fits the connector, otherwise it asserts
775*d83cc019SAndroid Build Coastguard Worker  * false and never returns. The blacklist mask can be used in case you have
776*d83cc019SAndroid Build Coastguard Worker  * CRTCs that are already in use by other connectors.
777*d83cc019SAndroid Build Coastguard Worker  */
kmstest_find_crtc_for_connector(int fd,drmModeRes * res,drmModeConnector * connector,uint32_t crtc_blacklist_idx_mask)778*d83cc019SAndroid Build Coastguard Worker uint32_t kmstest_find_crtc_for_connector(int fd, drmModeRes *res,
779*d83cc019SAndroid Build Coastguard Worker 					 drmModeConnector *connector,
780*d83cc019SAndroid Build Coastguard Worker 					 uint32_t crtc_blacklist_idx_mask)
781*d83cc019SAndroid Build Coastguard Worker {
782*d83cc019SAndroid Build Coastguard Worker 	drmModeEncoder *e;
783*d83cc019SAndroid Build Coastguard Worker 	uint32_t possible_crtcs;
784*d83cc019SAndroid Build Coastguard Worker 	int i, j;
785*d83cc019SAndroid Build Coastguard Worker 
786*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < connector->count_encoders; i++) {
787*d83cc019SAndroid Build Coastguard Worker 		e = drmModeGetEncoder(fd, connector->encoders[i]);
788*d83cc019SAndroid Build Coastguard Worker 		possible_crtcs = e->possible_crtcs & ~crtc_blacklist_idx_mask;
789*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeEncoder(e);
790*d83cc019SAndroid Build Coastguard Worker 
791*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; possible_crtcs >> j; j++)
792*d83cc019SAndroid Build Coastguard Worker 			if (possible_crtcs & (1 << j))
793*d83cc019SAndroid Build Coastguard Worker 				return res->crtcs[j];
794*d83cc019SAndroid Build Coastguard Worker 	}
795*d83cc019SAndroid Build Coastguard Worker 
796*d83cc019SAndroid Build Coastguard Worker 	igt_assert(false);
797*d83cc019SAndroid Build Coastguard Worker }
798*d83cc019SAndroid Build Coastguard Worker 
799*d83cc019SAndroid Build Coastguard Worker /**
800*d83cc019SAndroid Build Coastguard Worker  * kmstest_dumb_create:
801*d83cc019SAndroid Build Coastguard Worker  * @fd: open drm file descriptor
802*d83cc019SAndroid Build Coastguard Worker  * @width: width of the buffer in pixels
803*d83cc019SAndroid Build Coastguard Worker  * @height: height of the buffer in pixels
804*d83cc019SAndroid Build Coastguard Worker  * @bpp: bytes per pixel of the buffer
805*d83cc019SAndroid Build Coastguard Worker  * @stride: Pointer which receives the dumb bo's stride, can be NULL.
806*d83cc019SAndroid Build Coastguard Worker  * @size: Pointer which receives the dumb bo's size, can be NULL.
807*d83cc019SAndroid Build Coastguard Worker  *
808*d83cc019SAndroid Build Coastguard Worker  * This wraps the CREATE_DUMB ioctl, which allocates a new dumb buffer object
809*d83cc019SAndroid Build Coastguard Worker  * for the specified dimensions.
810*d83cc019SAndroid Build Coastguard Worker  *
811*d83cc019SAndroid Build Coastguard Worker  * Returns: The file-private handle of the created buffer object
812*d83cc019SAndroid Build Coastguard Worker  */
kmstest_dumb_create(int fd,int width,int height,int bpp,unsigned * stride,uint64_t * size)813*d83cc019SAndroid Build Coastguard Worker uint32_t kmstest_dumb_create(int fd, int width, int height, int bpp,
814*d83cc019SAndroid Build Coastguard Worker 			     unsigned *stride, uint64_t *size)
815*d83cc019SAndroid Build Coastguard Worker {
816*d83cc019SAndroid Build Coastguard Worker 	struct drm_mode_create_dumb create;
817*d83cc019SAndroid Build Coastguard Worker 
818*d83cc019SAndroid Build Coastguard Worker 	memset(&create, 0, sizeof(create));
819*d83cc019SAndroid Build Coastguard Worker 	create.width = width;
820*d83cc019SAndroid Build Coastguard Worker 	create.height = height;
821*d83cc019SAndroid Build Coastguard Worker 	create.bpp = bpp;
822*d83cc019SAndroid Build Coastguard Worker 
823*d83cc019SAndroid Build Coastguard Worker 	create.handle = 0;
824*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
825*d83cc019SAndroid Build Coastguard Worker 	igt_assert(create.handle);
826*d83cc019SAndroid Build Coastguard Worker 	igt_assert(create.size >= (uint64_t) width * height * bpp / 8);
827*d83cc019SAndroid Build Coastguard Worker 
828*d83cc019SAndroid Build Coastguard Worker 	if (stride)
829*d83cc019SAndroid Build Coastguard Worker 		*stride = create.pitch;
830*d83cc019SAndroid Build Coastguard Worker 
831*d83cc019SAndroid Build Coastguard Worker 	if (size)
832*d83cc019SAndroid Build Coastguard Worker 		*size = create.size;
833*d83cc019SAndroid Build Coastguard Worker 
834*d83cc019SAndroid Build Coastguard Worker 	return create.handle;
835*d83cc019SAndroid Build Coastguard Worker }
836*d83cc019SAndroid Build Coastguard Worker 
837*d83cc019SAndroid Build Coastguard Worker /**
838*d83cc019SAndroid Build Coastguard Worker  * kmstest_dumb_map_buffer:
839*d83cc019SAndroid Build Coastguard Worker  * @fd: Opened drm file descriptor
840*d83cc019SAndroid Build Coastguard Worker  * @handle: Offset in the file referred to by fd
841*d83cc019SAndroid Build Coastguard Worker  * @size: Length of the mapping, must be greater than 0
842*d83cc019SAndroid Build Coastguard Worker  * @prot: Describes the memory protection of the mapping
843*d83cc019SAndroid Build Coastguard Worker  * Returns: A pointer representing the start of the virtual mapping
844*d83cc019SAndroid Build Coastguard Worker  */
kmstest_dumb_map_buffer(int fd,uint32_t handle,uint64_t size,unsigned prot)845*d83cc019SAndroid Build Coastguard Worker void *kmstest_dumb_map_buffer(int fd, uint32_t handle, uint64_t size,
846*d83cc019SAndroid Build Coastguard Worker 			      unsigned prot)
847*d83cc019SAndroid Build Coastguard Worker {
848*d83cc019SAndroid Build Coastguard Worker 	struct drm_mode_map_dumb arg = {};
849*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
850*d83cc019SAndroid Build Coastguard Worker 
851*d83cc019SAndroid Build Coastguard Worker 	arg.handle = handle;
852*d83cc019SAndroid Build Coastguard Worker 
853*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
854*d83cc019SAndroid Build Coastguard Worker 
855*d83cc019SAndroid Build Coastguard Worker 	ptr = mmap(NULL, size, prot, MAP_SHARED, fd, arg.offset);
856*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ptr != MAP_FAILED);
857*d83cc019SAndroid Build Coastguard Worker 
858*d83cc019SAndroid Build Coastguard Worker 	return ptr;
859*d83cc019SAndroid Build Coastguard Worker }
860*d83cc019SAndroid Build Coastguard Worker 
__kmstest_dumb_destroy(int fd,uint32_t handle)861*d83cc019SAndroid Build Coastguard Worker static int __kmstest_dumb_destroy(int fd, uint32_t handle)
862*d83cc019SAndroid Build Coastguard Worker {
863*d83cc019SAndroid Build Coastguard Worker 	struct drm_mode_destroy_dumb arg = { handle };
864*d83cc019SAndroid Build Coastguard Worker 	int err = 0;
865*d83cc019SAndroid Build Coastguard Worker 
866*d83cc019SAndroid Build Coastguard Worker 	if (drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg))
867*d83cc019SAndroid Build Coastguard Worker 		err = -errno;
868*d83cc019SAndroid Build Coastguard Worker 
869*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
870*d83cc019SAndroid Build Coastguard Worker 	return err;
871*d83cc019SAndroid Build Coastguard Worker }
872*d83cc019SAndroid Build Coastguard Worker 
873*d83cc019SAndroid Build Coastguard Worker /**
874*d83cc019SAndroid Build Coastguard Worker  * kmstest_dumb_destroy:
875*d83cc019SAndroid Build Coastguard Worker  * @fd: Opened drm file descriptor
876*d83cc019SAndroid Build Coastguard Worker  * @handle: Offset in the file referred to by fd
877*d83cc019SAndroid Build Coastguard Worker  */
kmstest_dumb_destroy(int fd,uint32_t handle)878*d83cc019SAndroid Build Coastguard Worker void kmstest_dumb_destroy(int fd, uint32_t handle)
879*d83cc019SAndroid Build Coastguard Worker {
880*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__kmstest_dumb_destroy(fd, handle), 0);
881*d83cc019SAndroid Build Coastguard Worker }
882*d83cc019SAndroid Build Coastguard Worker 
883*d83cc019SAndroid Build Coastguard Worker #if !defined(ANDROID)
884*d83cc019SAndroid Build Coastguard Worker /*
885*d83cc019SAndroid Build Coastguard Worker  * Returns: the previous mode, or KD_GRAPHICS if no /dev/tty0 was
886*d83cc019SAndroid Build Coastguard Worker  * found and nothing was done.
887*d83cc019SAndroid Build Coastguard Worker  */
set_vt_mode(unsigned long mode)888*d83cc019SAndroid Build Coastguard Worker static signed long set_vt_mode(unsigned long mode)
889*d83cc019SAndroid Build Coastguard Worker {
890*d83cc019SAndroid Build Coastguard Worker 	int fd;
891*d83cc019SAndroid Build Coastguard Worker 	unsigned long prev_mode;
892*d83cc019SAndroid Build Coastguard Worker 	static const char TTY0[] = "/dev/tty0";
893*d83cc019SAndroid Build Coastguard Worker 
894*d83cc019SAndroid Build Coastguard Worker 	if (access(TTY0, F_OK)) {
895*d83cc019SAndroid Build Coastguard Worker 		/* errno message should be "No such file". Do not
896*d83cc019SAndroid Build Coastguard Worker 		   hardcode but ask strerror() in the very unlikely
897*d83cc019SAndroid Build Coastguard Worker 		   case something else happened. */
898*d83cc019SAndroid Build Coastguard Worker 		igt_debug("VT: %s: %s, cannot change its mode\n",
899*d83cc019SAndroid Build Coastguard Worker 			  TTY0, strerror(errno));
900*d83cc019SAndroid Build Coastguard Worker 		return KD_GRAPHICS;
901*d83cc019SAndroid Build Coastguard Worker 	}
902*d83cc019SAndroid Build Coastguard Worker 
903*d83cc019SAndroid Build Coastguard Worker 	fd = open(TTY0, O_RDONLY);
904*d83cc019SAndroid Build Coastguard Worker 	if (fd < 0)
905*d83cc019SAndroid Build Coastguard Worker 		return -errno;
906*d83cc019SAndroid Build Coastguard Worker 
907*d83cc019SAndroid Build Coastguard Worker 	prev_mode = 0;
908*d83cc019SAndroid Build Coastguard Worker 	if (drmIoctl(fd, KDGETMODE, &prev_mode))
909*d83cc019SAndroid Build Coastguard Worker 		goto err;
910*d83cc019SAndroid Build Coastguard Worker 	if (drmIoctl(fd, KDSETMODE, (void *)mode))
911*d83cc019SAndroid Build Coastguard Worker 		goto err;
912*d83cc019SAndroid Build Coastguard Worker 
913*d83cc019SAndroid Build Coastguard Worker 	close(fd);
914*d83cc019SAndroid Build Coastguard Worker 
915*d83cc019SAndroid Build Coastguard Worker 	return prev_mode;
916*d83cc019SAndroid Build Coastguard Worker err:
917*d83cc019SAndroid Build Coastguard Worker 	close(fd);
918*d83cc019SAndroid Build Coastguard Worker 
919*d83cc019SAndroid Build Coastguard Worker 	return -errno;
920*d83cc019SAndroid Build Coastguard Worker }
921*d83cc019SAndroid Build Coastguard Worker #endif
922*d83cc019SAndroid Build Coastguard Worker 
923*d83cc019SAndroid Build Coastguard Worker static unsigned long orig_vt_mode = -1UL;
924*d83cc019SAndroid Build Coastguard Worker 
925*d83cc019SAndroid Build Coastguard Worker /**
926*d83cc019SAndroid Build Coastguard Worker  * kmstest_restore_vt_mode:
927*d83cc019SAndroid Build Coastguard Worker  *
928*d83cc019SAndroid Build Coastguard Worker  * Restore the VT mode in use before #kmstest_set_vt_graphics_mode was called.
929*d83cc019SAndroid Build Coastguard Worker  */
kmstest_restore_vt_mode(void)930*d83cc019SAndroid Build Coastguard Worker void kmstest_restore_vt_mode(void)
931*d83cc019SAndroid Build Coastguard Worker {
932*d83cc019SAndroid Build Coastguard Worker #if !defined(ANDROID)
933*d83cc019SAndroid Build Coastguard Worker 	long ret;
934*d83cc019SAndroid Build Coastguard Worker 
935*d83cc019SAndroid Build Coastguard Worker 	if (orig_vt_mode != -1UL) {
936*d83cc019SAndroid Build Coastguard Worker 		ret = set_vt_mode(orig_vt_mode);
937*d83cc019SAndroid Build Coastguard Worker 
938*d83cc019SAndroid Build Coastguard Worker 		igt_assert(ret >= 0);
939*d83cc019SAndroid Build Coastguard Worker 		igt_debug("VT: original mode 0x%lx restored\n", orig_vt_mode);
940*d83cc019SAndroid Build Coastguard Worker 		orig_vt_mode = -1UL;
941*d83cc019SAndroid Build Coastguard Worker 	}
942*d83cc019SAndroid Build Coastguard Worker #endif
943*d83cc019SAndroid Build Coastguard Worker }
944*d83cc019SAndroid Build Coastguard Worker 
945*d83cc019SAndroid Build Coastguard Worker /**
946*d83cc019SAndroid Build Coastguard Worker  * kmstest_set_vt_graphics_mode:
947*d83cc019SAndroid Build Coastguard Worker  *
948*d83cc019SAndroid Build Coastguard Worker  * Sets the controlling VT (if available) into graphics/raw mode and installs
949*d83cc019SAndroid Build Coastguard Worker  * an igt exit handler to set the VT back to text mode on exit. Use
950*d83cc019SAndroid Build Coastguard Worker  * #kmstest_restore_vt_mode to restore the previous VT mode manually.
951*d83cc019SAndroid Build Coastguard Worker  *
952*d83cc019SAndroid Build Coastguard Worker  * All kms tests must call this function to make sure that the fbcon doesn't
953*d83cc019SAndroid Build Coastguard Worker  * interfere by e.g. blanking the screen.
954*d83cc019SAndroid Build Coastguard Worker  */
kmstest_set_vt_graphics_mode(void)955*d83cc019SAndroid Build Coastguard Worker void kmstest_set_vt_graphics_mode(void)
956*d83cc019SAndroid Build Coastguard Worker {
957*d83cc019SAndroid Build Coastguard Worker #if !defined(ANDROID)
958*d83cc019SAndroid Build Coastguard Worker 	long ret;
959*d83cc019SAndroid Build Coastguard Worker 
960*d83cc019SAndroid Build Coastguard Worker 	igt_install_exit_handler((igt_exit_handler_t) kmstest_restore_vt_mode);
961*d83cc019SAndroid Build Coastguard Worker 
962*d83cc019SAndroid Build Coastguard Worker 	ret = set_vt_mode(KD_GRAPHICS);
963*d83cc019SAndroid Build Coastguard Worker 
964*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret >= 0);
965*d83cc019SAndroid Build Coastguard Worker 	orig_vt_mode = ret;
966*d83cc019SAndroid Build Coastguard Worker 
967*d83cc019SAndroid Build Coastguard Worker 	igt_debug("VT: graphics mode set (mode was 0x%lx)\n", ret);
968*d83cc019SAndroid Build Coastguard Worker #endif
969*d83cc019SAndroid Build Coastguard Worker }
970*d83cc019SAndroid Build Coastguard Worker 
971*d83cc019SAndroid Build Coastguard Worker 
reset_connectors_at_exit(int sig)972*d83cc019SAndroid Build Coastguard Worker static void reset_connectors_at_exit(int sig)
973*d83cc019SAndroid Build Coastguard Worker {
974*d83cc019SAndroid Build Coastguard Worker 	igt_reset_connectors();
975*d83cc019SAndroid Build Coastguard Worker }
976*d83cc019SAndroid Build Coastguard Worker 
977*d83cc019SAndroid Build Coastguard Worker /**
978*d83cc019SAndroid Build Coastguard Worker  * kmstest_force_connector:
979*d83cc019SAndroid Build Coastguard Worker  * @fd: drm file descriptor
980*d83cc019SAndroid Build Coastguard Worker  * @connector: connector
981*d83cc019SAndroid Build Coastguard Worker  * @state: state to force on @connector
982*d83cc019SAndroid Build Coastguard Worker  *
983*d83cc019SAndroid Build Coastguard Worker  * Force the specified state on the specified connector.
984*d83cc019SAndroid Build Coastguard Worker  *
985*d83cc019SAndroid Build Coastguard Worker  * Returns: true on success
986*d83cc019SAndroid Build Coastguard Worker  */
kmstest_force_connector(int drm_fd,drmModeConnector * connector,enum kmstest_force_connector_state state)987*d83cc019SAndroid Build Coastguard Worker bool kmstest_force_connector(int drm_fd, drmModeConnector *connector,
988*d83cc019SAndroid Build Coastguard Worker 			     enum kmstest_force_connector_state state)
989*d83cc019SAndroid Build Coastguard Worker {
990*d83cc019SAndroid Build Coastguard Worker 	char *path, **tmp;
991*d83cc019SAndroid Build Coastguard Worker 	const char *value;
992*d83cc019SAndroid Build Coastguard Worker 	drmModeConnector *temp;
993*d83cc019SAndroid Build Coastguard Worker 	uint32_t devid;
994*d83cc019SAndroid Build Coastguard Worker 	int len, dir, idx;
995*d83cc019SAndroid Build Coastguard Worker 
996*d83cc019SAndroid Build Coastguard Worker #if defined(USE_INTEL)
997*d83cc019SAndroid Build Coastguard Worker 	if (is_i915_device(drm_fd)) {
998*d83cc019SAndroid Build Coastguard Worker 		devid = intel_get_drm_devid(drm_fd);
999*d83cc019SAndroid Build Coastguard Worker 
1000*d83cc019SAndroid Build Coastguard Worker 		/*
1001*d83cc019SAndroid Build Coastguard Worker 		 * forcing hdmi or dp connectors on HSW and BDW doesn't
1002*d83cc019SAndroid Build Coastguard Worker 		 * currently work, so fail early to allow the test to skip if
1003*d83cc019SAndroid Build Coastguard Worker 		 * required
1004*d83cc019SAndroid Build Coastguard Worker 		 */
1005*d83cc019SAndroid Build Coastguard Worker 		if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
1006*d83cc019SAndroid Build Coastguard Worker 		     connector->connector_type == DRM_MODE_CONNECTOR_HDMIB ||
1007*d83cc019SAndroid Build Coastguard Worker 		     connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
1008*d83cc019SAndroid Build Coastguard Worker 		    && (IS_HASWELL(devid) || IS_BROADWELL(devid)))
1009*d83cc019SAndroid Build Coastguard Worker 			return false;
1010*d83cc019SAndroid Build Coastguard Worker 	}
1011*d83cc019SAndroid Build Coastguard Worker #endif
1012*d83cc019SAndroid Build Coastguard Worker 
1013*d83cc019SAndroid Build Coastguard Worker 	switch (state) {
1014*d83cc019SAndroid Build Coastguard Worker 	case FORCE_CONNECTOR_ON:
1015*d83cc019SAndroid Build Coastguard Worker 		value = "on";
1016*d83cc019SAndroid Build Coastguard Worker 		break;
1017*d83cc019SAndroid Build Coastguard Worker 	case FORCE_CONNECTOR_DIGITAL:
1018*d83cc019SAndroid Build Coastguard Worker 		value = "on-digital";
1019*d83cc019SAndroid Build Coastguard Worker 		break;
1020*d83cc019SAndroid Build Coastguard Worker 	case FORCE_CONNECTOR_OFF:
1021*d83cc019SAndroid Build Coastguard Worker 		value = "off";
1022*d83cc019SAndroid Build Coastguard Worker 		break;
1023*d83cc019SAndroid Build Coastguard Worker 
1024*d83cc019SAndroid Build Coastguard Worker 	default:
1025*d83cc019SAndroid Build Coastguard Worker 	case FORCE_CONNECTOR_UNSPECIFIED:
1026*d83cc019SAndroid Build Coastguard Worker 		value = "detect";
1027*d83cc019SAndroid Build Coastguard Worker 		break;
1028*d83cc019SAndroid Build Coastguard Worker 	}
1029*d83cc019SAndroid Build Coastguard Worker 
1030*d83cc019SAndroid Build Coastguard Worker 	dir = igt_sysfs_open(drm_fd);
1031*d83cc019SAndroid Build Coastguard Worker 	if (dir < 0)
1032*d83cc019SAndroid Build Coastguard Worker 		return false;
1033*d83cc019SAndroid Build Coastguard Worker 
1034*d83cc019SAndroid Build Coastguard Worker 	idx = igt_device_get_card_index(drm_fd);
1035*d83cc019SAndroid Build Coastguard Worker 	if (idx < 0 || idx > 63)
1036*d83cc019SAndroid Build Coastguard Worker 		return false;
1037*d83cc019SAndroid Build Coastguard Worker 
1038*d83cc019SAndroid Build Coastguard Worker 	if (asprintf(&path, "card%d-%s-%d/status",
1039*d83cc019SAndroid Build Coastguard Worker 		     idx,
1040*d83cc019SAndroid Build Coastguard Worker 		     kmstest_connector_type_str(connector->connector_type),
1041*d83cc019SAndroid Build Coastguard Worker 		     connector->connector_type_id) < 0) {
1042*d83cc019SAndroid Build Coastguard Worker 		close(dir);
1043*d83cc019SAndroid Build Coastguard Worker 		return false;
1044*d83cc019SAndroid Build Coastguard Worker 	}
1045*d83cc019SAndroid Build Coastguard Worker 
1046*d83cc019SAndroid Build Coastguard Worker 	if (!igt_sysfs_set(dir, path, value)) {
1047*d83cc019SAndroid Build Coastguard Worker 		close(dir);
1048*d83cc019SAndroid Build Coastguard Worker 		return false;
1049*d83cc019SAndroid Build Coastguard Worker 	}
1050*d83cc019SAndroid Build Coastguard Worker 
1051*d83cc019SAndroid Build Coastguard Worker 	for (len = 0, tmp = forced_connectors; *tmp; tmp++) {
1052*d83cc019SAndroid Build Coastguard Worker 		/* check the connector is not already present */
1053*d83cc019SAndroid Build Coastguard Worker 		if (strcmp(*tmp, path) == 0) {
1054*d83cc019SAndroid Build Coastguard Worker 			len = -1;
1055*d83cc019SAndroid Build Coastguard Worker 			break;
1056*d83cc019SAndroid Build Coastguard Worker 		}
1057*d83cc019SAndroid Build Coastguard Worker 		len++;
1058*d83cc019SAndroid Build Coastguard Worker 	}
1059*d83cc019SAndroid Build Coastguard Worker 
1060*d83cc019SAndroid Build Coastguard Worker 	if (len != -1 && len < MAX_CONNECTORS) {
1061*d83cc019SAndroid Build Coastguard Worker 		forced_connectors[len] = path;
1062*d83cc019SAndroid Build Coastguard Worker 		forced_connectors_device[len] = dir;
1063*d83cc019SAndroid Build Coastguard Worker 	}
1064*d83cc019SAndroid Build Coastguard Worker 
1065*d83cc019SAndroid Build Coastguard Worker 	if (len >= MAX_CONNECTORS)
1066*d83cc019SAndroid Build Coastguard Worker 		igt_warn("Connector limit reached, %s will not be reset\n",
1067*d83cc019SAndroid Build Coastguard Worker 			 path);
1068*d83cc019SAndroid Build Coastguard Worker 
1069*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Connector %s is now forced %s\n", path, value);
1070*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Current forced connectors:\n");
1071*d83cc019SAndroid Build Coastguard Worker 	tmp = forced_connectors;
1072*d83cc019SAndroid Build Coastguard Worker 	while (*tmp) {
1073*d83cc019SAndroid Build Coastguard Worker 		igt_debug("\t%s\n", *tmp);
1074*d83cc019SAndroid Build Coastguard Worker 		tmp++;
1075*d83cc019SAndroid Build Coastguard Worker 	}
1076*d83cc019SAndroid Build Coastguard Worker 
1077*d83cc019SAndroid Build Coastguard Worker 	igt_install_exit_handler(reset_connectors_at_exit);
1078*d83cc019SAndroid Build Coastguard Worker 
1079*d83cc019SAndroid Build Coastguard Worker 	/* To allow callers to always use GetConnectorCurrent we need to force a
1080*d83cc019SAndroid Build Coastguard Worker 	 * redetection here. */
1081*d83cc019SAndroid Build Coastguard Worker 	temp = drmModeGetConnector(drm_fd, connector->connector_id);
1082*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeConnector(temp);
1083*d83cc019SAndroid Build Coastguard Worker 
1084*d83cc019SAndroid Build Coastguard Worker 	return true;
1085*d83cc019SAndroid Build Coastguard Worker }
1086*d83cc019SAndroid Build Coastguard Worker 
1087*d83cc019SAndroid Build Coastguard Worker /**
1088*d83cc019SAndroid Build Coastguard Worker  * kmstest_force_edid:
1089*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: drm file descriptor
1090*d83cc019SAndroid Build Coastguard Worker  * @connector: connector to set @edid on
1091*d83cc019SAndroid Build Coastguard Worker  * @edid: An EDID data block
1092*d83cc019SAndroid Build Coastguard Worker  *
1093*d83cc019SAndroid Build Coastguard Worker  * Set the EDID data on @connector to @edid. See also #igt_kms_get_base_edid.
1094*d83cc019SAndroid Build Coastguard Worker  *
1095*d83cc019SAndroid Build Coastguard Worker  * If @edid is NULL, the forced EDID will be removed.
1096*d83cc019SAndroid Build Coastguard Worker  */
kmstest_force_edid(int drm_fd,drmModeConnector * connector,const struct edid * edid)1097*d83cc019SAndroid Build Coastguard Worker void kmstest_force_edid(int drm_fd, drmModeConnector *connector,
1098*d83cc019SAndroid Build Coastguard Worker 			const struct edid *edid)
1099*d83cc019SAndroid Build Coastguard Worker {
1100*d83cc019SAndroid Build Coastguard Worker 	char *path;
1101*d83cc019SAndroid Build Coastguard Worker 	int debugfs_fd, ret;
1102*d83cc019SAndroid Build Coastguard Worker 	drmModeConnector *temp;
1103*d83cc019SAndroid Build Coastguard Worker 
1104*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(asprintf(&path, "%s-%d/edid_override", kmstest_connector_type_str(connector->connector_type), connector->connector_type_id),
1105*d83cc019SAndroid Build Coastguard Worker 		       -1);
1106*d83cc019SAndroid Build Coastguard Worker 	debugfs_fd = igt_debugfs_open(drm_fd, path, O_WRONLY | O_TRUNC);
1107*d83cc019SAndroid Build Coastguard Worker 	free(path);
1108*d83cc019SAndroid Build Coastguard Worker 
1109*d83cc019SAndroid Build Coastguard Worker 	igt_require(debugfs_fd != -1);
1110*d83cc019SAndroid Build Coastguard Worker 
1111*d83cc019SAndroid Build Coastguard Worker 	if (edid == NULL)
1112*d83cc019SAndroid Build Coastguard Worker 		ret = write(debugfs_fd, "reset", 5);
1113*d83cc019SAndroid Build Coastguard Worker 	else
1114*d83cc019SAndroid Build Coastguard Worker 		ret = write(debugfs_fd, edid,
1115*d83cc019SAndroid Build Coastguard Worker 			    edid_get_size(edid));
1116*d83cc019SAndroid Build Coastguard Worker 	close(debugfs_fd);
1117*d83cc019SAndroid Build Coastguard Worker 
1118*d83cc019SAndroid Build Coastguard Worker 	/* To allow callers to always use GetConnectorCurrent we need to force a
1119*d83cc019SAndroid Build Coastguard Worker 	 * redetection here. */
1120*d83cc019SAndroid Build Coastguard Worker 	temp = drmModeGetConnector(drm_fd, connector->connector_id);
1121*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeConnector(temp);
1122*d83cc019SAndroid Build Coastguard Worker 
1123*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret != -1);
1124*d83cc019SAndroid Build Coastguard Worker }
1125*d83cc019SAndroid Build Coastguard Worker 
1126*d83cc019SAndroid Build Coastguard Worker /**
1127*d83cc019SAndroid Build Coastguard Worker  * kmstest_get_connector_default_mode:
1128*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: DRM fd
1129*d83cc019SAndroid Build Coastguard Worker  * @connector: libdrm connector
1130*d83cc019SAndroid Build Coastguard Worker  * @mode: libdrm mode
1131*d83cc019SAndroid Build Coastguard Worker  *
1132*d83cc019SAndroid Build Coastguard Worker  * Retrieves the default mode for @connector and stores it in @mode.
1133*d83cc019SAndroid Build Coastguard Worker  *
1134*d83cc019SAndroid Build Coastguard Worker  * Returns: true on success, false on failure
1135*d83cc019SAndroid Build Coastguard Worker  */
kmstest_get_connector_default_mode(int drm_fd,drmModeConnector * connector,drmModeModeInfo * mode)1136*d83cc019SAndroid Build Coastguard Worker bool kmstest_get_connector_default_mode(int drm_fd, drmModeConnector *connector,
1137*d83cc019SAndroid Build Coastguard Worker 					drmModeModeInfo *mode)
1138*d83cc019SAndroid Build Coastguard Worker {
1139*d83cc019SAndroid Build Coastguard Worker 	int i;
1140*d83cc019SAndroid Build Coastguard Worker 
1141*d83cc019SAndroid Build Coastguard Worker 	if (!connector->count_modes) {
1142*d83cc019SAndroid Build Coastguard Worker 		igt_warn("no modes for connector %d\n",
1143*d83cc019SAndroid Build Coastguard Worker 			 connector->connector_id);
1144*d83cc019SAndroid Build Coastguard Worker 		return false;
1145*d83cc019SAndroid Build Coastguard Worker 	}
1146*d83cc019SAndroid Build Coastguard Worker 
1147*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < connector->count_modes; i++) {
1148*d83cc019SAndroid Build Coastguard Worker 		if (i == 0 ||
1149*d83cc019SAndroid Build Coastguard Worker 		    connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
1150*d83cc019SAndroid Build Coastguard Worker 			*mode = connector->modes[i];
1151*d83cc019SAndroid Build Coastguard Worker 			if (mode->type & DRM_MODE_TYPE_PREFERRED)
1152*d83cc019SAndroid Build Coastguard Worker 				break;
1153*d83cc019SAndroid Build Coastguard Worker 		}
1154*d83cc019SAndroid Build Coastguard Worker 	}
1155*d83cc019SAndroid Build Coastguard Worker 
1156*d83cc019SAndroid Build Coastguard Worker 	return true;
1157*d83cc019SAndroid Build Coastguard Worker }
1158*d83cc019SAndroid Build Coastguard Worker 
1159*d83cc019SAndroid Build Coastguard Worker static void
_kmstest_connector_config_crtc_mask(int drm_fd,drmModeConnector * connector,struct kmstest_connector_config * config)1160*d83cc019SAndroid Build Coastguard Worker _kmstest_connector_config_crtc_mask(int drm_fd,
1161*d83cc019SAndroid Build Coastguard Worker 				    drmModeConnector *connector,
1162*d83cc019SAndroid Build Coastguard Worker 				    struct kmstest_connector_config *config)
1163*d83cc019SAndroid Build Coastguard Worker {
1164*d83cc019SAndroid Build Coastguard Worker 	int i;
1165*d83cc019SAndroid Build Coastguard Worker 
1166*d83cc019SAndroid Build Coastguard Worker 	config->valid_crtc_idx_mask = 0;
1167*d83cc019SAndroid Build Coastguard Worker 
1168*d83cc019SAndroid Build Coastguard Worker 	/* Now get a compatible encoder */
1169*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < connector->count_encoders; i++) {
1170*d83cc019SAndroid Build Coastguard Worker 		drmModeEncoder *encoder = drmModeGetEncoder(drm_fd,
1171*d83cc019SAndroid Build Coastguard Worker 							    connector->encoders[i]);
1172*d83cc019SAndroid Build Coastguard Worker 
1173*d83cc019SAndroid Build Coastguard Worker 		if (!encoder) {
1174*d83cc019SAndroid Build Coastguard Worker 			igt_warn("could not get encoder %d: %s\n",
1175*d83cc019SAndroid Build Coastguard Worker 				 connector->encoders[i],
1176*d83cc019SAndroid Build Coastguard Worker 				 strerror(errno));
1177*d83cc019SAndroid Build Coastguard Worker 
1178*d83cc019SAndroid Build Coastguard Worker 			continue;
1179*d83cc019SAndroid Build Coastguard Worker 		}
1180*d83cc019SAndroid Build Coastguard Worker 
1181*d83cc019SAndroid Build Coastguard Worker 		config->valid_crtc_idx_mask |= encoder->possible_crtcs;
1182*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeEncoder(encoder);
1183*d83cc019SAndroid Build Coastguard Worker 	}
1184*d83cc019SAndroid Build Coastguard Worker }
1185*d83cc019SAndroid Build Coastguard Worker 
1186*d83cc019SAndroid Build Coastguard Worker static drmModeEncoder *
_kmstest_connector_config_find_encoder(int drm_fd,drmModeConnector * connector,enum pipe pipe)1187*d83cc019SAndroid Build Coastguard Worker _kmstest_connector_config_find_encoder(int drm_fd, drmModeConnector *connector, enum pipe pipe)
1188*d83cc019SAndroid Build Coastguard Worker {
1189*d83cc019SAndroid Build Coastguard Worker 	int i;
1190*d83cc019SAndroid Build Coastguard Worker 
1191*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < connector->count_encoders; i++) {
1192*d83cc019SAndroid Build Coastguard Worker 		drmModeEncoder *encoder = drmModeGetEncoder(drm_fd, connector->encoders[i]);
1193*d83cc019SAndroid Build Coastguard Worker 
1194*d83cc019SAndroid Build Coastguard Worker 		if (!encoder) {
1195*d83cc019SAndroid Build Coastguard Worker 			igt_warn("could not get encoder %d: %s\n",
1196*d83cc019SAndroid Build Coastguard Worker 				 connector->encoders[i],
1197*d83cc019SAndroid Build Coastguard Worker 				 strerror(errno));
1198*d83cc019SAndroid Build Coastguard Worker 
1199*d83cc019SAndroid Build Coastguard Worker 			continue;
1200*d83cc019SAndroid Build Coastguard Worker 		}
1201*d83cc019SAndroid Build Coastguard Worker 
1202*d83cc019SAndroid Build Coastguard Worker 		if (encoder->possible_crtcs & (1 << pipe))
1203*d83cc019SAndroid Build Coastguard Worker 			return encoder;
1204*d83cc019SAndroid Build Coastguard Worker 
1205*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeEncoder(encoder);
1206*d83cc019SAndroid Build Coastguard Worker 	}
1207*d83cc019SAndroid Build Coastguard Worker 
1208*d83cc019SAndroid Build Coastguard Worker 	igt_assert(false);
1209*d83cc019SAndroid Build Coastguard Worker 	return NULL;
1210*d83cc019SAndroid Build Coastguard Worker }
1211*d83cc019SAndroid Build Coastguard Worker 
1212*d83cc019SAndroid Build Coastguard Worker /**
1213*d83cc019SAndroid Build Coastguard Worker  * _kmstest_connector_config:
1214*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: DRM fd
1215*d83cc019SAndroid Build Coastguard Worker  * @connector_id: DRM connector id
1216*d83cc019SAndroid Build Coastguard Worker  * @crtc_idx_mask: mask of allowed DRM CRTC indices
1217*d83cc019SAndroid Build Coastguard Worker  * @config: structure filled with the possible configuration
1218*d83cc019SAndroid Build Coastguard Worker  * @probe: whether to fully re-probe mode list or not
1219*d83cc019SAndroid Build Coastguard Worker  *
1220*d83cc019SAndroid Build Coastguard Worker  * This tries to find a suitable configuration for the given connector and CRTC
1221*d83cc019SAndroid Build Coastguard Worker  * constraint and fills it into @config.
1222*d83cc019SAndroid Build Coastguard Worker  */
_kmstest_connector_config(int drm_fd,uint32_t connector_id,unsigned long crtc_idx_mask,struct kmstest_connector_config * config,bool probe)1223*d83cc019SAndroid Build Coastguard Worker static bool _kmstest_connector_config(int drm_fd, uint32_t connector_id,
1224*d83cc019SAndroid Build Coastguard Worker 				      unsigned long crtc_idx_mask,
1225*d83cc019SAndroid Build Coastguard Worker 				      struct kmstest_connector_config *config,
1226*d83cc019SAndroid Build Coastguard Worker 				      bool probe)
1227*d83cc019SAndroid Build Coastguard Worker {
1228*d83cc019SAndroid Build Coastguard Worker 	drmModeRes *resources;
1229*d83cc019SAndroid Build Coastguard Worker 	drmModeConnector *connector;
1230*d83cc019SAndroid Build Coastguard Worker 
1231*d83cc019SAndroid Build Coastguard Worker 	config->pipe = PIPE_NONE;
1232*d83cc019SAndroid Build Coastguard Worker 
1233*d83cc019SAndroid Build Coastguard Worker 	resources = drmModeGetResources(drm_fd);
1234*d83cc019SAndroid Build Coastguard Worker 	if (!resources) {
1235*d83cc019SAndroid Build Coastguard Worker 		igt_warn("drmModeGetResources failed");
1236*d83cc019SAndroid Build Coastguard Worker 		goto err1;
1237*d83cc019SAndroid Build Coastguard Worker 	}
1238*d83cc019SAndroid Build Coastguard Worker 
1239*d83cc019SAndroid Build Coastguard Worker 	/* First, find the connector & mode */
1240*d83cc019SAndroid Build Coastguard Worker 	if (probe)
1241*d83cc019SAndroid Build Coastguard Worker 		connector = drmModeGetConnector(drm_fd, connector_id);
1242*d83cc019SAndroid Build Coastguard Worker 	else
1243*d83cc019SAndroid Build Coastguard Worker 		connector = drmModeGetConnectorCurrent(drm_fd, connector_id);
1244*d83cc019SAndroid Build Coastguard Worker 
1245*d83cc019SAndroid Build Coastguard Worker 	if (!connector)
1246*d83cc019SAndroid Build Coastguard Worker 		goto err2;
1247*d83cc019SAndroid Build Coastguard Worker 
1248*d83cc019SAndroid Build Coastguard Worker 	if (connector->connector_id != connector_id) {
1249*d83cc019SAndroid Build Coastguard Worker 		igt_warn("connector id doesn't match (%d != %d)\n",
1250*d83cc019SAndroid Build Coastguard Worker 			 connector->connector_id, connector_id);
1251*d83cc019SAndroid Build Coastguard Worker 		goto err3;
1252*d83cc019SAndroid Build Coastguard Worker 	}
1253*d83cc019SAndroid Build Coastguard Worker 
1254*d83cc019SAndroid Build Coastguard Worker 	/*
1255*d83cc019SAndroid Build Coastguard Worker 	 * Find given CRTC if crtc_id != 0 or else the first CRTC not in use.
1256*d83cc019SAndroid Build Coastguard Worker 	 * In both cases find the first compatible encoder and skip the CRTC
1257*d83cc019SAndroid Build Coastguard Worker 	 * if there is non such.
1258*d83cc019SAndroid Build Coastguard Worker 	 */
1259*d83cc019SAndroid Build Coastguard Worker 	_kmstest_connector_config_crtc_mask(drm_fd, connector, config);
1260*d83cc019SAndroid Build Coastguard Worker 
1261*d83cc019SAndroid Build Coastguard Worker 	if (!connector->count_modes)
1262*d83cc019SAndroid Build Coastguard Worker 		memset(&config->default_mode, 0, sizeof(config->default_mode));
1263*d83cc019SAndroid Build Coastguard Worker 	else if (!kmstest_get_connector_default_mode(drm_fd, connector,
1264*d83cc019SAndroid Build Coastguard Worker 						     &config->default_mode))
1265*d83cc019SAndroid Build Coastguard Worker 		goto err3;
1266*d83cc019SAndroid Build Coastguard Worker 
1267*d83cc019SAndroid Build Coastguard Worker 	config->connector = connector;
1268*d83cc019SAndroid Build Coastguard Worker 
1269*d83cc019SAndroid Build Coastguard Worker 	crtc_idx_mask &= config->valid_crtc_idx_mask;
1270*d83cc019SAndroid Build Coastguard Worker 	if (!crtc_idx_mask)
1271*d83cc019SAndroid Build Coastguard Worker 		/* Keep config->connector */
1272*d83cc019SAndroid Build Coastguard Worker 		goto err2;
1273*d83cc019SAndroid Build Coastguard Worker 
1274*d83cc019SAndroid Build Coastguard Worker 	config->pipe = ffs(crtc_idx_mask) - 1;
1275*d83cc019SAndroid Build Coastguard Worker 
1276*d83cc019SAndroid Build Coastguard Worker 	config->encoder = _kmstest_connector_config_find_encoder(drm_fd, connector, config->pipe);
1277*d83cc019SAndroid Build Coastguard Worker 	config->crtc = drmModeGetCrtc(drm_fd, resources->crtcs[config->pipe]);
1278*d83cc019SAndroid Build Coastguard Worker 
1279*d83cc019SAndroid Build Coastguard Worker 	if (connector->connection != DRM_MODE_CONNECTED)
1280*d83cc019SAndroid Build Coastguard Worker 		goto err2;
1281*d83cc019SAndroid Build Coastguard Worker 
1282*d83cc019SAndroid Build Coastguard Worker 	if (!connector->count_modes) {
1283*d83cc019SAndroid Build Coastguard Worker 		if (probe)
1284*d83cc019SAndroid Build Coastguard Worker 			igt_warn("connector %d/%s-%d has no modes\n", connector_id,
1285*d83cc019SAndroid Build Coastguard Worker 				kmstest_connector_type_str(connector->connector_type),
1286*d83cc019SAndroid Build Coastguard Worker 				connector->connector_type_id);
1287*d83cc019SAndroid Build Coastguard Worker 		goto err2;
1288*d83cc019SAndroid Build Coastguard Worker 	}
1289*d83cc019SAndroid Build Coastguard Worker 
1290*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeResources(resources);
1291*d83cc019SAndroid Build Coastguard Worker 	return true;
1292*d83cc019SAndroid Build Coastguard Worker err3:
1293*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeConnector(connector);
1294*d83cc019SAndroid Build Coastguard Worker err2:
1295*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeResources(resources);
1296*d83cc019SAndroid Build Coastguard Worker err1:
1297*d83cc019SAndroid Build Coastguard Worker 	return false;
1298*d83cc019SAndroid Build Coastguard Worker }
1299*d83cc019SAndroid Build Coastguard Worker 
1300*d83cc019SAndroid Build Coastguard Worker /**
1301*d83cc019SAndroid Build Coastguard Worker  * kmstest_get_connector_config:
1302*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: DRM fd
1303*d83cc019SAndroid Build Coastguard Worker  * @connector_id: DRM connector id
1304*d83cc019SAndroid Build Coastguard Worker  * @crtc_idx_mask: mask of allowed DRM CRTC indices
1305*d83cc019SAndroid Build Coastguard Worker  * @config: structure filled with the possible configuration
1306*d83cc019SAndroid Build Coastguard Worker  *
1307*d83cc019SAndroid Build Coastguard Worker  * This tries to find a suitable configuration for the given connector and CRTC
1308*d83cc019SAndroid Build Coastguard Worker  * constraint and fills it into @config.
1309*d83cc019SAndroid Build Coastguard Worker  */
kmstest_get_connector_config(int drm_fd,uint32_t connector_id,unsigned long crtc_idx_mask,struct kmstest_connector_config * config)1310*d83cc019SAndroid Build Coastguard Worker bool kmstest_get_connector_config(int drm_fd, uint32_t connector_id,
1311*d83cc019SAndroid Build Coastguard Worker 				  unsigned long crtc_idx_mask,
1312*d83cc019SAndroid Build Coastguard Worker 				  struct kmstest_connector_config *config)
1313*d83cc019SAndroid Build Coastguard Worker {
1314*d83cc019SAndroid Build Coastguard Worker 	return _kmstest_connector_config(drm_fd, connector_id, crtc_idx_mask,
1315*d83cc019SAndroid Build Coastguard Worker 					 config, 0);
1316*d83cc019SAndroid Build Coastguard Worker }
1317*d83cc019SAndroid Build Coastguard Worker 
1318*d83cc019SAndroid Build Coastguard Worker /**
1319*d83cc019SAndroid Build Coastguard Worker  * kmstest_probe_connector_config:
1320*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: DRM fd
1321*d83cc019SAndroid Build Coastguard Worker  * @connector_id: DRM connector id
1322*d83cc019SAndroid Build Coastguard Worker  * @crtc_idx_mask: mask of allowed DRM CRTC indices
1323*d83cc019SAndroid Build Coastguard Worker  * @config: structure filled with the possible configuration
1324*d83cc019SAndroid Build Coastguard Worker  *
1325*d83cc019SAndroid Build Coastguard Worker  * This tries to find a suitable configuration for the given connector and CRTC
1326*d83cc019SAndroid Build Coastguard Worker  * constraint and fills it into @config, fully probing the connector in the
1327*d83cc019SAndroid Build Coastguard Worker  * process.
1328*d83cc019SAndroid Build Coastguard Worker  */
kmstest_probe_connector_config(int drm_fd,uint32_t connector_id,unsigned long crtc_idx_mask,struct kmstest_connector_config * config)1329*d83cc019SAndroid Build Coastguard Worker bool kmstest_probe_connector_config(int drm_fd, uint32_t connector_id,
1330*d83cc019SAndroid Build Coastguard Worker 				    unsigned long crtc_idx_mask,
1331*d83cc019SAndroid Build Coastguard Worker 				    struct kmstest_connector_config *config)
1332*d83cc019SAndroid Build Coastguard Worker {
1333*d83cc019SAndroid Build Coastguard Worker 	return _kmstest_connector_config(drm_fd, connector_id, crtc_idx_mask,
1334*d83cc019SAndroid Build Coastguard Worker 					 config, 1);
1335*d83cc019SAndroid Build Coastguard Worker }
1336*d83cc019SAndroid Build Coastguard Worker 
1337*d83cc019SAndroid Build Coastguard Worker /**
1338*d83cc019SAndroid Build Coastguard Worker  * kmstest_free_connector_config:
1339*d83cc019SAndroid Build Coastguard Worker  * @config: connector configuration structure
1340*d83cc019SAndroid Build Coastguard Worker  *
1341*d83cc019SAndroid Build Coastguard Worker  * Free any resources in @config allocated in kmstest_get_connector_config().
1342*d83cc019SAndroid Build Coastguard Worker  */
kmstest_free_connector_config(struct kmstest_connector_config * config)1343*d83cc019SAndroid Build Coastguard Worker void kmstest_free_connector_config(struct kmstest_connector_config *config)
1344*d83cc019SAndroid Build Coastguard Worker {
1345*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeCrtc(config->crtc);
1346*d83cc019SAndroid Build Coastguard Worker 	config->crtc = NULL;
1347*d83cc019SAndroid Build Coastguard Worker 
1348*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeEncoder(config->encoder);
1349*d83cc019SAndroid Build Coastguard Worker 	config->encoder = NULL;
1350*d83cc019SAndroid Build Coastguard Worker 
1351*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeConnector(config->connector);
1352*d83cc019SAndroid Build Coastguard Worker 	config->connector = NULL;
1353*d83cc019SAndroid Build Coastguard Worker }
1354*d83cc019SAndroid Build Coastguard Worker 
1355*d83cc019SAndroid Build Coastguard Worker /**
1356*d83cc019SAndroid Build Coastguard Worker  * kmstest_set_connector_dpms:
1357*d83cc019SAndroid Build Coastguard Worker  * @fd: DRM fd
1358*d83cc019SAndroid Build Coastguard Worker  * @connector: libdrm connector
1359*d83cc019SAndroid Build Coastguard Worker  * @mode: DRM DPMS value
1360*d83cc019SAndroid Build Coastguard Worker  *
1361*d83cc019SAndroid Build Coastguard Worker  * This function sets the DPMS setting of @connector to @mode.
1362*d83cc019SAndroid Build Coastguard Worker  */
kmstest_set_connector_dpms(int fd,drmModeConnector * connector,int mode)1363*d83cc019SAndroid Build Coastguard Worker void kmstest_set_connector_dpms(int fd, drmModeConnector *connector, int mode)
1364*d83cc019SAndroid Build Coastguard Worker {
1365*d83cc019SAndroid Build Coastguard Worker 	int i, dpms = 0;
1366*d83cc019SAndroid Build Coastguard Worker 	bool found_it = false;
1367*d83cc019SAndroid Build Coastguard Worker 
1368*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < connector->count_props; i++) {
1369*d83cc019SAndroid Build Coastguard Worker 		struct drm_mode_get_property prop = {
1370*d83cc019SAndroid Build Coastguard Worker 			.prop_id = connector->props[i],
1371*d83cc019SAndroid Build Coastguard Worker 		};
1372*d83cc019SAndroid Build Coastguard Worker 
1373*d83cc019SAndroid Build Coastguard Worker 		if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
1374*d83cc019SAndroid Build Coastguard Worker 			continue;
1375*d83cc019SAndroid Build Coastguard Worker 
1376*d83cc019SAndroid Build Coastguard Worker 		if (strcmp(prop.name, "DPMS"))
1377*d83cc019SAndroid Build Coastguard Worker 			continue;
1378*d83cc019SAndroid Build Coastguard Worker 
1379*d83cc019SAndroid Build Coastguard Worker 		dpms = prop.prop_id;
1380*d83cc019SAndroid Build Coastguard Worker 		found_it = true;
1381*d83cc019SAndroid Build Coastguard Worker 		break;
1382*d83cc019SAndroid Build Coastguard Worker 	}
1383*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(found_it, "DPMS property not found on %d\n",
1384*d83cc019SAndroid Build Coastguard Worker 		     connector->connector_id);
1385*d83cc019SAndroid Build Coastguard Worker 
1386*d83cc019SAndroid Build Coastguard Worker 	igt_assert(drmModeConnectorSetProperty(fd, connector->connector_id,
1387*d83cc019SAndroid Build Coastguard Worker 					       dpms, mode) == 0);
1388*d83cc019SAndroid Build Coastguard Worker }
1389*d83cc019SAndroid Build Coastguard Worker 
1390*d83cc019SAndroid Build Coastguard Worker /**
1391*d83cc019SAndroid Build Coastguard Worker  * kmstest_get_property:
1392*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: drm file descriptor
1393*d83cc019SAndroid Build Coastguard Worker  * @object_id: object whose properties we're going to get
1394*d83cc019SAndroid Build Coastguard Worker  * @object_type: type of obj_id (DRM_MODE_OBJECT_*)
1395*d83cc019SAndroid Build Coastguard Worker  * @name: name of the property we're going to get
1396*d83cc019SAndroid Build Coastguard Worker  * @prop_id: if not NULL, returns the property id
1397*d83cc019SAndroid Build Coastguard Worker  * @value: if not NULL, returns the property value
1398*d83cc019SAndroid Build Coastguard Worker  * @prop: if not NULL, returns the property, and the caller will have to free
1399*d83cc019SAndroid Build Coastguard Worker  *        it manually.
1400*d83cc019SAndroid Build Coastguard Worker  *
1401*d83cc019SAndroid Build Coastguard Worker  * Finds a property with the given name on the given object.
1402*d83cc019SAndroid Build Coastguard Worker  *
1403*d83cc019SAndroid Build Coastguard Worker  * Returns: true in case we found something.
1404*d83cc019SAndroid Build Coastguard Worker  */
1405*d83cc019SAndroid Build Coastguard Worker bool
kmstest_get_property(int drm_fd,uint32_t object_id,uint32_t object_type,const char * name,uint32_t * prop_id,uint64_t * value,drmModePropertyPtr * prop)1406*d83cc019SAndroid Build Coastguard Worker kmstest_get_property(int drm_fd, uint32_t object_id, uint32_t object_type,
1407*d83cc019SAndroid Build Coastguard Worker 		     const char *name, uint32_t *prop_id /* out */,
1408*d83cc019SAndroid Build Coastguard Worker 		     uint64_t *value /* out */,
1409*d83cc019SAndroid Build Coastguard Worker 		     drmModePropertyPtr *prop /* out */)
1410*d83cc019SAndroid Build Coastguard Worker {
1411*d83cc019SAndroid Build Coastguard Worker 	drmModeObjectPropertiesPtr proplist;
1412*d83cc019SAndroid Build Coastguard Worker 	drmModePropertyPtr _prop;
1413*d83cc019SAndroid Build Coastguard Worker 	bool found = false;
1414*d83cc019SAndroid Build Coastguard Worker 	int i;
1415*d83cc019SAndroid Build Coastguard Worker 
1416*d83cc019SAndroid Build Coastguard Worker 	proplist = drmModeObjectGetProperties(drm_fd, object_id, object_type);
1417*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < proplist->count_props; i++) {
1418*d83cc019SAndroid Build Coastguard Worker 		_prop = drmModeGetProperty(drm_fd, proplist->props[i]);
1419*d83cc019SAndroid Build Coastguard Worker 		if (!_prop)
1420*d83cc019SAndroid Build Coastguard Worker 			continue;
1421*d83cc019SAndroid Build Coastguard Worker 
1422*d83cc019SAndroid Build Coastguard Worker 		if (strcmp(_prop->name, name) == 0) {
1423*d83cc019SAndroid Build Coastguard Worker 			found = true;
1424*d83cc019SAndroid Build Coastguard Worker 			if (prop_id)
1425*d83cc019SAndroid Build Coastguard Worker 				*prop_id = proplist->props[i];
1426*d83cc019SAndroid Build Coastguard Worker 			if (value)
1427*d83cc019SAndroid Build Coastguard Worker 				*value = proplist->prop_values[i];
1428*d83cc019SAndroid Build Coastguard Worker 			if (prop)
1429*d83cc019SAndroid Build Coastguard Worker 				*prop = _prop;
1430*d83cc019SAndroid Build Coastguard Worker 			else
1431*d83cc019SAndroid Build Coastguard Worker 				drmModeFreeProperty(_prop);
1432*d83cc019SAndroid Build Coastguard Worker 
1433*d83cc019SAndroid Build Coastguard Worker 			break;
1434*d83cc019SAndroid Build Coastguard Worker 		}
1435*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeProperty(_prop);
1436*d83cc019SAndroid Build Coastguard Worker 	}
1437*d83cc019SAndroid Build Coastguard Worker 
1438*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeObjectProperties(proplist);
1439*d83cc019SAndroid Build Coastguard Worker 	return found;
1440*d83cc019SAndroid Build Coastguard Worker }
1441*d83cc019SAndroid Build Coastguard Worker 
1442*d83cc019SAndroid Build Coastguard Worker /**
1443*d83cc019SAndroid Build Coastguard Worker  * kmstest_unset_all_crtcs:
1444*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: the DRM fd
1445*d83cc019SAndroid Build Coastguard Worker  * @resources: libdrm resources pointer
1446*d83cc019SAndroid Build Coastguard Worker  *
1447*d83cc019SAndroid Build Coastguard Worker  * Disables all the screens.
1448*d83cc019SAndroid Build Coastguard Worker  */
kmstest_unset_all_crtcs(int drm_fd,drmModeResPtr resources)1449*d83cc019SAndroid Build Coastguard Worker void kmstest_unset_all_crtcs(int drm_fd, drmModeResPtr resources)
1450*d83cc019SAndroid Build Coastguard Worker {
1451*d83cc019SAndroid Build Coastguard Worker 	int i, rc;
1452*d83cc019SAndroid Build Coastguard Worker 
1453*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < resources->count_crtcs; i++) {
1454*d83cc019SAndroid Build Coastguard Worker 		rc = drmModeSetCrtc(drm_fd, resources->crtcs[i], 0, 0, 0, NULL,
1455*d83cc019SAndroid Build Coastguard Worker 				    0, NULL);
1456*d83cc019SAndroid Build Coastguard Worker 		igt_assert(rc == 0);
1457*d83cc019SAndroid Build Coastguard Worker 	}
1458*d83cc019SAndroid Build Coastguard Worker }
1459*d83cc019SAndroid Build Coastguard Worker 
1460*d83cc019SAndroid Build Coastguard Worker /**
1461*d83cc019SAndroid Build Coastguard Worker  * kmstest_get_crtc_idx:
1462*d83cc019SAndroid Build Coastguard Worker  * @res: the libdrm resources
1463*d83cc019SAndroid Build Coastguard Worker  * @crtc_id: the CRTC id
1464*d83cc019SAndroid Build Coastguard Worker  *
1465*d83cc019SAndroid Build Coastguard Worker  * Get the CRTC index based on its ID. This is useful since a few places of
1466*d83cc019SAndroid Build Coastguard Worker  * libdrm deal with CRTC masks.
1467*d83cc019SAndroid Build Coastguard Worker  */
kmstest_get_crtc_idx(drmModeRes * res,uint32_t crtc_id)1468*d83cc019SAndroid Build Coastguard Worker int kmstest_get_crtc_idx(drmModeRes *res, uint32_t crtc_id)
1469*d83cc019SAndroid Build Coastguard Worker {
1470*d83cc019SAndroid Build Coastguard Worker 	int i;
1471*d83cc019SAndroid Build Coastguard Worker 
1472*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < res->count_crtcs; i++)
1473*d83cc019SAndroid Build Coastguard Worker 		if (res->crtcs[i] == crtc_id)
1474*d83cc019SAndroid Build Coastguard Worker 			return i;
1475*d83cc019SAndroid Build Coastguard Worker 
1476*d83cc019SAndroid Build Coastguard Worker 	igt_assert(false);
1477*d83cc019SAndroid Build Coastguard Worker }
1478*d83cc019SAndroid Build Coastguard Worker 
pipe_select(int pipe)1479*d83cc019SAndroid Build Coastguard Worker static inline uint32_t pipe_select(int pipe)
1480*d83cc019SAndroid Build Coastguard Worker {
1481*d83cc019SAndroid Build Coastguard Worker 	if (pipe > 1)
1482*d83cc019SAndroid Build Coastguard Worker 		return pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
1483*d83cc019SAndroid Build Coastguard Worker 	else if (pipe > 0)
1484*d83cc019SAndroid Build Coastguard Worker 		return DRM_VBLANK_SECONDARY;
1485*d83cc019SAndroid Build Coastguard Worker 	else
1486*d83cc019SAndroid Build Coastguard Worker 		return 0;
1487*d83cc019SAndroid Build Coastguard Worker }
1488*d83cc019SAndroid Build Coastguard Worker 
1489*d83cc019SAndroid Build Coastguard Worker /**
1490*d83cc019SAndroid Build Coastguard Worker  * kmstest_get_vblank:
1491*d83cc019SAndroid Build Coastguard Worker  * @fd: Opened drm file descriptor
1492*d83cc019SAndroid Build Coastguard Worker  * @pipe: Display pipe
1493*d83cc019SAndroid Build Coastguard Worker  * @flags: Flags passed to drm_ioctl_wait_vblank
1494*d83cc019SAndroid Build Coastguard Worker  *
1495*d83cc019SAndroid Build Coastguard Worker  * Blocks or request a signal when a specified vblank event occurs
1496*d83cc019SAndroid Build Coastguard Worker  *
1497*d83cc019SAndroid Build Coastguard Worker  * Returns 0 on success or non-zero unsigned integer otherwise
1498*d83cc019SAndroid Build Coastguard Worker  */
kmstest_get_vblank(int fd,int pipe,unsigned int flags)1499*d83cc019SAndroid Build Coastguard Worker unsigned int kmstest_get_vblank(int fd, int pipe, unsigned int flags)
1500*d83cc019SAndroid Build Coastguard Worker {
1501*d83cc019SAndroid Build Coastguard Worker 	union drm_wait_vblank vbl;
1502*d83cc019SAndroid Build Coastguard Worker 
1503*d83cc019SAndroid Build Coastguard Worker 	memset(&vbl, 0, sizeof(vbl));
1504*d83cc019SAndroid Build Coastguard Worker 	vbl.request.type = DRM_VBLANK_RELATIVE | pipe_select(pipe) | flags;
1505*d83cc019SAndroid Build Coastguard Worker 	if (drmIoctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl))
1506*d83cc019SAndroid Build Coastguard Worker 		return 0;
1507*d83cc019SAndroid Build Coastguard Worker 
1508*d83cc019SAndroid Build Coastguard Worker 	return vbl.reply.sequence;
1509*d83cc019SAndroid Build Coastguard Worker }
1510*d83cc019SAndroid Build Coastguard Worker 
1511*d83cc019SAndroid Build Coastguard Worker /**
1512*d83cc019SAndroid Build Coastguard Worker  * kmstest_wait_for_pageflip:
1513*d83cc019SAndroid Build Coastguard Worker  * @fd: Opened drm file descriptor
1514*d83cc019SAndroid Build Coastguard Worker  *
1515*d83cc019SAndroid Build Coastguard Worker  * Blocks until pageflip is completed
1516*d83cc019SAndroid Build Coastguard Worker  *
1517*d83cc019SAndroid Build Coastguard Worker  */
kmstest_wait_for_pageflip(int fd)1518*d83cc019SAndroid Build Coastguard Worker void kmstest_wait_for_pageflip(int fd)
1519*d83cc019SAndroid Build Coastguard Worker {
1520*d83cc019SAndroid Build Coastguard Worker 	drmEventContext evctx = { .version = 2 };
1521*d83cc019SAndroid Build Coastguard Worker 	struct timeval timeout = { .tv_sec = 0, .tv_usec = 50000 };
1522*d83cc019SAndroid Build Coastguard Worker 	fd_set fds;
1523*d83cc019SAndroid Build Coastguard Worker 	int ret;
1524*d83cc019SAndroid Build Coastguard Worker 
1525*d83cc019SAndroid Build Coastguard Worker 	/* Wait for pageflip completion, then consume event on fd */
1526*d83cc019SAndroid Build Coastguard Worker 	FD_ZERO(&fds);
1527*d83cc019SAndroid Build Coastguard Worker 	FD_SET(fd, &fds);
1528*d83cc019SAndroid Build Coastguard Worker 	do {
1529*d83cc019SAndroid Build Coastguard Worker 		errno = 0;
1530*d83cc019SAndroid Build Coastguard Worker 		ret = select(fd + 1, &fds, NULL, NULL, &timeout);
1531*d83cc019SAndroid Build Coastguard Worker 	} while (ret < 0 && errno == EINTR);
1532*d83cc019SAndroid Build Coastguard Worker 
1533*d83cc019SAndroid Build Coastguard Worker 	igt_fail_on_f(ret == 0,
1534*d83cc019SAndroid Build Coastguard Worker 		     "Exceeded timeout (50ms) while waiting for a pageflip\n");
1535*d83cc019SAndroid Build Coastguard Worker 
1536*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(ret == 1,
1537*d83cc019SAndroid Build Coastguard Worker 		     "Waiting for pageflip failed with %d from select(drmfd)\n",
1538*d83cc019SAndroid Build Coastguard Worker 		     ret);
1539*d83cc019SAndroid Build Coastguard Worker 
1540*d83cc019SAndroid Build Coastguard Worker 	igt_assert(drmHandleEvent(fd, &evctx) == 0);
1541*d83cc019SAndroid Build Coastguard Worker }
1542*d83cc019SAndroid Build Coastguard Worker 
get_plane(char * str,int type,struct kmstest_plane * plane)1543*d83cc019SAndroid Build Coastguard Worker static void get_plane(char *str, int type, struct kmstest_plane *plane)
1544*d83cc019SAndroid Build Coastguard Worker {
1545*d83cc019SAndroid Build Coastguard Worker 	int ret;
1546*d83cc019SAndroid Build Coastguard Worker 	char buf[256];
1547*d83cc019SAndroid Build Coastguard Worker 
1548*d83cc019SAndroid Build Coastguard Worker 	plane->type = type;
1549*d83cc019SAndroid Build Coastguard Worker 	ret = sscanf(str + 12, "%d%*c %*s %[^n]s",
1550*d83cc019SAndroid Build Coastguard Worker 		     &plane->id,
1551*d83cc019SAndroid Build Coastguard Worker 		     buf);
1552*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 2);
1553*d83cc019SAndroid Build Coastguard Worker 
1554*d83cc019SAndroid Build Coastguard Worker 	ret = sscanf(buf + 9, "%4d%*c%4d%*c", &plane->pos_x, &plane->pos_y);
1555*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 2);
1556*d83cc019SAndroid Build Coastguard Worker 
1557*d83cc019SAndroid Build Coastguard Worker 	ret = sscanf(buf + 30, "%4d%*c%4d%*c", &plane->width, &plane->height);
1558*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 2);
1559*d83cc019SAndroid Build Coastguard Worker }
1560*d83cc019SAndroid Build Coastguard Worker 
parse_planes(FILE * fid,struct kmstest_plane * planes)1561*d83cc019SAndroid Build Coastguard Worker static int parse_planes(FILE *fid, struct kmstest_plane *planes)
1562*d83cc019SAndroid Build Coastguard Worker {
1563*d83cc019SAndroid Build Coastguard Worker 	char tmp[256];
1564*d83cc019SAndroid Build Coastguard Worker 	int n_planes;
1565*d83cc019SAndroid Build Coastguard Worker 
1566*d83cc019SAndroid Build Coastguard Worker 	n_planes = 0;
1567*d83cc019SAndroid Build Coastguard Worker 	while (fgets(tmp, 256, fid) != NULL) {
1568*d83cc019SAndroid Build Coastguard Worker 		if (strstr(tmp, "type=PRI") != NULL) {
1569*d83cc019SAndroid Build Coastguard Worker 			if (planes) {
1570*d83cc019SAndroid Build Coastguard Worker 				get_plane(tmp, DRM_PLANE_TYPE_PRIMARY, &planes[n_planes]);
1571*d83cc019SAndroid Build Coastguard Worker 				planes[n_planes].index = n_planes;
1572*d83cc019SAndroid Build Coastguard Worker 			}
1573*d83cc019SAndroid Build Coastguard Worker 			n_planes++;
1574*d83cc019SAndroid Build Coastguard Worker 		} else if (strstr(tmp, "type=OVL") != NULL) {
1575*d83cc019SAndroid Build Coastguard Worker 			if (planes) {
1576*d83cc019SAndroid Build Coastguard Worker 				get_plane(tmp, DRM_PLANE_TYPE_OVERLAY, &planes[n_planes]);
1577*d83cc019SAndroid Build Coastguard Worker 				planes[n_planes].index = n_planes;
1578*d83cc019SAndroid Build Coastguard Worker 			}
1579*d83cc019SAndroid Build Coastguard Worker 			n_planes++;
1580*d83cc019SAndroid Build Coastguard Worker 		} else if (strstr(tmp, "type=CUR") != NULL) {
1581*d83cc019SAndroid Build Coastguard Worker 			if (planes) {
1582*d83cc019SAndroid Build Coastguard Worker 				get_plane(tmp, DRM_PLANE_TYPE_CURSOR, &planes[n_planes]);
1583*d83cc019SAndroid Build Coastguard Worker 				planes[n_planes].index = n_planes;
1584*d83cc019SAndroid Build Coastguard Worker 			}
1585*d83cc019SAndroid Build Coastguard Worker 			n_planes++;
1586*d83cc019SAndroid Build Coastguard Worker 			break;
1587*d83cc019SAndroid Build Coastguard Worker 		}
1588*d83cc019SAndroid Build Coastguard Worker 	}
1589*d83cc019SAndroid Build Coastguard Worker 
1590*d83cc019SAndroid Build Coastguard Worker 	return n_planes;
1591*d83cc019SAndroid Build Coastguard Worker }
1592*d83cc019SAndroid Build Coastguard Worker 
parse_crtc(char * info,struct kmstest_crtc * crtc)1593*d83cc019SAndroid Build Coastguard Worker static void parse_crtc(char *info, struct kmstest_crtc *crtc)
1594*d83cc019SAndroid Build Coastguard Worker {
1595*d83cc019SAndroid Build Coastguard Worker 	char buf[256];
1596*d83cc019SAndroid Build Coastguard Worker 	int ret;
1597*d83cc019SAndroid Build Coastguard Worker 	char pipe;
1598*d83cc019SAndroid Build Coastguard Worker 
1599*d83cc019SAndroid Build Coastguard Worker 	ret = sscanf(info + 4, "%d%*c %*s %c%*c %*s %s%*c",
1600*d83cc019SAndroid Build Coastguard Worker 		     &crtc->id, &pipe, buf);
1601*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 3);
1602*d83cc019SAndroid Build Coastguard Worker 
1603*d83cc019SAndroid Build Coastguard Worker 	crtc->pipe = kmstest_pipe_to_index(pipe);
1604*d83cc019SAndroid Build Coastguard Worker 	igt_assert(crtc->pipe >= 0);
1605*d83cc019SAndroid Build Coastguard Worker 
1606*d83cc019SAndroid Build Coastguard Worker 	ret = sscanf(buf + 6, "%d%*c%d%*c",
1607*d83cc019SAndroid Build Coastguard Worker 		     &crtc->width, &crtc->height);
1608*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 2);
1609*d83cc019SAndroid Build Coastguard Worker }
1610*d83cc019SAndroid Build Coastguard Worker 
kmstest_get_crtc(int device,enum pipe pipe,struct kmstest_crtc * crtc)1611*d83cc019SAndroid Build Coastguard Worker static void kmstest_get_crtc(int device, enum pipe pipe, struct kmstest_crtc *crtc)
1612*d83cc019SAndroid Build Coastguard Worker {
1613*d83cc019SAndroid Build Coastguard Worker 	char tmp[256];
1614*d83cc019SAndroid Build Coastguard Worker 	FILE *file;
1615*d83cc019SAndroid Build Coastguard Worker 	int ncrtc;
1616*d83cc019SAndroid Build Coastguard Worker 	int line;
1617*d83cc019SAndroid Build Coastguard Worker 	long int n;
1618*d83cc019SAndroid Build Coastguard Worker 	int fd;
1619*d83cc019SAndroid Build Coastguard Worker 
1620*d83cc019SAndroid Build Coastguard Worker 	fd = igt_debugfs_open(device, "i915_display_info", O_RDONLY);
1621*d83cc019SAndroid Build Coastguard Worker 	file = fdopen(fd, "r");
1622*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on(file == NULL);
1623*d83cc019SAndroid Build Coastguard Worker 
1624*d83cc019SAndroid Build Coastguard Worker 	ncrtc = 0;
1625*d83cc019SAndroid Build Coastguard Worker 	line = 0;
1626*d83cc019SAndroid Build Coastguard Worker 	while (fgets(tmp, 256, file) != NULL) {
1627*d83cc019SAndroid Build Coastguard Worker 		if ((strstr(tmp, "CRTC") != NULL) && (line > 0)) {
1628*d83cc019SAndroid Build Coastguard Worker 			if (strstr(tmp, "active=yes") != NULL) {
1629*d83cc019SAndroid Build Coastguard Worker 				crtc->active = true;
1630*d83cc019SAndroid Build Coastguard Worker 				parse_crtc(tmp, crtc);
1631*d83cc019SAndroid Build Coastguard Worker 
1632*d83cc019SAndroid Build Coastguard Worker 				n = ftell(file);
1633*d83cc019SAndroid Build Coastguard Worker 				crtc->n_planes = parse_planes(file, NULL);
1634*d83cc019SAndroid Build Coastguard Worker 				igt_assert_lt(0, crtc->n_planes);
1635*d83cc019SAndroid Build Coastguard Worker 				crtc->planes = calloc(crtc->n_planes, sizeof(*crtc->planes));
1636*d83cc019SAndroid Build Coastguard Worker 				igt_assert_f(crtc->planes, "Failed to allocate memory for %d planes\n", crtc->n_planes);
1637*d83cc019SAndroid Build Coastguard Worker 
1638*d83cc019SAndroid Build Coastguard Worker 				fseek(file, n, SEEK_SET);
1639*d83cc019SAndroid Build Coastguard Worker 				parse_planes(file, crtc->planes);
1640*d83cc019SAndroid Build Coastguard Worker 
1641*d83cc019SAndroid Build Coastguard Worker 				if (crtc->pipe != pipe) {
1642*d83cc019SAndroid Build Coastguard Worker 					free(crtc->planes);
1643*d83cc019SAndroid Build Coastguard Worker 				} else {
1644*d83cc019SAndroid Build Coastguard Worker 					ncrtc++;
1645*d83cc019SAndroid Build Coastguard Worker 					break;
1646*d83cc019SAndroid Build Coastguard Worker 				}
1647*d83cc019SAndroid Build Coastguard Worker 			}
1648*d83cc019SAndroid Build Coastguard Worker 		}
1649*d83cc019SAndroid Build Coastguard Worker 
1650*d83cc019SAndroid Build Coastguard Worker 		line++;
1651*d83cc019SAndroid Build Coastguard Worker 	}
1652*d83cc019SAndroid Build Coastguard Worker 
1653*d83cc019SAndroid Build Coastguard Worker 	fclose(file);
1654*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1655*d83cc019SAndroid Build Coastguard Worker 
1656*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ncrtc == 1);
1657*d83cc019SAndroid Build Coastguard Worker }
1658*d83cc019SAndroid Build Coastguard Worker 
1659*d83cc019SAndroid Build Coastguard Worker /**
1660*d83cc019SAndroid Build Coastguard Worker  * igt_assert_plane_visible:
1661*d83cc019SAndroid Build Coastguard Worker  * @fd: Opened file descriptor
1662*d83cc019SAndroid Build Coastguard Worker  * @pipe: Display pipe
1663*d83cc019SAndroid Build Coastguard Worker  * @visibility: Boolean parameter to test against the plane's current visibility state
1664*d83cc019SAndroid Build Coastguard Worker  *
1665*d83cc019SAndroid Build Coastguard Worker  * Asserts only if the plane's visibility state matches the status being passed by @visibility
1666*d83cc019SAndroid Build Coastguard Worker  */
igt_assert_plane_visible(int fd,enum pipe pipe,int plane_index,bool visibility)1667*d83cc019SAndroid Build Coastguard Worker void igt_assert_plane_visible(int fd, enum pipe pipe, int plane_index, bool visibility)
1668*d83cc019SAndroid Build Coastguard Worker {
1669*d83cc019SAndroid Build Coastguard Worker 	struct kmstest_crtc crtc;
1670*d83cc019SAndroid Build Coastguard Worker 	bool visible = true;
1671*d83cc019SAndroid Build Coastguard Worker 
1672*d83cc019SAndroid Build Coastguard Worker 	kmstest_get_crtc(fd, pipe, &crtc);
1673*d83cc019SAndroid Build Coastguard Worker 
1674*d83cc019SAndroid Build Coastguard Worker 	igt_assert(plane_index < crtc.n_planes);
1675*d83cc019SAndroid Build Coastguard Worker 
1676*d83cc019SAndroid Build Coastguard Worker 	if (crtc.planes[plane_index].pos_x > crtc.width ||
1677*d83cc019SAndroid Build Coastguard Worker 	    crtc.planes[plane_index].pos_y > crtc.height)
1678*d83cc019SAndroid Build Coastguard Worker 		visible = false;
1679*d83cc019SAndroid Build Coastguard Worker 
1680*d83cc019SAndroid Build Coastguard Worker 	free(crtc.planes);
1681*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(visible, visibility);
1682*d83cc019SAndroid Build Coastguard Worker }
1683*d83cc019SAndroid Build Coastguard Worker 
1684*d83cc019SAndroid Build Coastguard Worker /**
1685*d83cc019SAndroid Build Coastguard Worker  * kms_has_vblank:
1686*d83cc019SAndroid Build Coastguard Worker  * @fd: DRM fd
1687*d83cc019SAndroid Build Coastguard Worker  *
1688*d83cc019SAndroid Build Coastguard Worker  * Get the VBlank errno after an attempt to call drmWaitVBlank(). This
1689*d83cc019SAndroid Build Coastguard Worker  * function is useful for checking if a driver has support or not for VBlank.
1690*d83cc019SAndroid Build Coastguard Worker  *
1691*d83cc019SAndroid Build Coastguard Worker  * Returns: true if target driver has VBlank support, otherwise return false.
1692*d83cc019SAndroid Build Coastguard Worker  */
kms_has_vblank(int fd)1693*d83cc019SAndroid Build Coastguard Worker bool kms_has_vblank(int fd)
1694*d83cc019SAndroid Build Coastguard Worker {
1695*d83cc019SAndroid Build Coastguard Worker 	drmVBlank dummy_vbl;
1696*d83cc019SAndroid Build Coastguard Worker 
1697*d83cc019SAndroid Build Coastguard Worker 	memset(&dummy_vbl, 0, sizeof(drmVBlank));
1698*d83cc019SAndroid Build Coastguard Worker 	dummy_vbl.request.type = DRM_VBLANK_RELATIVE;
1699*d83cc019SAndroid Build Coastguard Worker 
1700*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
1701*d83cc019SAndroid Build Coastguard Worker 	drmWaitVBlank(fd, &dummy_vbl);
1702*d83cc019SAndroid Build Coastguard Worker 	return (errno != EOPNOTSUPP);
1703*d83cc019SAndroid Build Coastguard Worker }
1704*d83cc019SAndroid Build Coastguard Worker 
1705*d83cc019SAndroid Build Coastguard Worker /*
1706*d83cc019SAndroid Build Coastguard Worker  * A small modeset API
1707*d83cc019SAndroid Build Coastguard Worker  */
1708*d83cc019SAndroid Build Coastguard Worker 
1709*d83cc019SAndroid Build Coastguard Worker #define LOG_SPACES		"    "
1710*d83cc019SAndroid Build Coastguard Worker #define LOG_N_SPACES		(sizeof(LOG_SPACES) - 1)
1711*d83cc019SAndroid Build Coastguard Worker 
1712*d83cc019SAndroid Build Coastguard Worker #define LOG_INDENT(d, section)				\
1713*d83cc019SAndroid Build Coastguard Worker 	do {						\
1714*d83cc019SAndroid Build Coastguard Worker 		igt_display_log(d, "%s {\n", section);	\
1715*d83cc019SAndroid Build Coastguard Worker 		igt_display_log_shift(d, 1);		\
1716*d83cc019SAndroid Build Coastguard Worker 	} while (0)
1717*d83cc019SAndroid Build Coastguard Worker #define LOG_UNINDENT(d)					\
1718*d83cc019SAndroid Build Coastguard Worker 	do {						\
1719*d83cc019SAndroid Build Coastguard Worker 		igt_display_log_shift(d, -1);		\
1720*d83cc019SAndroid Build Coastguard Worker 		igt_display_log(d, "}\n");		\
1721*d83cc019SAndroid Build Coastguard Worker 	} while (0)
1722*d83cc019SAndroid Build Coastguard Worker #define LOG(d, fmt, ...)	igt_display_log(d, fmt, ## __VA_ARGS__)
1723*d83cc019SAndroid Build Coastguard Worker 
1724*d83cc019SAndroid Build Coastguard Worker static void  __attribute__((format(printf, 2, 3)))
igt_display_log(igt_display_t * display,const char * fmt,...)1725*d83cc019SAndroid Build Coastguard Worker igt_display_log(igt_display_t *display, const char *fmt, ...)
1726*d83cc019SAndroid Build Coastguard Worker {
1727*d83cc019SAndroid Build Coastguard Worker 	va_list args;
1728*d83cc019SAndroid Build Coastguard Worker 	int i;
1729*d83cc019SAndroid Build Coastguard Worker 
1730*d83cc019SAndroid Build Coastguard Worker 	va_start(args, fmt);
1731*d83cc019SAndroid Build Coastguard Worker 	igt_debug("display: ");
1732*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->log_shift; i++)
1733*d83cc019SAndroid Build Coastguard Worker 		igt_debug("%s", LOG_SPACES);
1734*d83cc019SAndroid Build Coastguard Worker 	igt_vlog(IGT_LOG_DOMAIN, IGT_LOG_DEBUG, fmt, args);
1735*d83cc019SAndroid Build Coastguard Worker 	va_end(args);
1736*d83cc019SAndroid Build Coastguard Worker }
1737*d83cc019SAndroid Build Coastguard Worker 
igt_display_log_shift(igt_display_t * display,int shift)1738*d83cc019SAndroid Build Coastguard Worker static void igt_display_log_shift(igt_display_t *display, int shift)
1739*d83cc019SAndroid Build Coastguard Worker {
1740*d83cc019SAndroid Build Coastguard Worker 	display->log_shift += shift;
1741*d83cc019SAndroid Build Coastguard Worker 	igt_assert(display->log_shift >= 0);
1742*d83cc019SAndroid Build Coastguard Worker }
1743*d83cc019SAndroid Build Coastguard Worker 
igt_output_refresh(igt_output_t * output)1744*d83cc019SAndroid Build Coastguard Worker static void igt_output_refresh(igt_output_t *output)
1745*d83cc019SAndroid Build Coastguard Worker {
1746*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = output->display;
1747*d83cc019SAndroid Build Coastguard Worker 	unsigned long crtc_idx_mask = 0;
1748*d83cc019SAndroid Build Coastguard Worker 
1749*d83cc019SAndroid Build Coastguard Worker 	if (output->pending_pipe != PIPE_NONE)
1750*d83cc019SAndroid Build Coastguard Worker 		crtc_idx_mask = 1 << output->pending_pipe;
1751*d83cc019SAndroid Build Coastguard Worker 
1752*d83cc019SAndroid Build Coastguard Worker 	kmstest_free_connector_config(&output->config);
1753*d83cc019SAndroid Build Coastguard Worker 
1754*d83cc019SAndroid Build Coastguard Worker 	_kmstest_connector_config(display->drm_fd, output->id, crtc_idx_mask,
1755*d83cc019SAndroid Build Coastguard Worker 				  &output->config, output->force_reprobe);
1756*d83cc019SAndroid Build Coastguard Worker 	output->force_reprobe = false;
1757*d83cc019SAndroid Build Coastguard Worker 
1758*d83cc019SAndroid Build Coastguard Worker 	if (!output->name && output->config.connector) {
1759*d83cc019SAndroid Build Coastguard Worker 		drmModeConnector *c = output->config.connector;
1760*d83cc019SAndroid Build Coastguard Worker 
1761*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(asprintf(&output->name, "%s-%d", kmstest_connector_type_str(c->connector_type), c->connector_type_id),
1762*d83cc019SAndroid Build Coastguard Worker 			       -1);
1763*d83cc019SAndroid Build Coastguard Worker 	}
1764*d83cc019SAndroid Build Coastguard Worker 
1765*d83cc019SAndroid Build Coastguard Worker 	if (output->config.connector)
1766*d83cc019SAndroid Build Coastguard Worker 		igt_atomic_fill_connector_props(display, output,
1767*d83cc019SAndroid Build Coastguard Worker 			IGT_NUM_CONNECTOR_PROPS, igt_connector_prop_names);
1768*d83cc019SAndroid Build Coastguard Worker 
1769*d83cc019SAndroid Build Coastguard Worker 	LOG(display, "%s: Selecting pipe %s\n", output->name,
1770*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(output->pending_pipe));
1771*d83cc019SAndroid Build Coastguard Worker }
1772*d83cc019SAndroid Build Coastguard Worker 
1773*d83cc019SAndroid Build Coastguard Worker static int
igt_plane_set_property(igt_plane_t * plane,uint32_t prop_id,uint64_t value)1774*d83cc019SAndroid Build Coastguard Worker igt_plane_set_property(igt_plane_t *plane, uint32_t prop_id, uint64_t value)
1775*d83cc019SAndroid Build Coastguard Worker {
1776*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = plane->pipe;
1777*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
1778*d83cc019SAndroid Build Coastguard Worker 
1779*d83cc019SAndroid Build Coastguard Worker 	return drmModeObjectSetProperty(display->drm_fd, plane->drm_plane->plane_id,
1780*d83cc019SAndroid Build Coastguard Worker 				 DRM_MODE_OBJECT_PLANE, prop_id, value);
1781*d83cc019SAndroid Build Coastguard Worker }
1782*d83cc019SAndroid Build Coastguard Worker 
1783*d83cc019SAndroid Build Coastguard Worker /*
1784*d83cc019SAndroid Build Coastguard Worker  * Walk a plane's property list to determine its type.  If we don't
1785*d83cc019SAndroid Build Coastguard Worker  * find a type property, then the kernel doesn't support universal
1786*d83cc019SAndroid Build Coastguard Worker  * planes and we know the plane is an overlay/sprite.
1787*d83cc019SAndroid Build Coastguard Worker  */
get_drm_plane_type(int drm_fd,uint32_t plane_id)1788*d83cc019SAndroid Build Coastguard Worker static int get_drm_plane_type(int drm_fd, uint32_t plane_id)
1789*d83cc019SAndroid Build Coastguard Worker {
1790*d83cc019SAndroid Build Coastguard Worker 	uint64_t value;
1791*d83cc019SAndroid Build Coastguard Worker 	bool has_prop;
1792*d83cc019SAndroid Build Coastguard Worker 
1793*d83cc019SAndroid Build Coastguard Worker 	has_prop = kmstest_get_property(drm_fd, plane_id, DRM_MODE_OBJECT_PLANE,
1794*d83cc019SAndroid Build Coastguard Worker 					"type", NULL, &value, NULL);
1795*d83cc019SAndroid Build Coastguard Worker 	if (has_prop)
1796*d83cc019SAndroid Build Coastguard Worker 		return (int)value;
1797*d83cc019SAndroid Build Coastguard Worker 
1798*d83cc019SAndroid Build Coastguard Worker 	return DRM_PLANE_TYPE_OVERLAY;
1799*d83cc019SAndroid Build Coastguard Worker }
1800*d83cc019SAndroid Build Coastguard Worker 
igt_plane_reset(igt_plane_t * plane)1801*d83cc019SAndroid Build Coastguard Worker static void igt_plane_reset(igt_plane_t *plane)
1802*d83cc019SAndroid Build Coastguard Worker {
1803*d83cc019SAndroid Build Coastguard Worker 	/* Reset src coordinates. */
1804*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_X, 0);
1805*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_Y, 0);
1806*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_W, 0);
1807*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_H, 0);
1808*d83cc019SAndroid Build Coastguard Worker 
1809*d83cc019SAndroid Build Coastguard Worker 	/* Reset crtc coordinates. */
1810*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_X, 0);
1811*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_Y, 0);
1812*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_W, 0);
1813*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_H, 0);
1814*d83cc019SAndroid Build Coastguard Worker 
1815*d83cc019SAndroid Build Coastguard Worker 	/* Reset binding to fb and crtc. */
1816*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, 0);
1817*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, 0);
1818*d83cc019SAndroid Build Coastguard Worker 
1819*d83cc019SAndroid Build Coastguard Worker 	if (igt_plane_has_prop(plane, IGT_PLANE_COLOR_ENCODING))
1820*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_prop_enum(plane, IGT_PLANE_COLOR_ENCODING,
1821*d83cc019SAndroid Build Coastguard Worker 			igt_color_encoding_to_str(IGT_COLOR_YCBCR_BT601));
1822*d83cc019SAndroid Build Coastguard Worker 
1823*d83cc019SAndroid Build Coastguard Worker 	if (igt_plane_has_prop(plane, IGT_PLANE_COLOR_RANGE))
1824*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_prop_enum(plane, IGT_PLANE_COLOR_RANGE,
1825*d83cc019SAndroid Build Coastguard Worker 			igt_color_range_to_str(IGT_COLOR_YCBCR_LIMITED_RANGE));
1826*d83cc019SAndroid Build Coastguard Worker 
1827*d83cc019SAndroid Build Coastguard Worker 	/* Use default rotation */
1828*d83cc019SAndroid Build Coastguard Worker 	if (igt_plane_has_prop(plane, IGT_PLANE_ROTATION))
1829*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_prop_value(plane, IGT_PLANE_ROTATION, IGT_ROTATION_0);
1830*d83cc019SAndroid Build Coastguard Worker 
1831*d83cc019SAndroid Build Coastguard Worker 	if (igt_plane_has_prop(plane, IGT_PLANE_PIXEL_BLEND_MODE))
1832*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_prop_enum(plane, IGT_PLANE_PIXEL_BLEND_MODE, "Pre-multiplied");
1833*d83cc019SAndroid Build Coastguard Worker 
1834*d83cc019SAndroid Build Coastguard Worker 	if (igt_plane_has_prop(plane, IGT_PLANE_ALPHA))
1835*d83cc019SAndroid Build Coastguard Worker 	{
1836*d83cc019SAndroid Build Coastguard Worker 		uint64_t max_alpha = 0xffff;
1837*d83cc019SAndroid Build Coastguard Worker 		drmModePropertyPtr alpha_prop = drmModeGetProperty(
1838*d83cc019SAndroid Build Coastguard Worker 			plane->pipe->display->drm_fd,
1839*d83cc019SAndroid Build Coastguard Worker 			plane->props[IGT_PLANE_ALPHA]);
1840*d83cc019SAndroid Build Coastguard Worker 
1841*d83cc019SAndroid Build Coastguard Worker 		if (alpha_prop)
1842*d83cc019SAndroid Build Coastguard Worker 		{
1843*d83cc019SAndroid Build Coastguard Worker 			if (alpha_prop->flags & DRM_MODE_PROP_RANGE)
1844*d83cc019SAndroid Build Coastguard Worker 			{
1845*d83cc019SAndroid Build Coastguard Worker 				max_alpha = alpha_prop->values[1];
1846*d83cc019SAndroid Build Coastguard Worker 			}
1847*d83cc019SAndroid Build Coastguard Worker 
1848*d83cc019SAndroid Build Coastguard Worker 			drmModeFreeProperty(alpha_prop);
1849*d83cc019SAndroid Build Coastguard Worker 		}
1850*d83cc019SAndroid Build Coastguard Worker 
1851*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_prop_value(plane, IGT_PLANE_ALPHA, max_alpha);
1852*d83cc019SAndroid Build Coastguard Worker 	}
1853*d83cc019SAndroid Build Coastguard Worker 
1854*d83cc019SAndroid Build Coastguard Worker 
1855*d83cc019SAndroid Build Coastguard Worker 	igt_plane_clear_prop_changed(plane, IGT_PLANE_IN_FENCE_FD);
1856*d83cc019SAndroid Build Coastguard Worker 	plane->values[IGT_PLANE_IN_FENCE_FD] = ~0ULL;
1857*d83cc019SAndroid Build Coastguard Worker 	plane->gem_handle = 0;
1858*d83cc019SAndroid Build Coastguard Worker }
1859*d83cc019SAndroid Build Coastguard Worker 
igt_pipe_reset(igt_pipe_t * pipe)1860*d83cc019SAndroid Build Coastguard Worker static void igt_pipe_reset(igt_pipe_t *pipe)
1861*d83cc019SAndroid Build Coastguard Worker {
1862*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, 0);
1863*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 0);
1864*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_obj_clear_prop_changed(pipe, IGT_CRTC_OUT_FENCE_PTR);
1865*d83cc019SAndroid Build Coastguard Worker 
1866*d83cc019SAndroid Build Coastguard Worker 	if (igt_pipe_obj_has_prop(pipe, IGT_CRTC_CTM))
1867*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_CTM, 0);
1868*d83cc019SAndroid Build Coastguard Worker 
1869*d83cc019SAndroid Build Coastguard Worker 	if (igt_pipe_obj_has_prop(pipe, IGT_CRTC_GAMMA_LUT))
1870*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_LUT, 0);
1871*d83cc019SAndroid Build Coastguard Worker 
1872*d83cc019SAndroid Build Coastguard Worker 	if (igt_pipe_obj_has_prop(pipe, IGT_CRTC_DEGAMMA_LUT))
1873*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_DEGAMMA_LUT, 0);
1874*d83cc019SAndroid Build Coastguard Worker 
1875*d83cc019SAndroid Build Coastguard Worker 	pipe->out_fence_fd = -1;
1876*d83cc019SAndroid Build Coastguard Worker }
1877*d83cc019SAndroid Build Coastguard Worker 
igt_output_reset(igt_output_t * output)1878*d83cc019SAndroid Build Coastguard Worker static void igt_output_reset(igt_output_t *output)
1879*d83cc019SAndroid Build Coastguard Worker {
1880*d83cc019SAndroid Build Coastguard Worker 	output->pending_pipe = PIPE_NONE;
1881*d83cc019SAndroid Build Coastguard Worker 	output->use_override_mode = false;
1882*d83cc019SAndroid Build Coastguard Worker 	memset(&output->override_mode, 0, sizeof(output->override_mode));
1883*d83cc019SAndroid Build Coastguard Worker 
1884*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, 0);
1885*d83cc019SAndroid Build Coastguard Worker 
1886*d83cc019SAndroid Build Coastguard Worker 	if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
1887*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
1888*d83cc019SAndroid Build Coastguard Worker 					  BROADCAST_RGB_FULL);
1889*d83cc019SAndroid Build Coastguard Worker 
1890*d83cc019SAndroid Build Coastguard Worker 	if (igt_output_has_prop(output, IGT_CONNECTOR_CONTENT_PROTECTION))
1891*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_prop_enum(output, IGT_CONNECTOR_CONTENT_PROTECTION,
1892*d83cc019SAndroid Build Coastguard Worker 					 "Undesired");
1893*d83cc019SAndroid Build Coastguard Worker }
1894*d83cc019SAndroid Build Coastguard Worker 
1895*d83cc019SAndroid Build Coastguard Worker /**
1896*d83cc019SAndroid Build Coastguard Worker  * igt_display_reset:
1897*d83cc019SAndroid Build Coastguard Worker  * @display: a pointer to an #igt_display_t structure
1898*d83cc019SAndroid Build Coastguard Worker  *
1899*d83cc019SAndroid Build Coastguard Worker  * Reset basic pipes, connectors and planes on @display back to default values.
1900*d83cc019SAndroid Build Coastguard Worker  * In particular, the following properties will be reset:
1901*d83cc019SAndroid Build Coastguard Worker  *
1902*d83cc019SAndroid Build Coastguard Worker  * For outputs:
1903*d83cc019SAndroid Build Coastguard Worker  * - %IGT_CONNECTOR_CRTC_ID
1904*d83cc019SAndroid Build Coastguard Worker  * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
1905*d83cc019SAndroid Build Coastguard Worker  *   %IGT_CONNECTOR_CONTENT_PROTECTION (if applicable)
1906*d83cc019SAndroid Build Coastguard Worker  * - igt_output_override_mode() to default.
1907*d83cc019SAndroid Build Coastguard Worker  *
1908*d83cc019SAndroid Build Coastguard Worker  * For pipes:
1909*d83cc019SAndroid Build Coastguard Worker  * - %IGT_CRTC_MODE_ID (leaked)
1910*d83cc019SAndroid Build Coastguard Worker  * - %IGT_CRTC_ACTIVE
1911*d83cc019SAndroid Build Coastguard Worker  * - %IGT_CRTC_OUT_FENCE_PTR
1912*d83cc019SAndroid Build Coastguard Worker  *
1913*d83cc019SAndroid Build Coastguard Worker  * For planes:
1914*d83cc019SAndroid Build Coastguard Worker  * - %IGT_PLANE_SRC_*
1915*d83cc019SAndroid Build Coastguard Worker  * - %IGT_PLANE_CRTC_*
1916*d83cc019SAndroid Build Coastguard Worker  * - %IGT_PLANE_FB_ID
1917*d83cc019SAndroid Build Coastguard Worker  * - %IGT_PLANE_CRTC_ID
1918*d83cc019SAndroid Build Coastguard Worker  * - %IGT_PLANE_ROTATION
1919*d83cc019SAndroid Build Coastguard Worker  * - %IGT_PLANE_IN_FENCE_FD
1920*d83cc019SAndroid Build Coastguard Worker  */
igt_display_reset(igt_display_t * display)1921*d83cc019SAndroid Build Coastguard Worker void igt_display_reset(igt_display_t *display)
1922*d83cc019SAndroid Build Coastguard Worker {
1923*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
1924*d83cc019SAndroid Build Coastguard Worker 	int i;
1925*d83cc019SAndroid Build Coastguard Worker 
1926*d83cc019SAndroid Build Coastguard Worker 	/*
1927*d83cc019SAndroid Build Coastguard Worker 	 * Allow resetting rotation on all planes, which is normally
1928*d83cc019SAndroid Build Coastguard Worker 	 * prohibited on the primary and cursor plane for legacy commits.
1929*d83cc019SAndroid Build Coastguard Worker 	 */
1930*d83cc019SAndroid Build Coastguard Worker 	display->first_commit = true;
1931*d83cc019SAndroid Build Coastguard Worker 
1932*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe(display, pipe) {
1933*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_t *pipe_obj = &display->pipes[pipe];
1934*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane;
1935*d83cc019SAndroid Build Coastguard Worker 
1936*d83cc019SAndroid Build Coastguard Worker 		for_each_plane_on_pipe(display, pipe, plane)
1937*d83cc019SAndroid Build Coastguard Worker 			igt_plane_reset(plane);
1938*d83cc019SAndroid Build Coastguard Worker 
1939*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_reset(pipe_obj);
1940*d83cc019SAndroid Build Coastguard Worker 	}
1941*d83cc019SAndroid Build Coastguard Worker 
1942*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++) {
1943*d83cc019SAndroid Build Coastguard Worker 		igt_output_t *output = &display->outputs[i];
1944*d83cc019SAndroid Build Coastguard Worker 
1945*d83cc019SAndroid Build Coastguard Worker 		igt_output_reset(output);
1946*d83cc019SAndroid Build Coastguard Worker 	}
1947*d83cc019SAndroid Build Coastguard Worker }
1948*d83cc019SAndroid Build Coastguard Worker 
1949*d83cc019SAndroid Build Coastguard Worker static void igt_fill_plane_format_mod(igt_display_t *display, igt_plane_t *plane);
1950*d83cc019SAndroid Build Coastguard Worker static void igt_fill_display_format_mod(igt_display_t *display);
1951*d83cc019SAndroid Build Coastguard Worker 
1952*d83cc019SAndroid Build Coastguard Worker /**
1953*d83cc019SAndroid Build Coastguard Worker  * igt_display_require:
1954*d83cc019SAndroid Build Coastguard Worker  * @display: a pointer to an #igt_display_t structure
1955*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: a drm file descriptor
1956*d83cc019SAndroid Build Coastguard Worker  *
1957*d83cc019SAndroid Build Coastguard Worker  * Initialize @display and allocate the various resources required. Use
1958*d83cc019SAndroid Build Coastguard Worker  * #igt_display_fini to release the resources when they are no longer required.
1959*d83cc019SAndroid Build Coastguard Worker  *
1960*d83cc019SAndroid Build Coastguard Worker  * This function automatically skips if the kernel driver doesn't support any
1961*d83cc019SAndroid Build Coastguard Worker  * CRTC or outputs.
1962*d83cc019SAndroid Build Coastguard Worker  */
igt_display_require(igt_display_t * display,int drm_fd)1963*d83cc019SAndroid Build Coastguard Worker void igt_display_require(igt_display_t *display, int drm_fd)
1964*d83cc019SAndroid Build Coastguard Worker {
1965*d83cc019SAndroid Build Coastguard Worker 	drmModeRes *resources;
1966*d83cc019SAndroid Build Coastguard Worker 	drmModePlaneRes *plane_resources;
1967*d83cc019SAndroid Build Coastguard Worker 	int i;
1968*d83cc019SAndroid Build Coastguard Worker 
1969*d83cc019SAndroid Build Coastguard Worker 	memset(display, 0, sizeof(igt_display_t));
1970*d83cc019SAndroid Build Coastguard Worker 
1971*d83cc019SAndroid Build Coastguard Worker 	LOG_INDENT(display, "init");
1972*d83cc019SAndroid Build Coastguard Worker 
1973*d83cc019SAndroid Build Coastguard Worker 	display->drm_fd = drm_fd;
1974*d83cc019SAndroid Build Coastguard Worker 
1975*d83cc019SAndroid Build Coastguard Worker 	resources = drmModeGetResources(display->drm_fd);
1976*d83cc019SAndroid Build Coastguard Worker 	if (!resources)
1977*d83cc019SAndroid Build Coastguard Worker 		goto out;
1978*d83cc019SAndroid Build Coastguard Worker 
1979*d83cc019SAndroid Build Coastguard Worker 	/*
1980*d83cc019SAndroid Build Coastguard Worker 	 * We cache the number of pipes, that number is a physical limit of the
1981*d83cc019SAndroid Build Coastguard Worker 	 * hardware and cannot change of time (for now, at least).
1982*d83cc019SAndroid Build Coastguard Worker 	 */
1983*d83cc019SAndroid Build Coastguard Worker 	display->n_pipes = resources->count_crtcs;
1984*d83cc019SAndroid Build Coastguard Worker 	display->pipes = calloc(sizeof(igt_pipe_t), display->n_pipes);
1985*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(display->pipes, "Failed to allocate memory for %d pipes\n", display->n_pipes);
1986*d83cc019SAndroid Build Coastguard Worker 
1987*d83cc019SAndroid Build Coastguard Worker 	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
1988*d83cc019SAndroid Build Coastguard Worker 	if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
1989*d83cc019SAndroid Build Coastguard Worker 		display->is_atomic = 1;
1990*d83cc019SAndroid Build Coastguard Worker 
1991*d83cc019SAndroid Build Coastguard Worker 	plane_resources = drmModeGetPlaneResources(display->drm_fd);
1992*d83cc019SAndroid Build Coastguard Worker 	igt_assert(plane_resources);
1993*d83cc019SAndroid Build Coastguard Worker 
1994*d83cc019SAndroid Build Coastguard Worker 	display->n_planes = plane_resources->count_planes;
1995*d83cc019SAndroid Build Coastguard Worker 	display->planes = calloc(sizeof(igt_plane_t), display->n_planes);
1996*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(display->planes, "Failed to allocate memory for %d planes\n", display->n_planes);
1997*d83cc019SAndroid Build Coastguard Worker 
1998*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < plane_resources->count_planes; ++i) {
1999*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane = &display->planes[i];
2000*d83cc019SAndroid Build Coastguard Worker 		uint32_t id = plane_resources->planes[i];
2001*d83cc019SAndroid Build Coastguard Worker 
2002*d83cc019SAndroid Build Coastguard Worker 		plane->drm_plane = drmModeGetPlane(display->drm_fd, id);
2003*d83cc019SAndroid Build Coastguard Worker 		igt_assert(plane->drm_plane);
2004*d83cc019SAndroid Build Coastguard Worker 
2005*d83cc019SAndroid Build Coastguard Worker 		plane->type = get_drm_plane_type(display->drm_fd, id);
2006*d83cc019SAndroid Build Coastguard Worker 
2007*d83cc019SAndroid Build Coastguard Worker 		/*
2008*d83cc019SAndroid Build Coastguard Worker 		 * TODO: Fill in the rest of the plane properties here and
2009*d83cc019SAndroid Build Coastguard Worker 		 * move away from the plane per pipe model to align closer
2010*d83cc019SAndroid Build Coastguard Worker 		 * to the DRM KMS model.
2011*d83cc019SAndroid Build Coastguard Worker 		 */
2012*d83cc019SAndroid Build Coastguard Worker 	}
2013*d83cc019SAndroid Build Coastguard Worker 
2014*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe(display, i) {
2015*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_t *pipe = &display->pipes[i];
2016*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane;
2017*d83cc019SAndroid Build Coastguard Worker 		int p = 1;
2018*d83cc019SAndroid Build Coastguard Worker 		int j, type;
2019*d83cc019SAndroid Build Coastguard Worker 		uint8_t last_plane = 0, n_planes = 0;
2020*d83cc019SAndroid Build Coastguard Worker 
2021*d83cc019SAndroid Build Coastguard Worker 		pipe->crtc_id = resources->crtcs[i];
2022*d83cc019SAndroid Build Coastguard Worker 		pipe->display = display;
2023*d83cc019SAndroid Build Coastguard Worker 		pipe->pipe = i;
2024*d83cc019SAndroid Build Coastguard Worker 		pipe->plane_cursor = -1;
2025*d83cc019SAndroid Build Coastguard Worker 		pipe->plane_primary = -1;
2026*d83cc019SAndroid Build Coastguard Worker 		pipe->planes = NULL;
2027*d83cc019SAndroid Build Coastguard Worker 
2028*d83cc019SAndroid Build Coastguard Worker 		igt_fill_pipe_props(display, pipe, IGT_NUM_CRTC_PROPS, igt_crtc_prop_names);
2029*d83cc019SAndroid Build Coastguard Worker 
2030*d83cc019SAndroid Build Coastguard Worker 		/* count number of valid planes */
2031*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < display->n_planes; j++) {
2032*d83cc019SAndroid Build Coastguard Worker 			drmModePlane *drm_plane = display->planes[j].drm_plane;
2033*d83cc019SAndroid Build Coastguard Worker 			igt_assert(drm_plane);
2034*d83cc019SAndroid Build Coastguard Worker 
2035*d83cc019SAndroid Build Coastguard Worker 			if (drm_plane->possible_crtcs & (1 << i))
2036*d83cc019SAndroid Build Coastguard Worker 				n_planes++;
2037*d83cc019SAndroid Build Coastguard Worker 		}
2038*d83cc019SAndroid Build Coastguard Worker 
2039*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lt(0, n_planes);
2040*d83cc019SAndroid Build Coastguard Worker 		pipe->planes = calloc(sizeof(igt_plane_t), n_planes);
2041*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(pipe->planes, "Failed to allocate memory for %d planes\n", n_planes);
2042*d83cc019SAndroid Build Coastguard Worker 		last_plane = n_planes - 1;
2043*d83cc019SAndroid Build Coastguard Worker 
2044*d83cc019SAndroid Build Coastguard Worker 		/* add the planes that can be used with that pipe */
2045*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < display->n_planes; j++) {
2046*d83cc019SAndroid Build Coastguard Worker 			igt_plane_t *global_plane = &display->planes[j];
2047*d83cc019SAndroid Build Coastguard Worker 			drmModePlane *drm_plane = global_plane->drm_plane;
2048*d83cc019SAndroid Build Coastguard Worker 
2049*d83cc019SAndroid Build Coastguard Worker 			if (!(drm_plane->possible_crtcs & (1 << i)))
2050*d83cc019SAndroid Build Coastguard Worker 				continue;
2051*d83cc019SAndroid Build Coastguard Worker 
2052*d83cc019SAndroid Build Coastguard Worker 			type = global_plane->type;
2053*d83cc019SAndroid Build Coastguard Worker 
2054*d83cc019SAndroid Build Coastguard Worker 			if (type == DRM_PLANE_TYPE_PRIMARY && pipe->plane_primary == -1) {
2055*d83cc019SAndroid Build Coastguard Worker 				plane = &pipe->planes[0];
2056*d83cc019SAndroid Build Coastguard Worker 				plane->index = 0;
2057*d83cc019SAndroid Build Coastguard Worker 				pipe->plane_primary = 0;
2058*d83cc019SAndroid Build Coastguard Worker 			} else if (type == DRM_PLANE_TYPE_CURSOR && pipe->plane_cursor == -1) {
2059*d83cc019SAndroid Build Coastguard Worker 				plane = &pipe->planes[last_plane];
2060*d83cc019SAndroid Build Coastguard Worker 				plane->index = last_plane;
2061*d83cc019SAndroid Build Coastguard Worker 				pipe->plane_cursor = last_plane;
2062*d83cc019SAndroid Build Coastguard Worker 				display->has_cursor_plane = true;
2063*d83cc019SAndroid Build Coastguard Worker 			} else {
2064*d83cc019SAndroid Build Coastguard Worker 				plane = &pipe->planes[p];
2065*d83cc019SAndroid Build Coastguard Worker 				plane->index = p++;
2066*d83cc019SAndroid Build Coastguard Worker 			}
2067*d83cc019SAndroid Build Coastguard Worker 
2068*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(plane->index < n_planes, "n_planes < plane->index failed\n");
2069*d83cc019SAndroid Build Coastguard Worker 			plane->type = type;
2070*d83cc019SAndroid Build Coastguard Worker 			plane->pipe = pipe;
2071*d83cc019SAndroid Build Coastguard Worker 			plane->drm_plane = drm_plane;
2072*d83cc019SAndroid Build Coastguard Worker 			plane->values[IGT_PLANE_IN_FENCE_FD] = ~0ULL;
2073*d83cc019SAndroid Build Coastguard Worker 			plane->ref = global_plane;
2074*d83cc019SAndroid Build Coastguard Worker 
2075*d83cc019SAndroid Build Coastguard Worker 			/*
2076*d83cc019SAndroid Build Coastguard Worker 			 * HACK: point the global plane to the first pipe that
2077*d83cc019SAndroid Build Coastguard Worker 			 * it can go on.
2078*d83cc019SAndroid Build Coastguard Worker 			 */
2079*d83cc019SAndroid Build Coastguard Worker 			if (!global_plane->ref)
2080*d83cc019SAndroid Build Coastguard Worker 				igt_plane_set_pipe(plane, pipe);
2081*d83cc019SAndroid Build Coastguard Worker 
2082*d83cc019SAndroid Build Coastguard Worker 			igt_fill_plane_props(display, plane, IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
2083*d83cc019SAndroid Build Coastguard Worker 
2084*d83cc019SAndroid Build Coastguard Worker 			igt_fill_plane_format_mod(display, plane);
2085*d83cc019SAndroid Build Coastguard Worker 		}
2086*d83cc019SAndroid Build Coastguard Worker 
2087*d83cc019SAndroid Build Coastguard Worker 		/*
2088*d83cc019SAndroid Build Coastguard Worker 		 * At the bare minimum, we should expect to have a primary
2089*d83cc019SAndroid Build Coastguard Worker 		 * plane, and it must be in slot 0.
2090*d83cc019SAndroid Build Coastguard Worker 		 */
2091*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(pipe->plane_primary, 0);
2092*d83cc019SAndroid Build Coastguard Worker 
2093*d83cc019SAndroid Build Coastguard Worker 		/* Check that we filled every slot exactly once */
2094*d83cc019SAndroid Build Coastguard Worker 		if (display->has_cursor_plane)
2095*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(p, last_plane);
2096*d83cc019SAndroid Build Coastguard Worker 		else
2097*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(p, n_planes);
2098*d83cc019SAndroid Build Coastguard Worker 
2099*d83cc019SAndroid Build Coastguard Worker 		pipe->n_planes = n_planes;
2100*d83cc019SAndroid Build Coastguard Worker 	}
2101*d83cc019SAndroid Build Coastguard Worker 
2102*d83cc019SAndroid Build Coastguard Worker 	igt_fill_display_format_mod(display);
2103*d83cc019SAndroid Build Coastguard Worker 
2104*d83cc019SAndroid Build Coastguard Worker 	/*
2105*d83cc019SAndroid Build Coastguard Worker 	 * The number of connectors is set, so we just initialize the outputs
2106*d83cc019SAndroid Build Coastguard Worker 	 * array in _init(). This may change when we need dynamic connectors
2107*d83cc019SAndroid Build Coastguard Worker 	 * (say DisplayPort MST).
2108*d83cc019SAndroid Build Coastguard Worker 	 */
2109*d83cc019SAndroid Build Coastguard Worker 	display->n_outputs = resources->count_connectors;
2110*d83cc019SAndroid Build Coastguard Worker 	display->outputs = calloc(display->n_outputs, sizeof(igt_output_t));
2111*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(display->outputs, "Failed to allocate memory for %d outputs\n", display->n_outputs);
2112*d83cc019SAndroid Build Coastguard Worker 
2113*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++) {
2114*d83cc019SAndroid Build Coastguard Worker 		igt_output_t *output = &display->outputs[i];
2115*d83cc019SAndroid Build Coastguard Worker 		drmModeConnector *connector;
2116*d83cc019SAndroid Build Coastguard Worker 
2117*d83cc019SAndroid Build Coastguard Worker 		/*
2118*d83cc019SAndroid Build Coastguard Worker 		 * We don't assign each output a pipe unless
2119*d83cc019SAndroid Build Coastguard Worker 		 * a pipe is set with igt_output_set_pipe().
2120*d83cc019SAndroid Build Coastguard Worker 		 */
2121*d83cc019SAndroid Build Coastguard Worker 		output->pending_pipe = PIPE_NONE;
2122*d83cc019SAndroid Build Coastguard Worker 		output->id = resources->connectors[i];
2123*d83cc019SAndroid Build Coastguard Worker 		output->display = display;
2124*d83cc019SAndroid Build Coastguard Worker 
2125*d83cc019SAndroid Build Coastguard Worker 		igt_output_refresh(output);
2126*d83cc019SAndroid Build Coastguard Worker 
2127*d83cc019SAndroid Build Coastguard Worker 		connector = output->config.connector;
2128*d83cc019SAndroid Build Coastguard Worker 		if (connector && (!connector->count_modes ||
2129*d83cc019SAndroid Build Coastguard Worker 		    connector->connection == DRM_MODE_UNKNOWNCONNECTION)) {
2130*d83cc019SAndroid Build Coastguard Worker 			output->force_reprobe = true;
2131*d83cc019SAndroid Build Coastguard Worker 			igt_output_refresh(output);
2132*d83cc019SAndroid Build Coastguard Worker 		}
2133*d83cc019SAndroid Build Coastguard Worker 	}
2134*d83cc019SAndroid Build Coastguard Worker 
2135*d83cc019SAndroid Build Coastguard Worker 	drmModeFreePlaneResources(plane_resources);
2136*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeResources(resources);
2137*d83cc019SAndroid Build Coastguard Worker 
2138*d83cc019SAndroid Build Coastguard Worker 	/* Set reasonable default values for every object in the display. */
2139*d83cc019SAndroid Build Coastguard Worker 	igt_display_reset(display);
2140*d83cc019SAndroid Build Coastguard Worker 
2141*d83cc019SAndroid Build Coastguard Worker out:
2142*d83cc019SAndroid Build Coastguard Worker 	LOG_UNINDENT(display);
2143*d83cc019SAndroid Build Coastguard Worker 
2144*d83cc019SAndroid Build Coastguard Worker 	if (display->n_pipes && display->n_outputs)
2145*d83cc019SAndroid Build Coastguard Worker 		igt_enable_connectors(drm_fd);
2146*d83cc019SAndroid Build Coastguard Worker 	else
2147*d83cc019SAndroid Build Coastguard Worker 		igt_skip("No KMS driver or no outputs, pipes: %d, outputs: %d\n",
2148*d83cc019SAndroid Build Coastguard Worker 			 display->n_pipes, display->n_outputs);
2149*d83cc019SAndroid Build Coastguard Worker }
2150*d83cc019SAndroid Build Coastguard Worker 
2151*d83cc019SAndroid Build Coastguard Worker /**
2152*d83cc019SAndroid Build Coastguard Worker  * igt_display_get_n_pipes:
2153*d83cc019SAndroid Build Coastguard Worker  * @display: A pointer to an #igt_display_t structure
2154*d83cc019SAndroid Build Coastguard Worker  *
2155*d83cc019SAndroid Build Coastguard Worker  * Returns total number of pipes for the given @display
2156*d83cc019SAndroid Build Coastguard Worker  */
igt_display_get_n_pipes(igt_display_t * display)2157*d83cc019SAndroid Build Coastguard Worker int igt_display_get_n_pipes(igt_display_t *display)
2158*d83cc019SAndroid Build Coastguard Worker {
2159*d83cc019SAndroid Build Coastguard Worker 	return display->n_pipes;
2160*d83cc019SAndroid Build Coastguard Worker }
2161*d83cc019SAndroid Build Coastguard Worker 
2162*d83cc019SAndroid Build Coastguard Worker /**
2163*d83cc019SAndroid Build Coastguard Worker  * igt_display_require_output:
2164*d83cc019SAndroid Build Coastguard Worker  * @display: A pointer to an #igt_display_t structure
2165*d83cc019SAndroid Build Coastguard Worker  *
2166*d83cc019SAndroid Build Coastguard Worker  * Checks whether there's a valid @pipe/@output combination for the given @display
2167*d83cc019SAndroid Build Coastguard Worker  * Skips test if a valid combination of @pipe and @output is not found
2168*d83cc019SAndroid Build Coastguard Worker  */
igt_display_require_output(igt_display_t * display)2169*d83cc019SAndroid Build Coastguard Worker void igt_display_require_output(igt_display_t *display)
2170*d83cc019SAndroid Build Coastguard Worker {
2171*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
2172*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
2173*d83cc019SAndroid Build Coastguard Worker 
2174*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe_with_valid_output(display, pipe, output)
2175*d83cc019SAndroid Build Coastguard Worker 		return;
2176*d83cc019SAndroid Build Coastguard Worker 
2177*d83cc019SAndroid Build Coastguard Worker 	igt_skip("No valid crtc/connector combinations found.\n");
2178*d83cc019SAndroid Build Coastguard Worker }
2179*d83cc019SAndroid Build Coastguard Worker 
2180*d83cc019SAndroid Build Coastguard Worker /**
2181*d83cc019SAndroid Build Coastguard Worker  * igt_display_require_output_on_pipe:
2182*d83cc019SAndroid Build Coastguard Worker  * @display: A pointer to an #igt_display_t structure
2183*d83cc019SAndroid Build Coastguard Worker  * @pipe: Display pipe
2184*d83cc019SAndroid Build Coastguard Worker  *
2185*d83cc019SAndroid Build Coastguard Worker  * Checks whether there's a valid @pipe/@output combination for the given @display and @pipe
2186*d83cc019SAndroid Build Coastguard Worker  * Skips test if a valid @pipe is not found
2187*d83cc019SAndroid Build Coastguard Worker  */
igt_display_require_output_on_pipe(igt_display_t * display,enum pipe pipe)2188*d83cc019SAndroid Build Coastguard Worker void igt_display_require_output_on_pipe(igt_display_t *display, enum pipe pipe)
2189*d83cc019SAndroid Build Coastguard Worker {
2190*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
2191*d83cc019SAndroid Build Coastguard Worker 
2192*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_f(pipe >= igt_display_get_n_pipes(display),
2193*d83cc019SAndroid Build Coastguard Worker 		      "Pipe %s does not exist.\n", kmstest_pipe_name(pipe));
2194*d83cc019SAndroid Build Coastguard Worker 
2195*d83cc019SAndroid Build Coastguard Worker 	for_each_valid_output_on_pipe(display, pipe, output)
2196*d83cc019SAndroid Build Coastguard Worker 		return;
2197*d83cc019SAndroid Build Coastguard Worker 
2198*d83cc019SAndroid Build Coastguard Worker 	igt_skip("No valid connector found on pipe %s\n", kmstest_pipe_name(pipe));
2199*d83cc019SAndroid Build Coastguard Worker }
2200*d83cc019SAndroid Build Coastguard Worker 
2201*d83cc019SAndroid Build Coastguard Worker /**
2202*d83cc019SAndroid Build Coastguard Worker  * igt_output_from_connector:
2203*d83cc019SAndroid Build Coastguard Worker  * @display: a pointer to an #igt_display_t structure
2204*d83cc019SAndroid Build Coastguard Worker  * @connector: a pointer to a drmModeConnector
2205*d83cc019SAndroid Build Coastguard Worker  *
2206*d83cc019SAndroid Build Coastguard Worker  * Finds the output corresponding to the given connector
2207*d83cc019SAndroid Build Coastguard Worker  *
2208*d83cc019SAndroid Build Coastguard Worker  * Returns: A #igt_output_t structure configured to use the connector, or NULL
2209*d83cc019SAndroid Build Coastguard Worker  * if none was found
2210*d83cc019SAndroid Build Coastguard Worker  */
igt_output_from_connector(igt_display_t * display,drmModeConnector * connector)2211*d83cc019SAndroid Build Coastguard Worker igt_output_t *igt_output_from_connector(igt_display_t *display,
2212*d83cc019SAndroid Build Coastguard Worker 					drmModeConnector *connector)
2213*d83cc019SAndroid Build Coastguard Worker {
2214*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output, *found = NULL;
2215*d83cc019SAndroid Build Coastguard Worker 	int i;
2216*d83cc019SAndroid Build Coastguard Worker 
2217*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++) {
2218*d83cc019SAndroid Build Coastguard Worker 		output = &display->outputs[i];
2219*d83cc019SAndroid Build Coastguard Worker 
2220*d83cc019SAndroid Build Coastguard Worker 		if (output->config.connector &&
2221*d83cc019SAndroid Build Coastguard Worker 		    output->config.connector->connector_id ==
2222*d83cc019SAndroid Build Coastguard Worker 		    connector->connector_id) {
2223*d83cc019SAndroid Build Coastguard Worker 			found = output;
2224*d83cc019SAndroid Build Coastguard Worker 			break;
2225*d83cc019SAndroid Build Coastguard Worker 		}
2226*d83cc019SAndroid Build Coastguard Worker 	}
2227*d83cc019SAndroid Build Coastguard Worker 
2228*d83cc019SAndroid Build Coastguard Worker 	return found;
2229*d83cc019SAndroid Build Coastguard Worker }
2230*d83cc019SAndroid Build Coastguard Worker 
igt_std_1024_mode_get(void)2231*d83cc019SAndroid Build Coastguard Worker const drmModeModeInfo *igt_std_1024_mode_get(void)
2232*d83cc019SAndroid Build Coastguard Worker {
2233*d83cc019SAndroid Build Coastguard Worker 	static const drmModeModeInfo std_1024_mode = {
2234*d83cc019SAndroid Build Coastguard Worker 		.clock = 65000,
2235*d83cc019SAndroid Build Coastguard Worker 		.hdisplay = 1024,
2236*d83cc019SAndroid Build Coastguard Worker 		.hsync_start = 1048,
2237*d83cc019SAndroid Build Coastguard Worker 		.hsync_end = 1184,
2238*d83cc019SAndroid Build Coastguard Worker 		.htotal = 1344,
2239*d83cc019SAndroid Build Coastguard Worker 		.hskew = 0,
2240*d83cc019SAndroid Build Coastguard Worker 		.vdisplay = 768,
2241*d83cc019SAndroid Build Coastguard Worker 		.vsync_start = 771,
2242*d83cc019SAndroid Build Coastguard Worker 		.vsync_end = 777,
2243*d83cc019SAndroid Build Coastguard Worker 		.vtotal = 806,
2244*d83cc019SAndroid Build Coastguard Worker 		.vscan = 0,
2245*d83cc019SAndroid Build Coastguard Worker 		.vrefresh = 60,
2246*d83cc019SAndroid Build Coastguard Worker 		.flags = 0xA,
2247*d83cc019SAndroid Build Coastguard Worker 		.type = 0x40,
2248*d83cc019SAndroid Build Coastguard Worker 		.name = "Custom 1024x768",
2249*d83cc019SAndroid Build Coastguard Worker 	};
2250*d83cc019SAndroid Build Coastguard Worker 
2251*d83cc019SAndroid Build Coastguard Worker 	return &std_1024_mode;
2252*d83cc019SAndroid Build Coastguard Worker }
2253*d83cc019SAndroid Build Coastguard Worker 
igt_pipe_fini(igt_pipe_t * pipe)2254*d83cc019SAndroid Build Coastguard Worker static void igt_pipe_fini(igt_pipe_t *pipe)
2255*d83cc019SAndroid Build Coastguard Worker {
2256*d83cc019SAndroid Build Coastguard Worker 	free(pipe->planes);
2257*d83cc019SAndroid Build Coastguard Worker 	pipe->planes = NULL;
2258*d83cc019SAndroid Build Coastguard Worker 
2259*d83cc019SAndroid Build Coastguard Worker 	if (pipe->out_fence_fd != -1)
2260*d83cc019SAndroid Build Coastguard Worker 		close(pipe->out_fence_fd);
2261*d83cc019SAndroid Build Coastguard Worker }
2262*d83cc019SAndroid Build Coastguard Worker 
igt_output_fini(igt_output_t * output)2263*d83cc019SAndroid Build Coastguard Worker static void igt_output_fini(igt_output_t *output)
2264*d83cc019SAndroid Build Coastguard Worker {
2265*d83cc019SAndroid Build Coastguard Worker 	kmstest_free_connector_config(&output->config);
2266*d83cc019SAndroid Build Coastguard Worker 	free(output->name);
2267*d83cc019SAndroid Build Coastguard Worker 	output->name = NULL;
2268*d83cc019SAndroid Build Coastguard Worker }
2269*d83cc019SAndroid Build Coastguard Worker 
2270*d83cc019SAndroid Build Coastguard Worker /**
2271*d83cc019SAndroid Build Coastguard Worker  * igt_display_fini:
2272*d83cc019SAndroid Build Coastguard Worker  * @display: a pointer to an #igt_display_t structure
2273*d83cc019SAndroid Build Coastguard Worker  *
2274*d83cc019SAndroid Build Coastguard Worker  * Release any resources associated with @display. This does not free @display
2275*d83cc019SAndroid Build Coastguard Worker  * itself.
2276*d83cc019SAndroid Build Coastguard Worker  */
igt_display_fini(igt_display_t * display)2277*d83cc019SAndroid Build Coastguard Worker void igt_display_fini(igt_display_t *display)
2278*d83cc019SAndroid Build Coastguard Worker {
2279*d83cc019SAndroid Build Coastguard Worker 	int i;
2280*d83cc019SAndroid Build Coastguard Worker 
2281*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_planes; ++i) {
2282*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane = &display->planes[i];
2283*d83cc019SAndroid Build Coastguard Worker 
2284*d83cc019SAndroid Build Coastguard Worker 		if (plane->drm_plane) {
2285*d83cc019SAndroid Build Coastguard Worker 			drmModeFreePlane(plane->drm_plane);
2286*d83cc019SAndroid Build Coastguard Worker 			plane->drm_plane = NULL;
2287*d83cc019SAndroid Build Coastguard Worker 		}
2288*d83cc019SAndroid Build Coastguard Worker 	}
2289*d83cc019SAndroid Build Coastguard Worker 
2290*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_pipes; i++)
2291*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_fini(&display->pipes[i]);
2292*d83cc019SAndroid Build Coastguard Worker 
2293*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++)
2294*d83cc019SAndroid Build Coastguard Worker 		igt_output_fini(&display->outputs[i]);
2295*d83cc019SAndroid Build Coastguard Worker 	free(display->outputs);
2296*d83cc019SAndroid Build Coastguard Worker 	display->outputs = NULL;
2297*d83cc019SAndroid Build Coastguard Worker 	free(display->pipes);
2298*d83cc019SAndroid Build Coastguard Worker 	display->pipes = NULL;
2299*d83cc019SAndroid Build Coastguard Worker 	free(display->planes);
2300*d83cc019SAndroid Build Coastguard Worker 	display->planes = NULL;
2301*d83cc019SAndroid Build Coastguard Worker }
2302*d83cc019SAndroid Build Coastguard Worker 
igt_display_refresh(igt_display_t * display)2303*d83cc019SAndroid Build Coastguard Worker static void igt_display_refresh(igt_display_t *display)
2304*d83cc019SAndroid Build Coastguard Worker {
2305*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
2306*d83cc019SAndroid Build Coastguard Worker 	int i;
2307*d83cc019SAndroid Build Coastguard Worker 
2308*d83cc019SAndroid Build Coastguard Worker 	unsigned long pipes_in_use = 0;
2309*d83cc019SAndroid Build Coastguard Worker 
2310*d83cc019SAndroid Build Coastguard Worker        /* Check that two outputs aren't trying to use the same pipe */
2311*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++) {
2312*d83cc019SAndroid Build Coastguard Worker 		output = &display->outputs[i];
2313*d83cc019SAndroid Build Coastguard Worker 
2314*d83cc019SAndroid Build Coastguard Worker 		if (output->pending_pipe != PIPE_NONE) {
2315*d83cc019SAndroid Build Coastguard Worker 			if (pipes_in_use & (1 << output->pending_pipe))
2316*d83cc019SAndroid Build Coastguard Worker 				goto report_dup;
2317*d83cc019SAndroid Build Coastguard Worker 
2318*d83cc019SAndroid Build Coastguard Worker 			pipes_in_use |= 1 << output->pending_pipe;
2319*d83cc019SAndroid Build Coastguard Worker 		}
2320*d83cc019SAndroid Build Coastguard Worker 
2321*d83cc019SAndroid Build Coastguard Worker 		if (output->force_reprobe)
2322*d83cc019SAndroid Build Coastguard Worker 			igt_output_refresh(output);
2323*d83cc019SAndroid Build Coastguard Worker 	}
2324*d83cc019SAndroid Build Coastguard Worker 
2325*d83cc019SAndroid Build Coastguard Worker 	return;
2326*d83cc019SAndroid Build Coastguard Worker 
2327*d83cc019SAndroid Build Coastguard Worker report_dup:
2328*d83cc019SAndroid Build Coastguard Worker 	for (; i > 0; i--) {
2329*d83cc019SAndroid Build Coastguard Worker 		igt_output_t *b = &display->outputs[i - 1];
2330*d83cc019SAndroid Build Coastguard Worker 
2331*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(output->pending_pipe !=
2332*d83cc019SAndroid Build Coastguard Worker 			     b->pending_pipe,
2333*d83cc019SAndroid Build Coastguard Worker 			     "%s and %s are both trying to use pipe %s\n",
2334*d83cc019SAndroid Build Coastguard Worker 			     igt_output_name(output), igt_output_name(b),
2335*d83cc019SAndroid Build Coastguard Worker 			     kmstest_pipe_name(output->pending_pipe));
2336*d83cc019SAndroid Build Coastguard Worker 	}
2337*d83cc019SAndroid Build Coastguard Worker }
2338*d83cc019SAndroid Build Coastguard Worker 
igt_output_get_driving_pipe(igt_output_t * output)2339*d83cc019SAndroid Build Coastguard Worker static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
2340*d83cc019SAndroid Build Coastguard Worker {
2341*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = output->display;
2342*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
2343*d83cc019SAndroid Build Coastguard Worker 
2344*d83cc019SAndroid Build Coastguard Worker 	if (output->pending_pipe == PIPE_NONE) {
2345*d83cc019SAndroid Build Coastguard Worker 		/*
2346*d83cc019SAndroid Build Coastguard Worker 		 * The user hasn't specified a pipe to use, return none.
2347*d83cc019SAndroid Build Coastguard Worker 		 */
2348*d83cc019SAndroid Build Coastguard Worker 		return NULL;
2349*d83cc019SAndroid Build Coastguard Worker 	} else {
2350*d83cc019SAndroid Build Coastguard Worker 		/*
2351*d83cc019SAndroid Build Coastguard Worker 		 * Otherwise, return the pending pipe (ie the pipe that should
2352*d83cc019SAndroid Build Coastguard Worker 		 * drive this output after the commit()
2353*d83cc019SAndroid Build Coastguard Worker 		 */
2354*d83cc019SAndroid Build Coastguard Worker 		pipe = output->pending_pipe;
2355*d83cc019SAndroid Build Coastguard Worker 	}
2356*d83cc019SAndroid Build Coastguard Worker 
2357*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pipe >= 0 && pipe < display->n_pipes);
2358*d83cc019SAndroid Build Coastguard Worker 
2359*d83cc019SAndroid Build Coastguard Worker 	return &display->pipes[pipe];
2360*d83cc019SAndroid Build Coastguard Worker }
2361*d83cc019SAndroid Build Coastguard Worker 
igt_pipe_get_plane(igt_pipe_t * pipe,int plane_idx)2362*d83cc019SAndroid Build Coastguard Worker static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
2363*d83cc019SAndroid Build Coastguard Worker {
2364*d83cc019SAndroid Build Coastguard Worker 	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
2365*d83cc019SAndroid Build Coastguard Worker 		      "Valid pipe->planes plane_idx not found, plane_idx=%d n_planes=%d",
2366*d83cc019SAndroid Build Coastguard Worker 		      plane_idx, pipe->n_planes);
2367*d83cc019SAndroid Build Coastguard Worker 
2368*d83cc019SAndroid Build Coastguard Worker 	return &pipe->planes[plane_idx];
2369*d83cc019SAndroid Build Coastguard Worker }
2370*d83cc019SAndroid Build Coastguard Worker 
2371*d83cc019SAndroid Build Coastguard Worker /**
2372*d83cc019SAndroid Build Coastguard Worker  * igt_pipe_get_plane_type:
2373*d83cc019SAndroid Build Coastguard Worker  * @pipe: Target pipe
2374*d83cc019SAndroid Build Coastguard Worker  * @plane_type: Cursor, primary or an overlay plane
2375*d83cc019SAndroid Build Coastguard Worker  *
2376*d83cc019SAndroid Build Coastguard Worker  * Finds a valid plane type for the given @pipe otherwise
2377*d83cc019SAndroid Build Coastguard Worker  * it skips the test if the right combination of @pipe/@plane_type is not found
2378*d83cc019SAndroid Build Coastguard Worker  *
2379*d83cc019SAndroid Build Coastguard Worker  * Returns: A #igt_plane_t structure that matches the requested plane type
2380*d83cc019SAndroid Build Coastguard Worker  */
igt_pipe_get_plane_type(igt_pipe_t * pipe,int plane_type)2381*d83cc019SAndroid Build Coastguard Worker igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type)
2382*d83cc019SAndroid Build Coastguard Worker {
2383*d83cc019SAndroid Build Coastguard Worker 	int i, plane_idx = -1;
2384*d83cc019SAndroid Build Coastguard Worker 
2385*d83cc019SAndroid Build Coastguard Worker 	switch(plane_type) {
2386*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_CURSOR:
2387*d83cc019SAndroid Build Coastguard Worker 		plane_idx = pipe->plane_cursor;
2388*d83cc019SAndroid Build Coastguard Worker 		break;
2389*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_PRIMARY:
2390*d83cc019SAndroid Build Coastguard Worker 		plane_idx = pipe->plane_primary;
2391*d83cc019SAndroid Build Coastguard Worker 		break;
2392*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_OVERLAY:
2393*d83cc019SAndroid Build Coastguard Worker 		for(i = 0; i < pipe->n_planes; i++)
2394*d83cc019SAndroid Build Coastguard Worker 			if (pipe->planes[i].type == DRM_PLANE_TYPE_OVERLAY)
2395*d83cc019SAndroid Build Coastguard Worker 			    plane_idx = i;
2396*d83cc019SAndroid Build Coastguard Worker 		break;
2397*d83cc019SAndroid Build Coastguard Worker 	default:
2398*d83cc019SAndroid Build Coastguard Worker 		break;
2399*d83cc019SAndroid Build Coastguard Worker 	}
2400*d83cc019SAndroid Build Coastguard Worker 
2401*d83cc019SAndroid Build Coastguard Worker 	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
2402*d83cc019SAndroid Build Coastguard Worker 		      "Valid pipe->planes idx not found. plane_idx=%d plane_type=%d n_planes=%d\n",
2403*d83cc019SAndroid Build Coastguard Worker 		      plane_idx, plane_type, pipe->n_planes);
2404*d83cc019SAndroid Build Coastguard Worker 
2405*d83cc019SAndroid Build Coastguard Worker 	return &pipe->planes[plane_idx];
2406*d83cc019SAndroid Build Coastguard Worker }
2407*d83cc019SAndroid Build Coastguard Worker 
2408*d83cc019SAndroid Build Coastguard Worker /**
2409*d83cc019SAndroid Build Coastguard Worker  * igt_pipe_count_plane_type:
2410*d83cc019SAndroid Build Coastguard Worker  * @pipe: Target pipe
2411*d83cc019SAndroid Build Coastguard Worker  * @plane_type: Cursor, primary or an overlay plane
2412*d83cc019SAndroid Build Coastguard Worker  *
2413*d83cc019SAndroid Build Coastguard Worker  * Counts the number of planes of type @plane_type for the provided @pipe.
2414*d83cc019SAndroid Build Coastguard Worker  *
2415*d83cc019SAndroid Build Coastguard Worker  * Returns: The number of planes that match the requested plane type
2416*d83cc019SAndroid Build Coastguard Worker  */
igt_pipe_count_plane_type(igt_pipe_t * pipe,int plane_type)2417*d83cc019SAndroid Build Coastguard Worker int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type)
2418*d83cc019SAndroid Build Coastguard Worker {
2419*d83cc019SAndroid Build Coastguard Worker 	int i, count = 0;
2420*d83cc019SAndroid Build Coastguard Worker 
2421*d83cc019SAndroid Build Coastguard Worker 	for(i = 0; i < pipe->n_planes; i++)
2422*d83cc019SAndroid Build Coastguard Worker 		if (pipe->planes[i].type == plane_type)
2423*d83cc019SAndroid Build Coastguard Worker 			count++;
2424*d83cc019SAndroid Build Coastguard Worker 
2425*d83cc019SAndroid Build Coastguard Worker 	return count;
2426*d83cc019SAndroid Build Coastguard Worker }
2427*d83cc019SAndroid Build Coastguard Worker 
2428*d83cc019SAndroid Build Coastguard Worker /**
2429*d83cc019SAndroid Build Coastguard Worker  * igt_pipe_get_plane_type_index:
2430*d83cc019SAndroid Build Coastguard Worker  * @pipe: Target pipe
2431*d83cc019SAndroid Build Coastguard Worker  * @plane_type: Cursor, primary or an overlay plane
2432*d83cc019SAndroid Build Coastguard Worker  * @index: the index of the plane among planes of the same type
2433*d83cc019SAndroid Build Coastguard Worker  *
2434*d83cc019SAndroid Build Coastguard Worker  * Get the @index th plane of type @plane_type for the provided @pipe.
2435*d83cc019SAndroid Build Coastguard Worker  *
2436*d83cc019SAndroid Build Coastguard Worker  * Returns: The @index th plane that matches the requested plane type
2437*d83cc019SAndroid Build Coastguard Worker  */
igt_pipe_get_plane_type_index(igt_pipe_t * pipe,int plane_type,int index)2438*d83cc019SAndroid Build Coastguard Worker igt_plane_t *igt_pipe_get_plane_type_index(igt_pipe_t *pipe, int plane_type,
2439*d83cc019SAndroid Build Coastguard Worker 					   int index)
2440*d83cc019SAndroid Build Coastguard Worker {
2441*d83cc019SAndroid Build Coastguard Worker 	int i, type_index = 0;
2442*d83cc019SAndroid Build Coastguard Worker 
2443*d83cc019SAndroid Build Coastguard Worker 	for(i = 0; i < pipe->n_planes; i++) {
2444*d83cc019SAndroid Build Coastguard Worker 		if (pipe->planes[i].type != plane_type)
2445*d83cc019SAndroid Build Coastguard Worker 			continue;
2446*d83cc019SAndroid Build Coastguard Worker 
2447*d83cc019SAndroid Build Coastguard Worker 		if (type_index == index)
2448*d83cc019SAndroid Build Coastguard Worker 			return &pipe->planes[i];
2449*d83cc019SAndroid Build Coastguard Worker 
2450*d83cc019SAndroid Build Coastguard Worker 		type_index++;
2451*d83cc019SAndroid Build Coastguard Worker 	}
2452*d83cc019SAndroid Build Coastguard Worker 
2453*d83cc019SAndroid Build Coastguard Worker 	return NULL;
2454*d83cc019SAndroid Build Coastguard Worker }
2455*d83cc019SAndroid Build Coastguard Worker 
output_is_internal_panel(igt_output_t * output)2456*d83cc019SAndroid Build Coastguard Worker static bool output_is_internal_panel(igt_output_t *output)
2457*d83cc019SAndroid Build Coastguard Worker {
2458*d83cc019SAndroid Build Coastguard Worker 	switch (output->config.connector->connector_type) {
2459*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_CONNECTOR_LVDS:
2460*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_CONNECTOR_eDP:
2461*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_CONNECTOR_DSI:
2462*d83cc019SAndroid Build Coastguard Worker 	case DRM_MODE_CONNECTOR_DPI:
2463*d83cc019SAndroid Build Coastguard Worker 		return true;
2464*d83cc019SAndroid Build Coastguard Worker 	default:
2465*d83cc019SAndroid Build Coastguard Worker 		return false;
2466*d83cc019SAndroid Build Coastguard Worker 	}
2467*d83cc019SAndroid Build Coastguard Worker }
2468*d83cc019SAndroid Build Coastguard Worker 
__igt_pipe_populate_outputs(igt_display_t * display,igt_output_t ** chosen_outputs)2469*d83cc019SAndroid Build Coastguard Worker igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t **chosen_outputs)
2470*d83cc019SAndroid Build Coastguard Worker {
2471*d83cc019SAndroid Build Coastguard Worker 	unsigned full_pipe_mask = (1 << (display->n_pipes)) - 1, assigned_pipes = 0;
2472*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
2473*d83cc019SAndroid Build Coastguard Worker 	int i, j;
2474*d83cc019SAndroid Build Coastguard Worker 
2475*d83cc019SAndroid Build Coastguard Worker 	memset(chosen_outputs, 0, sizeof(*chosen_outputs) * display->n_pipes);
2476*d83cc019SAndroid Build Coastguard Worker 
2477*d83cc019SAndroid Build Coastguard Worker 	/*
2478*d83cc019SAndroid Build Coastguard Worker 	 * Try to assign all outputs to the first available CRTC for
2479*d83cc019SAndroid Build Coastguard Worker 	 * it, start with the outputs restricted to 1 pipe, then increase
2480*d83cc019SAndroid Build Coastguard Worker 	 * number of pipes until we assign connectors to all pipes.
2481*d83cc019SAndroid Build Coastguard Worker 	 */
2482*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i <= display->n_pipes; i++) {
2483*d83cc019SAndroid Build Coastguard Worker 		for_each_connected_output(display, output) {
2484*d83cc019SAndroid Build Coastguard Worker 			uint32_t pipe_mask = output->config.valid_crtc_idx_mask & full_pipe_mask;
2485*d83cc019SAndroid Build Coastguard Worker 			bool found = false;
2486*d83cc019SAndroid Build Coastguard Worker 
2487*d83cc019SAndroid Build Coastguard Worker 			if (output_is_internal_panel(output)) {
2488*d83cc019SAndroid Build Coastguard Worker 				/*
2489*d83cc019SAndroid Build Coastguard Worker 				 * Internal panel should be assigned to pipe A
2490*d83cc019SAndroid Build Coastguard Worker 				 * if possible, so make sure they're enumerated
2491*d83cc019SAndroid Build Coastguard Worker 				 * first.
2492*d83cc019SAndroid Build Coastguard Worker 				 */
2493*d83cc019SAndroid Build Coastguard Worker 
2494*d83cc019SAndroid Build Coastguard Worker 				if (i)
2495*d83cc019SAndroid Build Coastguard Worker 					continue;
2496*d83cc019SAndroid Build Coastguard Worker 			} else if (__builtin_popcount(pipe_mask) != i)
2497*d83cc019SAndroid Build Coastguard Worker 				continue;
2498*d83cc019SAndroid Build Coastguard Worker 
2499*d83cc019SAndroid Build Coastguard Worker 			for (j = 0; j < display->n_pipes; j++) {
2500*d83cc019SAndroid Build Coastguard Worker 				bool pipe_assigned = assigned_pipes & (1 << j);
2501*d83cc019SAndroid Build Coastguard Worker 
2502*d83cc019SAndroid Build Coastguard Worker 				if (pipe_assigned || !(pipe_mask & (1 << j)))
2503*d83cc019SAndroid Build Coastguard Worker 					continue;
2504*d83cc019SAndroid Build Coastguard Worker 
2505*d83cc019SAndroid Build Coastguard Worker 				if (!found) {
2506*d83cc019SAndroid Build Coastguard Worker 					/* We found an unassigned pipe, use it! */
2507*d83cc019SAndroid Build Coastguard Worker 					found = true;
2508*d83cc019SAndroid Build Coastguard Worker 					assigned_pipes |= 1 << j;
2509*d83cc019SAndroid Build Coastguard Worker 					chosen_outputs[j] = output;
2510*d83cc019SAndroid Build Coastguard Worker 				} else if (!chosen_outputs[j] ||
2511*d83cc019SAndroid Build Coastguard Worker 					   /*
2512*d83cc019SAndroid Build Coastguard Worker 					    * Overwrite internal panel if not assigned,
2513*d83cc019SAndroid Build Coastguard Worker 					    * external outputs are faster to do modesets
2514*d83cc019SAndroid Build Coastguard Worker 					    */
2515*d83cc019SAndroid Build Coastguard Worker 					   output_is_internal_panel(chosen_outputs[j]))
2516*d83cc019SAndroid Build Coastguard Worker 					chosen_outputs[j] = output;
2517*d83cc019SAndroid Build Coastguard Worker 			}
2518*d83cc019SAndroid Build Coastguard Worker 
2519*d83cc019SAndroid Build Coastguard Worker 			if (!found)
2520*d83cc019SAndroid Build Coastguard Worker 				igt_warn("Output %s could not be assigned to a pipe\n",
2521*d83cc019SAndroid Build Coastguard Worker 					 igt_output_name(output));
2522*d83cc019SAndroid Build Coastguard Worker 		}
2523*d83cc019SAndroid Build Coastguard Worker 	}
2524*d83cc019SAndroid Build Coastguard Worker 
2525*d83cc019SAndroid Build Coastguard Worker 	return chosen_outputs;
2526*d83cc019SAndroid Build Coastguard Worker }
2527*d83cc019SAndroid Build Coastguard Worker 
2528*d83cc019SAndroid Build Coastguard Worker /**
2529*d83cc019SAndroid Build Coastguard Worker  * igt_get_single_output_for_pipe:
2530*d83cc019SAndroid Build Coastguard Worker  * @display: a pointer to an #igt_display_t structure
2531*d83cc019SAndroid Build Coastguard Worker  * @pipe: The pipe for which an #igt_output_t must be returned.
2532*d83cc019SAndroid Build Coastguard Worker  *
2533*d83cc019SAndroid Build Coastguard Worker  * Get a compatible output for a pipe.
2534*d83cc019SAndroid Build Coastguard Worker  *
2535*d83cc019SAndroid Build Coastguard Worker  * Returns: A compatible output for a given pipe, or NULL.
2536*d83cc019SAndroid Build Coastguard Worker  */
igt_get_single_output_for_pipe(igt_display_t * display,enum pipe pipe)2537*d83cc019SAndroid Build Coastguard Worker igt_output_t *igt_get_single_output_for_pipe(igt_display_t *display, enum pipe pipe)
2538*d83cc019SAndroid Build Coastguard Worker {
2539*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *chosen_outputs[display->n_pipes];
2540*d83cc019SAndroid Build Coastguard Worker 
2541*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pipe != PIPE_NONE);
2542*d83cc019SAndroid Build Coastguard Worker 	igt_require(pipe < display->n_pipes);
2543*d83cc019SAndroid Build Coastguard Worker 
2544*d83cc019SAndroid Build Coastguard Worker 	__igt_pipe_populate_outputs(display, chosen_outputs);
2545*d83cc019SAndroid Build Coastguard Worker 
2546*d83cc019SAndroid Build Coastguard Worker 	return chosen_outputs[pipe];
2547*d83cc019SAndroid Build Coastguard Worker }
2548*d83cc019SAndroid Build Coastguard Worker 
igt_pipe_get_output(igt_pipe_t * pipe)2549*d83cc019SAndroid Build Coastguard Worker static igt_output_t *igt_pipe_get_output(igt_pipe_t *pipe)
2550*d83cc019SAndroid Build Coastguard Worker {
2551*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
2552*d83cc019SAndroid Build Coastguard Worker 	int i;
2553*d83cc019SAndroid Build Coastguard Worker 
2554*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++) {
2555*d83cc019SAndroid Build Coastguard Worker 		igt_output_t *output = &display->outputs[i];
2556*d83cc019SAndroid Build Coastguard Worker 
2557*d83cc019SAndroid Build Coastguard Worker 		if (output->pending_pipe == pipe->pipe)
2558*d83cc019SAndroid Build Coastguard Worker 			return output;
2559*d83cc019SAndroid Build Coastguard Worker 	}
2560*d83cc019SAndroid Build Coastguard Worker 
2561*d83cc019SAndroid Build Coastguard Worker 	return NULL;
2562*d83cc019SAndroid Build Coastguard Worker }
2563*d83cc019SAndroid Build Coastguard Worker 
igt_plane_get_fb_id(igt_plane_t * plane)2564*d83cc019SAndroid Build Coastguard Worker static uint32_t igt_plane_get_fb_id(igt_plane_t *plane)
2565*d83cc019SAndroid Build Coastguard Worker {
2566*d83cc019SAndroid Build Coastguard Worker 	return plane->values[IGT_PLANE_FB_ID];
2567*d83cc019SAndroid Build Coastguard Worker }
2568*d83cc019SAndroid Build Coastguard Worker 
2569*d83cc019SAndroid Build Coastguard Worker #define CHECK_RETURN(r, fail) {	\
2570*d83cc019SAndroid Build Coastguard Worker 	if (r && !fail)		\
2571*d83cc019SAndroid Build Coastguard Worker 		return r;	\
2572*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(r, 0);	\
2573*d83cc019SAndroid Build Coastguard Worker }
2574*d83cc019SAndroid Build Coastguard Worker 
2575*d83cc019SAndroid Build Coastguard Worker /*
2576*d83cc019SAndroid Build Coastguard Worker  * Add position and fb changes of a plane to the atomic property set
2577*d83cc019SAndroid Build Coastguard Worker  */
2578*d83cc019SAndroid Build Coastguard Worker static void
igt_atomic_prepare_plane_commit(igt_plane_t * plane,igt_pipe_t * pipe,drmModeAtomicReq * req)2579*d83cc019SAndroid Build Coastguard Worker igt_atomic_prepare_plane_commit(igt_plane_t *plane, igt_pipe_t *pipe,
2580*d83cc019SAndroid Build Coastguard Worker 	drmModeAtomicReq *req)
2581*d83cc019SAndroid Build Coastguard Worker {
2582*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
2583*d83cc019SAndroid Build Coastguard Worker 	int i;
2584*d83cc019SAndroid Build Coastguard Worker 
2585*d83cc019SAndroid Build Coastguard Worker 	igt_assert(plane->drm_plane);
2586*d83cc019SAndroid Build Coastguard Worker 
2587*d83cc019SAndroid Build Coastguard Worker 	LOG(display,
2588*d83cc019SAndroid Build Coastguard Worker 	    "populating plane data: %s.%d, fb %u\n",
2589*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(pipe->pipe),
2590*d83cc019SAndroid Build Coastguard Worker 	    plane->index,
2591*d83cc019SAndroid Build Coastguard Worker 	    igt_plane_get_fb_id(plane));
2592*d83cc019SAndroid Build Coastguard Worker 
2593*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
2594*d83cc019SAndroid Build Coastguard Worker 		if (!igt_plane_is_prop_changed(plane, i))
2595*d83cc019SAndroid Build Coastguard Worker 			continue;
2596*d83cc019SAndroid Build Coastguard Worker 
2597*d83cc019SAndroid Build Coastguard Worker 		/* it's an error to try an unsupported feature */
2598*d83cc019SAndroid Build Coastguard Worker 		igt_assert(plane->props[i]);
2599*d83cc019SAndroid Build Coastguard Worker 
2600*d83cc019SAndroid Build Coastguard Worker 		igt_debug("plane %s.%d: Setting property \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
2601*d83cc019SAndroid Build Coastguard Worker 			kmstest_pipe_name(pipe->pipe), plane->index, igt_plane_prop_names[i],
2602*d83cc019SAndroid Build Coastguard Worker 			plane->values[i], plane->values[i]);
2603*d83cc019SAndroid Build Coastguard Worker 
2604*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->drm_plane->plane_id,
2605*d83cc019SAndroid Build Coastguard Worker 						  plane->props[i],
2606*d83cc019SAndroid Build Coastguard Worker 						  plane->values[i]));
2607*d83cc019SAndroid Build Coastguard Worker 	}
2608*d83cc019SAndroid Build Coastguard Worker }
2609*d83cc019SAndroid Build Coastguard Worker 
2610*d83cc019SAndroid Build Coastguard Worker /*
2611*d83cc019SAndroid Build Coastguard Worker  * Properties that can be changed through legacy SetProperty:
2612*d83cc019SAndroid Build Coastguard Worker  * - Obviously not the XYWH SRC/CRTC coordinates.
2613*d83cc019SAndroid Build Coastguard Worker  * - Not CRTC_ID or FENCE_ID, done through SetPlane.
2614*d83cc019SAndroid Build Coastguard Worker  * - Can't set IN_FENCE_FD, that would be silly.
2615*d83cc019SAndroid Build Coastguard Worker  *
2616*d83cc019SAndroid Build Coastguard Worker  * Theoretically the above can all be set through the legacy path
2617*d83cc019SAndroid Build Coastguard Worker  * with the atomic cap set, but that's not how our legacy plane
2618*d83cc019SAndroid Build Coastguard Worker  * commit behaves, so blacklist it by default.
2619*d83cc019SAndroid Build Coastguard Worker  */
2620*d83cc019SAndroid Build Coastguard Worker #define LEGACY_PLANE_COMMIT_MASK \
2621*d83cc019SAndroid Build Coastguard Worker 	(((1ULL << IGT_NUM_PLANE_PROPS) - 1) & \
2622*d83cc019SAndroid Build Coastguard Worker 	 ~(IGT_PLANE_COORD_CHANGED_MASK | \
2623*d83cc019SAndroid Build Coastguard Worker 	   (1ULL << IGT_PLANE_FB_ID) | \
2624*d83cc019SAndroid Build Coastguard Worker 	   (1ULL << IGT_PLANE_CRTC_ID) | \
2625*d83cc019SAndroid Build Coastguard Worker 	   (1ULL << IGT_PLANE_IN_FENCE_FD)))
2626*d83cc019SAndroid Build Coastguard Worker 
2627*d83cc019SAndroid Build Coastguard Worker /*
2628*d83cc019SAndroid Build Coastguard Worker  * Commit position and fb changes to a DRM plane via the SetPlane ioctl; if the
2629*d83cc019SAndroid Build Coastguard Worker  * DRM call to program the plane fails, we'll either fail immediately (for
2630*d83cc019SAndroid Build Coastguard Worker  * tests that expect the commit to succeed) or return the failure code (for
2631*d83cc019SAndroid Build Coastguard Worker  * tests that expect a specific error code).
2632*d83cc019SAndroid Build Coastguard Worker  */
igt_drm_plane_commit(igt_plane_t * plane,igt_pipe_t * pipe,bool fail_on_error)2633*d83cc019SAndroid Build Coastguard Worker static int igt_drm_plane_commit(igt_plane_t *plane,
2634*d83cc019SAndroid Build Coastguard Worker 				igt_pipe_t *pipe,
2635*d83cc019SAndroid Build Coastguard Worker 				bool fail_on_error)
2636*d83cc019SAndroid Build Coastguard Worker {
2637*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
2638*d83cc019SAndroid Build Coastguard Worker 	uint32_t fb_id, crtc_id;
2639*d83cc019SAndroid Build Coastguard Worker 	int ret, i;
2640*d83cc019SAndroid Build Coastguard Worker 	uint32_t src_x;
2641*d83cc019SAndroid Build Coastguard Worker 	uint32_t src_y;
2642*d83cc019SAndroid Build Coastguard Worker 	uint32_t src_w;
2643*d83cc019SAndroid Build Coastguard Worker 	uint32_t src_h;
2644*d83cc019SAndroid Build Coastguard Worker 	int32_t crtc_x;
2645*d83cc019SAndroid Build Coastguard Worker 	int32_t crtc_y;
2646*d83cc019SAndroid Build Coastguard Worker 	uint32_t crtc_w;
2647*d83cc019SAndroid Build Coastguard Worker 	uint32_t crtc_h;
2648*d83cc019SAndroid Build Coastguard Worker 	uint64_t changed_mask;
2649*d83cc019SAndroid Build Coastguard Worker 	bool setplane =
2650*d83cc019SAndroid Build Coastguard Worker 		igt_plane_is_prop_changed(plane, IGT_PLANE_FB_ID) ||
2651*d83cc019SAndroid Build Coastguard Worker 		plane->changed & IGT_PLANE_COORD_CHANGED_MASK;
2652*d83cc019SAndroid Build Coastguard Worker 
2653*d83cc019SAndroid Build Coastguard Worker 	igt_assert(plane->drm_plane);
2654*d83cc019SAndroid Build Coastguard Worker 
2655*d83cc019SAndroid Build Coastguard Worker 	fb_id = igt_plane_get_fb_id(plane);
2656*d83cc019SAndroid Build Coastguard Worker 	crtc_id = pipe->crtc_id;
2657*d83cc019SAndroid Build Coastguard Worker 
2658*d83cc019SAndroid Build Coastguard Worker 	if (setplane && fb_id == 0) {
2659*d83cc019SAndroid Build Coastguard Worker 		LOG(display,
2660*d83cc019SAndroid Build Coastguard Worker 		    "SetPlane pipe %s, plane %d, disabling\n",
2661*d83cc019SAndroid Build Coastguard Worker 		    kmstest_pipe_name(pipe->pipe),
2662*d83cc019SAndroid Build Coastguard Worker 		    plane->index);
2663*d83cc019SAndroid Build Coastguard Worker 
2664*d83cc019SAndroid Build Coastguard Worker 		ret = drmModeSetPlane(display->drm_fd,
2665*d83cc019SAndroid Build Coastguard Worker 				      plane->drm_plane->plane_id,
2666*d83cc019SAndroid Build Coastguard Worker 				      crtc_id,
2667*d83cc019SAndroid Build Coastguard Worker 				      fb_id,
2668*d83cc019SAndroid Build Coastguard Worker 				      0,    /* flags */
2669*d83cc019SAndroid Build Coastguard Worker 				      0, 0, /* crtc_x, crtc_y */
2670*d83cc019SAndroid Build Coastguard Worker 				      0, 0, /* crtc_w, crtc_h */
2671*d83cc019SAndroid Build Coastguard Worker 				      IGT_FIXED(0,0), /* src_x */
2672*d83cc019SAndroid Build Coastguard Worker 				      IGT_FIXED(0,0), /* src_y */
2673*d83cc019SAndroid Build Coastguard Worker 				      IGT_FIXED(0,0), /* src_w */
2674*d83cc019SAndroid Build Coastguard Worker 				      IGT_FIXED(0,0) /* src_h */);
2675*d83cc019SAndroid Build Coastguard Worker 
2676*d83cc019SAndroid Build Coastguard Worker 		CHECK_RETURN(ret, fail_on_error);
2677*d83cc019SAndroid Build Coastguard Worker 	} else if (setplane) {
2678*d83cc019SAndroid Build Coastguard Worker 		src_x = plane->values[IGT_PLANE_SRC_X];
2679*d83cc019SAndroid Build Coastguard Worker 		src_y = plane->values[IGT_PLANE_SRC_Y];
2680*d83cc019SAndroid Build Coastguard Worker 		src_w = plane->values[IGT_PLANE_SRC_W];
2681*d83cc019SAndroid Build Coastguard Worker 		src_h = plane->values[IGT_PLANE_SRC_H];
2682*d83cc019SAndroid Build Coastguard Worker 		crtc_x = plane->values[IGT_PLANE_CRTC_X];
2683*d83cc019SAndroid Build Coastguard Worker 		crtc_y = plane->values[IGT_PLANE_CRTC_Y];
2684*d83cc019SAndroid Build Coastguard Worker 		crtc_w = plane->values[IGT_PLANE_CRTC_W];
2685*d83cc019SAndroid Build Coastguard Worker 		crtc_h = plane->values[IGT_PLANE_CRTC_H];
2686*d83cc019SAndroid Build Coastguard Worker 
2687*d83cc019SAndroid Build Coastguard Worker 		LOG(display,
2688*d83cc019SAndroid Build Coastguard Worker 		    "SetPlane %s.%d, fb %u, src = (%d, %d) "
2689*d83cc019SAndroid Build Coastguard Worker 			"%ux%u dst = (%u, %u) %ux%u\n",
2690*d83cc019SAndroid Build Coastguard Worker 		    kmstest_pipe_name(pipe->pipe),
2691*d83cc019SAndroid Build Coastguard Worker 		    plane->index,
2692*d83cc019SAndroid Build Coastguard Worker 		    fb_id,
2693*d83cc019SAndroid Build Coastguard Worker 		    src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16,
2694*d83cc019SAndroid Build Coastguard Worker 		    crtc_x, crtc_y, crtc_w, crtc_h);
2695*d83cc019SAndroid Build Coastguard Worker 
2696*d83cc019SAndroid Build Coastguard Worker 		ret = drmModeSetPlane(display->drm_fd,
2697*d83cc019SAndroid Build Coastguard Worker 				      plane->drm_plane->plane_id,
2698*d83cc019SAndroid Build Coastguard Worker 				      crtc_id,
2699*d83cc019SAndroid Build Coastguard Worker 				      fb_id,
2700*d83cc019SAndroid Build Coastguard Worker 				      0,    /* flags */
2701*d83cc019SAndroid Build Coastguard Worker 				      crtc_x, crtc_y,
2702*d83cc019SAndroid Build Coastguard Worker 				      crtc_w, crtc_h,
2703*d83cc019SAndroid Build Coastguard Worker 				      src_x, src_y,
2704*d83cc019SAndroid Build Coastguard Worker 				      src_w, src_h);
2705*d83cc019SAndroid Build Coastguard Worker 
2706*d83cc019SAndroid Build Coastguard Worker 		CHECK_RETURN(ret, fail_on_error);
2707*d83cc019SAndroid Build Coastguard Worker 	}
2708*d83cc019SAndroid Build Coastguard Worker 
2709*d83cc019SAndroid Build Coastguard Worker 	changed_mask = plane->changed & LEGACY_PLANE_COMMIT_MASK;
2710*d83cc019SAndroid Build Coastguard Worker 
2711*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
2712*d83cc019SAndroid Build Coastguard Worker 		if (!(changed_mask & (1 << i)))
2713*d83cc019SAndroid Build Coastguard Worker 			continue;
2714*d83cc019SAndroid Build Coastguard Worker 
2715*d83cc019SAndroid Build Coastguard Worker 		LOG(display, "SetProp plane %s.%d \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
2716*d83cc019SAndroid Build Coastguard Worker 			kmstest_pipe_name(pipe->pipe), plane->index, igt_plane_prop_names[i],
2717*d83cc019SAndroid Build Coastguard Worker 			plane->values[i], plane->values[i]);
2718*d83cc019SAndroid Build Coastguard Worker 
2719*d83cc019SAndroid Build Coastguard Worker 		igt_assert(plane->props[i]);
2720*d83cc019SAndroid Build Coastguard Worker 
2721*d83cc019SAndroid Build Coastguard Worker 		ret = igt_plane_set_property(plane,
2722*d83cc019SAndroid Build Coastguard Worker 					     plane->props[i],
2723*d83cc019SAndroid Build Coastguard Worker 					     plane->values[i]);
2724*d83cc019SAndroid Build Coastguard Worker 
2725*d83cc019SAndroid Build Coastguard Worker 		CHECK_RETURN(ret, fail_on_error);
2726*d83cc019SAndroid Build Coastguard Worker 	}
2727*d83cc019SAndroid Build Coastguard Worker 
2728*d83cc019SAndroid Build Coastguard Worker 	return 0;
2729*d83cc019SAndroid Build Coastguard Worker }
2730*d83cc019SAndroid Build Coastguard Worker 
2731*d83cc019SAndroid Build Coastguard Worker /*
2732*d83cc019SAndroid Build Coastguard Worker  * Commit position and fb changes to a cursor via legacy ioctl's.  If commit
2733*d83cc019SAndroid Build Coastguard Worker  * fails, we'll either fail immediately (for tests that expect the commit to
2734*d83cc019SAndroid Build Coastguard Worker  * succeed) or return the failure code (for tests that expect a specific error
2735*d83cc019SAndroid Build Coastguard Worker  * code).
2736*d83cc019SAndroid Build Coastguard Worker  */
igt_cursor_commit_legacy(igt_plane_t * cursor,igt_pipe_t * pipe,bool fail_on_error)2737*d83cc019SAndroid Build Coastguard Worker static int igt_cursor_commit_legacy(igt_plane_t *cursor,
2738*d83cc019SAndroid Build Coastguard Worker 				    igt_pipe_t *pipe,
2739*d83cc019SAndroid Build Coastguard Worker 				    bool fail_on_error)
2740*d83cc019SAndroid Build Coastguard Worker {
2741*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
2742*d83cc019SAndroid Build Coastguard Worker 	uint32_t crtc_id = pipe->crtc_id;
2743*d83cc019SAndroid Build Coastguard Worker 	int ret;
2744*d83cc019SAndroid Build Coastguard Worker 
2745*d83cc019SAndroid Build Coastguard Worker 	if (igt_plane_is_prop_changed(cursor, IGT_PLANE_FB_ID) ||
2746*d83cc019SAndroid Build Coastguard Worker 	    igt_plane_is_prop_changed(cursor, IGT_PLANE_CRTC_W) ||
2747*d83cc019SAndroid Build Coastguard Worker 	    igt_plane_is_prop_changed(cursor, IGT_PLANE_CRTC_H)) {
2748*d83cc019SAndroid Build Coastguard Worker 		if (cursor->gem_handle)
2749*d83cc019SAndroid Build Coastguard Worker 			LOG(display,
2750*d83cc019SAndroid Build Coastguard Worker 			    "SetCursor pipe %s, fb %u %dx%d\n",
2751*d83cc019SAndroid Build Coastguard Worker 			    kmstest_pipe_name(pipe->pipe),
2752*d83cc019SAndroid Build Coastguard Worker 			    cursor->gem_handle,
2753*d83cc019SAndroid Build Coastguard Worker 			    (unsigned)cursor->values[IGT_PLANE_CRTC_W],
2754*d83cc019SAndroid Build Coastguard Worker 			    (unsigned)cursor->values[IGT_PLANE_CRTC_H]);
2755*d83cc019SAndroid Build Coastguard Worker 		else
2756*d83cc019SAndroid Build Coastguard Worker 			LOG(display,
2757*d83cc019SAndroid Build Coastguard Worker 			    "SetCursor pipe %s, disabling\n",
2758*d83cc019SAndroid Build Coastguard Worker 			    kmstest_pipe_name(pipe->pipe));
2759*d83cc019SAndroid Build Coastguard Worker 
2760*d83cc019SAndroid Build Coastguard Worker 		ret = drmModeSetCursor(display->drm_fd, crtc_id,
2761*d83cc019SAndroid Build Coastguard Worker 				       cursor->gem_handle,
2762*d83cc019SAndroid Build Coastguard Worker 				       cursor->values[IGT_PLANE_CRTC_W],
2763*d83cc019SAndroid Build Coastguard Worker 				       cursor->values[IGT_PLANE_CRTC_H]);
2764*d83cc019SAndroid Build Coastguard Worker 		CHECK_RETURN(ret, fail_on_error);
2765*d83cc019SAndroid Build Coastguard Worker 	}
2766*d83cc019SAndroid Build Coastguard Worker 
2767*d83cc019SAndroid Build Coastguard Worker 	if (igt_plane_is_prop_changed(cursor, IGT_PLANE_CRTC_X) ||
2768*d83cc019SAndroid Build Coastguard Worker 	    igt_plane_is_prop_changed(cursor, IGT_PLANE_CRTC_Y)) {
2769*d83cc019SAndroid Build Coastguard Worker 		int x = cursor->values[IGT_PLANE_CRTC_X];
2770*d83cc019SAndroid Build Coastguard Worker 		int y = cursor->values[IGT_PLANE_CRTC_Y];
2771*d83cc019SAndroid Build Coastguard Worker 
2772*d83cc019SAndroid Build Coastguard Worker 		LOG(display,
2773*d83cc019SAndroid Build Coastguard Worker 		    "MoveCursor pipe %s, (%d, %d)\n",
2774*d83cc019SAndroid Build Coastguard Worker 		    kmstest_pipe_name(pipe->pipe),
2775*d83cc019SAndroid Build Coastguard Worker 		    x, y);
2776*d83cc019SAndroid Build Coastguard Worker 
2777*d83cc019SAndroid Build Coastguard Worker 		ret = drmModeMoveCursor(display->drm_fd, crtc_id, x, y);
2778*d83cc019SAndroid Build Coastguard Worker 		CHECK_RETURN(ret, fail_on_error);
2779*d83cc019SAndroid Build Coastguard Worker 	}
2780*d83cc019SAndroid Build Coastguard Worker 
2781*d83cc019SAndroid Build Coastguard Worker 	return 0;
2782*d83cc019SAndroid Build Coastguard Worker }
2783*d83cc019SAndroid Build Coastguard Worker 
2784*d83cc019SAndroid Build Coastguard Worker /*
2785*d83cc019SAndroid Build Coastguard Worker  * Commit position and fb changes to a primary plane via the legacy interface
2786*d83cc019SAndroid Build Coastguard Worker  * (setmode).
2787*d83cc019SAndroid Build Coastguard Worker  */
igt_primary_plane_commit_legacy(igt_plane_t * primary,igt_pipe_t * pipe,bool fail_on_error)2788*d83cc019SAndroid Build Coastguard Worker static int igt_primary_plane_commit_legacy(igt_plane_t *primary,
2789*d83cc019SAndroid Build Coastguard Worker 					   igt_pipe_t *pipe,
2790*d83cc019SAndroid Build Coastguard Worker 					   bool fail_on_error)
2791*d83cc019SAndroid Build Coastguard Worker {
2792*d83cc019SAndroid Build Coastguard Worker 	struct igt_display *display = primary->pipe->display;
2793*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output = igt_pipe_get_output(pipe);
2794*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
2795*d83cc019SAndroid Build Coastguard Worker 	uint32_t fb_id, crtc_id;
2796*d83cc019SAndroid Build Coastguard Worker 	int ret;
2797*d83cc019SAndroid Build Coastguard Worker 
2798*d83cc019SAndroid Build Coastguard Worker 	/* Primary planes can't be windowed when using a legacy commit */
2799*d83cc019SAndroid Build Coastguard Worker 	igt_assert((primary->values[IGT_PLANE_CRTC_X] == 0 && primary->values[IGT_PLANE_CRTC_Y] == 0));
2800*d83cc019SAndroid Build Coastguard Worker 
2801*d83cc019SAndroid Build Coastguard Worker 	/* nor rotated */
2802*d83cc019SAndroid Build Coastguard Worker 	if (!pipe->display->first_commit)
2803*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!igt_plane_is_prop_changed(primary, IGT_PLANE_ROTATION));
2804*d83cc019SAndroid Build Coastguard Worker 
2805*d83cc019SAndroid Build Coastguard Worker 	if (!igt_plane_is_prop_changed(primary, IGT_PLANE_FB_ID) &&
2806*d83cc019SAndroid Build Coastguard Worker 	    !(primary->changed & IGT_PLANE_COORD_CHANGED_MASK) &&
2807*d83cc019SAndroid Build Coastguard Worker 	    !(igt_pipe_obj_is_prop_changed(primary->pipe, IGT_CRTC_MODE_ID) &&
2808*d83cc019SAndroid Build Coastguard Worker 		primary == igt_pipe_get_plane_type(primary->pipe, DRM_PLANE_TYPE_PRIMARY)))
2809*d83cc019SAndroid Build Coastguard Worker 		return 0;
2810*d83cc019SAndroid Build Coastguard Worker 
2811*d83cc019SAndroid Build Coastguard Worker 	crtc_id = pipe->crtc_id;
2812*d83cc019SAndroid Build Coastguard Worker 	fb_id = output ? igt_plane_get_fb_id(primary) : 0;
2813*d83cc019SAndroid Build Coastguard Worker 	if (fb_id)
2814*d83cc019SAndroid Build Coastguard Worker 		mode = igt_output_get_mode(output);
2815*d83cc019SAndroid Build Coastguard Worker 	else
2816*d83cc019SAndroid Build Coastguard Worker 		mode = NULL;
2817*d83cc019SAndroid Build Coastguard Worker 
2818*d83cc019SAndroid Build Coastguard Worker 	if (fb_id) {
2819*d83cc019SAndroid Build Coastguard Worker 		uint32_t src_x = primary->values[IGT_PLANE_SRC_X] >> 16;
2820*d83cc019SAndroid Build Coastguard Worker 		uint32_t src_y = primary->values[IGT_PLANE_SRC_Y] >> 16;
2821*d83cc019SAndroid Build Coastguard Worker 
2822*d83cc019SAndroid Build Coastguard Worker 		LOG(display,
2823*d83cc019SAndroid Build Coastguard Worker 		    "%s: SetCrtc pipe %s, fb %u, src (%d, %d), "
2824*d83cc019SAndroid Build Coastguard Worker 		    "mode %dx%d\n",
2825*d83cc019SAndroid Build Coastguard Worker 		    igt_output_name(output),
2826*d83cc019SAndroid Build Coastguard Worker 		    kmstest_pipe_name(pipe->pipe),
2827*d83cc019SAndroid Build Coastguard Worker 		    fb_id,
2828*d83cc019SAndroid Build Coastguard Worker 		    src_x, src_y,
2829*d83cc019SAndroid Build Coastguard Worker 		    mode->hdisplay, mode->vdisplay);
2830*d83cc019SAndroid Build Coastguard Worker 
2831*d83cc019SAndroid Build Coastguard Worker 		ret = drmModeSetCrtc(display->drm_fd,
2832*d83cc019SAndroid Build Coastguard Worker 				     crtc_id,
2833*d83cc019SAndroid Build Coastguard Worker 				     fb_id,
2834*d83cc019SAndroid Build Coastguard Worker 				     src_x, src_y,
2835*d83cc019SAndroid Build Coastguard Worker 				     &output->id,
2836*d83cc019SAndroid Build Coastguard Worker 				     1,
2837*d83cc019SAndroid Build Coastguard Worker 				     mode);
2838*d83cc019SAndroid Build Coastguard Worker 	} else {
2839*d83cc019SAndroid Build Coastguard Worker 		LOG(display,
2840*d83cc019SAndroid Build Coastguard Worker 		    "SetCrtc pipe %s, disabling\n",
2841*d83cc019SAndroid Build Coastguard Worker 		    kmstest_pipe_name(pipe->pipe));
2842*d83cc019SAndroid Build Coastguard Worker 
2843*d83cc019SAndroid Build Coastguard Worker 		ret = drmModeSetCrtc(display->drm_fd,
2844*d83cc019SAndroid Build Coastguard Worker 				     crtc_id,
2845*d83cc019SAndroid Build Coastguard Worker 				     fb_id,
2846*d83cc019SAndroid Build Coastguard Worker 				     0, 0, /* x, y */
2847*d83cc019SAndroid Build Coastguard Worker 				     NULL, /* connectors */
2848*d83cc019SAndroid Build Coastguard Worker 				     0,    /* n_connectors */
2849*d83cc019SAndroid Build Coastguard Worker 				     NULL  /* mode */);
2850*d83cc019SAndroid Build Coastguard Worker 	}
2851*d83cc019SAndroid Build Coastguard Worker 
2852*d83cc019SAndroid Build Coastguard Worker 	CHECK_RETURN(ret, fail_on_error);
2853*d83cc019SAndroid Build Coastguard Worker 
2854*d83cc019SAndroid Build Coastguard Worker 	return 0;
2855*d83cc019SAndroid Build Coastguard Worker }
2856*d83cc019SAndroid Build Coastguard Worker 
igt_plane_fixup_rotation(igt_plane_t * plane,igt_pipe_t * pipe)2857*d83cc019SAndroid Build Coastguard Worker static int igt_plane_fixup_rotation(igt_plane_t *plane,
2858*d83cc019SAndroid Build Coastguard Worker 				    igt_pipe_t *pipe)
2859*d83cc019SAndroid Build Coastguard Worker {
2860*d83cc019SAndroid Build Coastguard Worker 	int ret;
2861*d83cc019SAndroid Build Coastguard Worker 
2862*d83cc019SAndroid Build Coastguard Worker 	if (!igt_plane_has_prop(plane, IGT_PLANE_ROTATION))
2863*d83cc019SAndroid Build Coastguard Worker 		return 0;
2864*d83cc019SAndroid Build Coastguard Worker 
2865*d83cc019SAndroid Build Coastguard Worker 	LOG(pipe->display, "Fixing up initial rotation pipe %s, plane %d\n",
2866*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(pipe->pipe), plane->index);
2867*d83cc019SAndroid Build Coastguard Worker 
2868*d83cc019SAndroid Build Coastguard Worker 	/* First try the easy case, can we change rotation without problems? */
2869*d83cc019SAndroid Build Coastguard Worker 	ret = igt_plane_set_property(plane, plane->props[IGT_PLANE_ROTATION],
2870*d83cc019SAndroid Build Coastguard Worker 				     plane->values[IGT_PLANE_ROTATION]);
2871*d83cc019SAndroid Build Coastguard Worker 	if (!ret)
2872*d83cc019SAndroid Build Coastguard Worker 		return 0;
2873*d83cc019SAndroid Build Coastguard Worker 
2874*d83cc019SAndroid Build Coastguard Worker 	/* Disable the plane, while we tinker with rotation */
2875*d83cc019SAndroid Build Coastguard Worker 	ret = drmModeSetPlane(pipe->display->drm_fd,
2876*d83cc019SAndroid Build Coastguard Worker 			      plane->drm_plane->plane_id,
2877*d83cc019SAndroid Build Coastguard Worker 			      pipe->crtc_id, 0, /* fb_id */
2878*d83cc019SAndroid Build Coastguard Worker 			      0, /* flags */
2879*d83cc019SAndroid Build Coastguard Worker 			      0, 0, 0, 0, /* crtc_x, crtc_y, crtc_w, crtc_h */
2880*d83cc019SAndroid Build Coastguard Worker 			      IGT_FIXED(0,0), IGT_FIXED(0,0), /* src_x, src_y */
2881*d83cc019SAndroid Build Coastguard Worker 			      IGT_FIXED(0,0), IGT_FIXED(0,0)); /* src_w, src_h */
2882*d83cc019SAndroid Build Coastguard Worker 
2883*d83cc019SAndroid Build Coastguard Worker 	if (ret && plane->type != DRM_PLANE_TYPE_PRIMARY)
2884*d83cc019SAndroid Build Coastguard Worker 		return ret;
2885*d83cc019SAndroid Build Coastguard Worker 
2886*d83cc019SAndroid Build Coastguard Worker 	/* For primary plane, fall back to disabling the crtc. */
2887*d83cc019SAndroid Build Coastguard Worker 	if (ret) {
2888*d83cc019SAndroid Build Coastguard Worker 		ret = drmModeSetCrtc(pipe->display->drm_fd,
2889*d83cc019SAndroid Build Coastguard Worker 				     pipe->crtc_id, 0, 0, 0, NULL, 0, NULL);
2890*d83cc019SAndroid Build Coastguard Worker 
2891*d83cc019SAndroid Build Coastguard Worker 		if (ret)
2892*d83cc019SAndroid Build Coastguard Worker 			return ret;
2893*d83cc019SAndroid Build Coastguard Worker 	}
2894*d83cc019SAndroid Build Coastguard Worker 
2895*d83cc019SAndroid Build Coastguard Worker 	/* and finally, set rotation property. */
2896*d83cc019SAndroid Build Coastguard Worker 	return igt_plane_set_property(plane, plane->props[IGT_PLANE_ROTATION],
2897*d83cc019SAndroid Build Coastguard Worker 				      plane->values[IGT_PLANE_ROTATION]);
2898*d83cc019SAndroid Build Coastguard Worker }
2899*d83cc019SAndroid Build Coastguard Worker 
2900*d83cc019SAndroid Build Coastguard Worker /*
2901*d83cc019SAndroid Build Coastguard Worker  * Commit position and fb changes to a plane.  The value of @s will determine
2902*d83cc019SAndroid Build Coastguard Worker  * which API is used to do the programming.
2903*d83cc019SAndroid Build Coastguard Worker  */
igt_plane_commit(igt_plane_t * plane,igt_pipe_t * pipe,enum igt_commit_style s,bool fail_on_error)2904*d83cc019SAndroid Build Coastguard Worker static int igt_plane_commit(igt_plane_t *plane,
2905*d83cc019SAndroid Build Coastguard Worker 			    igt_pipe_t *pipe,
2906*d83cc019SAndroid Build Coastguard Worker 			    enum igt_commit_style s,
2907*d83cc019SAndroid Build Coastguard Worker 			    bool fail_on_error)
2908*d83cc019SAndroid Build Coastguard Worker {
2909*d83cc019SAndroid Build Coastguard Worker 	if (pipe->display->first_commit || (s == COMMIT_UNIVERSAL &&
2910*d83cc019SAndroid Build Coastguard Worker 	     igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION))) {
2911*d83cc019SAndroid Build Coastguard Worker 		int ret;
2912*d83cc019SAndroid Build Coastguard Worker 
2913*d83cc019SAndroid Build Coastguard Worker 		ret = igt_plane_fixup_rotation(plane, pipe);
2914*d83cc019SAndroid Build Coastguard Worker 		CHECK_RETURN(ret, fail_on_error);
2915*d83cc019SAndroid Build Coastguard Worker 	}
2916*d83cc019SAndroid Build Coastguard Worker 
2917*d83cc019SAndroid Build Coastguard Worker 	if (plane->type == DRM_PLANE_TYPE_CURSOR && s == COMMIT_LEGACY) {
2918*d83cc019SAndroid Build Coastguard Worker 		return igt_cursor_commit_legacy(plane, pipe, fail_on_error);
2919*d83cc019SAndroid Build Coastguard Worker 	} else if (plane->type == DRM_PLANE_TYPE_PRIMARY && s == COMMIT_LEGACY &&
2920*d83cc019SAndroid Build Coastguard Worker 		plane == igt_pipe_get_plane_type(plane->pipe, DRM_PLANE_TYPE_PRIMARY)) {
2921*d83cc019SAndroid Build Coastguard Worker 		return igt_primary_plane_commit_legacy(plane, pipe,
2922*d83cc019SAndroid Build Coastguard Worker 						       fail_on_error);
2923*d83cc019SAndroid Build Coastguard Worker 	} else {
2924*d83cc019SAndroid Build Coastguard Worker 		return igt_drm_plane_commit(plane, pipe, fail_on_error);
2925*d83cc019SAndroid Build Coastguard Worker 	}
2926*d83cc019SAndroid Build Coastguard Worker }
2927*d83cc019SAndroid Build Coastguard Worker 
is_atomic_prop(enum igt_atomic_crtc_properties prop)2928*d83cc019SAndroid Build Coastguard Worker static bool is_atomic_prop(enum igt_atomic_crtc_properties prop)
2929*d83cc019SAndroid Build Coastguard Worker {
2930*d83cc019SAndroid Build Coastguard Worker        if (prop == IGT_CRTC_MODE_ID ||
2931*d83cc019SAndroid Build Coastguard Worker 	   prop == IGT_CRTC_ACTIVE ||
2932*d83cc019SAndroid Build Coastguard Worker 	   prop == IGT_CRTC_OUT_FENCE_PTR)
2933*d83cc019SAndroid Build Coastguard Worker 		return true;
2934*d83cc019SAndroid Build Coastguard Worker 
2935*d83cc019SAndroid Build Coastguard Worker 	return false;
2936*d83cc019SAndroid Build Coastguard Worker }
2937*d83cc019SAndroid Build Coastguard Worker 
2938*d83cc019SAndroid Build Coastguard Worker /*
2939*d83cc019SAndroid Build Coastguard Worker  * Commit all plane changes to an output.  Note that if @s is COMMIT_LEGACY,
2940*d83cc019SAndroid Build Coastguard Worker  * enabling/disabling the primary plane will also enable/disable the CRTC.
2941*d83cc019SAndroid Build Coastguard Worker  *
2942*d83cc019SAndroid Build Coastguard Worker  * If @fail_on_error is true, any failure to commit plane state will lead
2943*d83cc019SAndroid Build Coastguard Worker  * to subtest failure in the specific function where the failure occurs.
2944*d83cc019SAndroid Build Coastguard Worker  * Otherwise, the first error code encountered will be returned and no
2945*d83cc019SAndroid Build Coastguard Worker  * further programming will take place, which may result in some changes
2946*d83cc019SAndroid Build Coastguard Worker  * taking effect and others not taking effect.
2947*d83cc019SAndroid Build Coastguard Worker  */
igt_pipe_commit(igt_pipe_t * pipe,enum igt_commit_style s,bool fail_on_error)2948*d83cc019SAndroid Build Coastguard Worker static int igt_pipe_commit(igt_pipe_t *pipe,
2949*d83cc019SAndroid Build Coastguard Worker 			   enum igt_commit_style s,
2950*d83cc019SAndroid Build Coastguard Worker 			   bool fail_on_error)
2951*d83cc019SAndroid Build Coastguard Worker {
2952*d83cc019SAndroid Build Coastguard Worker 	int i;
2953*d83cc019SAndroid Build Coastguard Worker 	int ret;
2954*d83cc019SAndroid Build Coastguard Worker 
2955*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++)
2956*d83cc019SAndroid Build Coastguard Worker 		if (igt_pipe_obj_is_prop_changed(pipe, i) &&
2957*d83cc019SAndroid Build Coastguard Worker 		    !is_atomic_prop(i)) {
2958*d83cc019SAndroid Build Coastguard Worker 			igt_assert(pipe->props[i]);
2959*d83cc019SAndroid Build Coastguard Worker 
2960*d83cc019SAndroid Build Coastguard Worker 			ret = drmModeObjectSetProperty(pipe->display->drm_fd,
2961*d83cc019SAndroid Build Coastguard Worker 				pipe->crtc_id, DRM_MODE_OBJECT_CRTC,
2962*d83cc019SAndroid Build Coastguard Worker 				pipe->props[i], pipe->values[i]);
2963*d83cc019SAndroid Build Coastguard Worker 
2964*d83cc019SAndroid Build Coastguard Worker 			CHECK_RETURN(ret, fail_on_error);
2965*d83cc019SAndroid Build Coastguard Worker 		}
2966*d83cc019SAndroid Build Coastguard Worker 
2967*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < pipe->n_planes; i++) {
2968*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane = &pipe->planes[i];
2969*d83cc019SAndroid Build Coastguard Worker 
2970*d83cc019SAndroid Build Coastguard Worker 		/* skip planes that are handled by another pipe */
2971*d83cc019SAndroid Build Coastguard Worker 		if (plane->ref->pipe != pipe)
2972*d83cc019SAndroid Build Coastguard Worker 			continue;
2973*d83cc019SAndroid Build Coastguard Worker 
2974*d83cc019SAndroid Build Coastguard Worker 		ret = igt_plane_commit(plane, pipe, s, fail_on_error);
2975*d83cc019SAndroid Build Coastguard Worker 		CHECK_RETURN(ret, fail_on_error);
2976*d83cc019SAndroid Build Coastguard Worker 	}
2977*d83cc019SAndroid Build Coastguard Worker 
2978*d83cc019SAndroid Build Coastguard Worker 	return 0;
2979*d83cc019SAndroid Build Coastguard Worker }
2980*d83cc019SAndroid Build Coastguard Worker 
igt_output_commit(igt_output_t * output,enum igt_commit_style s,bool fail_on_error)2981*d83cc019SAndroid Build Coastguard Worker static int igt_output_commit(igt_output_t *output,
2982*d83cc019SAndroid Build Coastguard Worker 			     enum igt_commit_style s,
2983*d83cc019SAndroid Build Coastguard Worker 			     bool fail_on_error)
2984*d83cc019SAndroid Build Coastguard Worker {
2985*d83cc019SAndroid Build Coastguard Worker 	int i, ret;
2986*d83cc019SAndroid Build Coastguard Worker 
2987*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < IGT_NUM_CONNECTOR_PROPS; i++) {
2988*d83cc019SAndroid Build Coastguard Worker 		if (!igt_output_is_prop_changed(output, i))
2989*d83cc019SAndroid Build Coastguard Worker 			continue;
2990*d83cc019SAndroid Build Coastguard Worker 
2991*d83cc019SAndroid Build Coastguard Worker 		/* CRTC_ID is set by calling drmModeSetCrtc in the legacy path. */
2992*d83cc019SAndroid Build Coastguard Worker 		if (i == IGT_CONNECTOR_CRTC_ID)
2993*d83cc019SAndroid Build Coastguard Worker 			continue;
2994*d83cc019SAndroid Build Coastguard Worker 
2995*d83cc019SAndroid Build Coastguard Worker 		igt_assert(output->props[i]);
2996*d83cc019SAndroid Build Coastguard Worker 
2997*d83cc019SAndroid Build Coastguard Worker 		if (s == COMMIT_LEGACY)
2998*d83cc019SAndroid Build Coastguard Worker 			ret = drmModeConnectorSetProperty(output->display->drm_fd, output->id,
2999*d83cc019SAndroid Build Coastguard Worker 							  output->props[i], output->values[i]);
3000*d83cc019SAndroid Build Coastguard Worker 		else
3001*d83cc019SAndroid Build Coastguard Worker 			ret = drmModeObjectSetProperty(output->display->drm_fd, output->id,
3002*d83cc019SAndroid Build Coastguard Worker 						       DRM_MODE_OBJECT_CONNECTOR,
3003*d83cc019SAndroid Build Coastguard Worker 						       output->props[i], output->values[i]);
3004*d83cc019SAndroid Build Coastguard Worker 
3005*d83cc019SAndroid Build Coastguard Worker 		CHECK_RETURN(ret, fail_on_error);
3006*d83cc019SAndroid Build Coastguard Worker 	}
3007*d83cc019SAndroid Build Coastguard Worker 
3008*d83cc019SAndroid Build Coastguard Worker 	return 0;
3009*d83cc019SAndroid Build Coastguard Worker }
3010*d83cc019SAndroid Build Coastguard Worker 
igt_mode_object_get_prop(igt_display_t * display,uint32_t object_type,uint32_t object_id,uint32_t prop)3011*d83cc019SAndroid Build Coastguard Worker static uint64_t igt_mode_object_get_prop(igt_display_t *display,
3012*d83cc019SAndroid Build Coastguard Worker 					 uint32_t object_type,
3013*d83cc019SAndroid Build Coastguard Worker 					 uint32_t object_id,
3014*d83cc019SAndroid Build Coastguard Worker 					 uint32_t prop)
3015*d83cc019SAndroid Build Coastguard Worker {
3016*d83cc019SAndroid Build Coastguard Worker 	drmModeObjectPropertiesPtr proplist;
3017*d83cc019SAndroid Build Coastguard Worker 	bool found = false;
3018*d83cc019SAndroid Build Coastguard Worker 	int i;
3019*d83cc019SAndroid Build Coastguard Worker 	uint64_t ret;
3020*d83cc019SAndroid Build Coastguard Worker 
3021*d83cc019SAndroid Build Coastguard Worker 	proplist = drmModeObjectGetProperties(display->drm_fd, object_id, object_type);
3022*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < proplist->count_props; i++) {
3023*d83cc019SAndroid Build Coastguard Worker 		if (proplist->props[i] != prop)
3024*d83cc019SAndroid Build Coastguard Worker 			continue;
3025*d83cc019SAndroid Build Coastguard Worker 
3026*d83cc019SAndroid Build Coastguard Worker 		found = true;
3027*d83cc019SAndroid Build Coastguard Worker 		break;
3028*d83cc019SAndroid Build Coastguard Worker 	}
3029*d83cc019SAndroid Build Coastguard Worker 
3030*d83cc019SAndroid Build Coastguard Worker 	igt_assert(found);
3031*d83cc019SAndroid Build Coastguard Worker 
3032*d83cc019SAndroid Build Coastguard Worker 	ret = proplist->prop_values[i];
3033*d83cc019SAndroid Build Coastguard Worker 
3034*d83cc019SAndroid Build Coastguard Worker 	drmModeFreeObjectProperties(proplist);
3035*d83cc019SAndroid Build Coastguard Worker 	return ret;
3036*d83cc019SAndroid Build Coastguard Worker }
3037*d83cc019SAndroid Build Coastguard Worker 
3038*d83cc019SAndroid Build Coastguard Worker /**
3039*d83cc019SAndroid Build Coastguard Worker  * igt_plane_get_prop:
3040*d83cc019SAndroid Build Coastguard Worker  * @plane: Target plane.
3041*d83cc019SAndroid Build Coastguard Worker  * @prop: Property to check.
3042*d83cc019SAndroid Build Coastguard Worker  *
3043*d83cc019SAndroid Build Coastguard Worker  * Return current value on a plane for a given property.
3044*d83cc019SAndroid Build Coastguard Worker  *
3045*d83cc019SAndroid Build Coastguard Worker  * Returns: The value the property is set to, if this
3046*d83cc019SAndroid Build Coastguard Worker  * is a blob, the blob id is returned. This can be passed
3047*d83cc019SAndroid Build Coastguard Worker  * to drmModeGetPropertyBlob() to get the contents of the blob.
3048*d83cc019SAndroid Build Coastguard Worker  */
igt_plane_get_prop(igt_plane_t * plane,enum igt_atomic_plane_properties prop)3049*d83cc019SAndroid Build Coastguard Worker uint64_t igt_plane_get_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
3050*d83cc019SAndroid Build Coastguard Worker {
3051*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_plane_has_prop(plane, prop));
3052*d83cc019SAndroid Build Coastguard Worker 
3053*d83cc019SAndroid Build Coastguard Worker 	return igt_mode_object_get_prop(plane->pipe->display, DRM_MODE_OBJECT_PLANE,
3054*d83cc019SAndroid Build Coastguard Worker 					plane->drm_plane->plane_id, plane->props[prop]);
3055*d83cc019SAndroid Build Coastguard Worker }
3056*d83cc019SAndroid Build Coastguard Worker 
igt_mode_object_get_prop_enum_value(int drm_fd,uint32_t id,const char * str,uint64_t * val)3057*d83cc019SAndroid Build Coastguard Worker static bool igt_mode_object_get_prop_enum_value(int drm_fd, uint32_t id, const char *str, uint64_t *val)
3058*d83cc019SAndroid Build Coastguard Worker {
3059*d83cc019SAndroid Build Coastguard Worker 	drmModePropertyPtr prop = drmModeGetProperty(drm_fd, id);
3060*d83cc019SAndroid Build Coastguard Worker 	int i;
3061*d83cc019SAndroid Build Coastguard Worker 
3062*d83cc019SAndroid Build Coastguard Worker 	igt_assert(id);
3063*d83cc019SAndroid Build Coastguard Worker 	igt_assert(prop);
3064*d83cc019SAndroid Build Coastguard Worker 
3065*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < prop->count_enums; i++)
3066*d83cc019SAndroid Build Coastguard Worker 		if (!strcmp(str, prop->enums[i].name)) {
3067*d83cc019SAndroid Build Coastguard Worker 			*val = prop->enums[i].value;
3068*d83cc019SAndroid Build Coastguard Worker 			drmModeFreeProperty(prop);
3069*d83cc019SAndroid Build Coastguard Worker 			return true;
3070*d83cc019SAndroid Build Coastguard Worker 		}
3071*d83cc019SAndroid Build Coastguard Worker 
3072*d83cc019SAndroid Build Coastguard Worker 	return false;
3073*d83cc019SAndroid Build Coastguard Worker }
3074*d83cc019SAndroid Build Coastguard Worker 
igt_plane_try_prop_enum(igt_plane_t * plane,enum igt_atomic_plane_properties prop,const char * val)3075*d83cc019SAndroid Build Coastguard Worker bool igt_plane_try_prop_enum(igt_plane_t *plane,
3076*d83cc019SAndroid Build Coastguard Worker 			     enum igt_atomic_plane_properties prop,
3077*d83cc019SAndroid Build Coastguard Worker 			     const char *val)
3078*d83cc019SAndroid Build Coastguard Worker {
3079*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = plane->pipe->display;
3080*d83cc019SAndroid Build Coastguard Worker 	uint64_t uval;
3081*d83cc019SAndroid Build Coastguard Worker 
3082*d83cc019SAndroid Build Coastguard Worker 	igt_assert(plane->props[prop]);
3083*d83cc019SAndroid Build Coastguard Worker 
3084*d83cc019SAndroid Build Coastguard Worker 	if (!igt_mode_object_get_prop_enum_value(display->drm_fd,
3085*d83cc019SAndroid Build Coastguard Worker 						 plane->props[prop], val, &uval))
3086*d83cc019SAndroid Build Coastguard Worker 		return false;
3087*d83cc019SAndroid Build Coastguard Worker 
3088*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, prop, uval);
3089*d83cc019SAndroid Build Coastguard Worker 	return true;
3090*d83cc019SAndroid Build Coastguard Worker }
3091*d83cc019SAndroid Build Coastguard Worker 
igt_plane_set_prop_enum(igt_plane_t * plane,enum igt_atomic_plane_properties prop,const char * val)3092*d83cc019SAndroid Build Coastguard Worker void igt_plane_set_prop_enum(igt_plane_t *plane,
3093*d83cc019SAndroid Build Coastguard Worker 			     enum igt_atomic_plane_properties prop,
3094*d83cc019SAndroid Build Coastguard Worker 			     const char *val)
3095*d83cc019SAndroid Build Coastguard Worker {
3096*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_plane_try_prop_enum(plane, prop, val));
3097*d83cc019SAndroid Build Coastguard Worker }
3098*d83cc019SAndroid Build Coastguard Worker 
3099*d83cc019SAndroid Build Coastguard Worker /**
3100*d83cc019SAndroid Build Coastguard Worker  * igt_plane_replace_prop_blob:
3101*d83cc019SAndroid Build Coastguard Worker  * @plane: plane to set property on.
3102*d83cc019SAndroid Build Coastguard Worker  * @prop: property for which the blob will be replaced.
3103*d83cc019SAndroid Build Coastguard Worker  * @ptr: Pointer to contents for the property.
3104*d83cc019SAndroid Build Coastguard Worker  * @length: Length of contents.
3105*d83cc019SAndroid Build Coastguard Worker  *
3106*d83cc019SAndroid Build Coastguard Worker  * This function will destroy the old property blob for the given property,
3107*d83cc019SAndroid Build Coastguard Worker  * and will create a new property blob with the values passed to this function.
3108*d83cc019SAndroid Build Coastguard Worker  *
3109*d83cc019SAndroid Build Coastguard Worker  * The new property blob will be committed when you call igt_display_commit(),
3110*d83cc019SAndroid Build Coastguard Worker  * igt_display_commit2() or igt_display_commit_atomic().
3111*d83cc019SAndroid Build Coastguard Worker  */
3112*d83cc019SAndroid Build Coastguard Worker void
igt_plane_replace_prop_blob(igt_plane_t * plane,enum igt_atomic_plane_properties prop,const void * ptr,size_t length)3113*d83cc019SAndroid Build Coastguard Worker igt_plane_replace_prop_blob(igt_plane_t *plane, enum igt_atomic_plane_properties prop, const void *ptr, size_t length)
3114*d83cc019SAndroid Build Coastguard Worker {
3115*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = plane->pipe->display;
3116*d83cc019SAndroid Build Coastguard Worker 	uint64_t *blob = &plane->values[prop];
3117*d83cc019SAndroid Build Coastguard Worker 	uint32_t blob_id = 0;
3118*d83cc019SAndroid Build Coastguard Worker 
3119*d83cc019SAndroid Build Coastguard Worker 	if (*blob != 0)
3120*d83cc019SAndroid Build Coastguard Worker 		igt_assert(drmModeDestroyPropertyBlob(display->drm_fd,
3121*d83cc019SAndroid Build Coastguard Worker 						      *blob) == 0);
3122*d83cc019SAndroid Build Coastguard Worker 
3123*d83cc019SAndroid Build Coastguard Worker 	if (length > 0)
3124*d83cc019SAndroid Build Coastguard Worker 		igt_assert(drmModeCreatePropertyBlob(display->drm_fd,
3125*d83cc019SAndroid Build Coastguard Worker 						     ptr, length, &blob_id) == 0);
3126*d83cc019SAndroid Build Coastguard Worker 
3127*d83cc019SAndroid Build Coastguard Worker 	*blob = blob_id;
3128*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_changed(plane, prop);
3129*d83cc019SAndroid Build Coastguard Worker }
3130*d83cc019SAndroid Build Coastguard Worker 
3131*d83cc019SAndroid Build Coastguard Worker /**
3132*d83cc019SAndroid Build Coastguard Worker  * igt_output_get_prop:
3133*d83cc019SAndroid Build Coastguard Worker  * @output: Target output.
3134*d83cc019SAndroid Build Coastguard Worker  * @prop: Property to return.
3135*d83cc019SAndroid Build Coastguard Worker  *
3136*d83cc019SAndroid Build Coastguard Worker  * Return current value on an output for a given property.
3137*d83cc019SAndroid Build Coastguard Worker  *
3138*d83cc019SAndroid Build Coastguard Worker  * Returns: The value the property is set to, if this
3139*d83cc019SAndroid Build Coastguard Worker  * is a blob, the blob id is returned. This can be passed
3140*d83cc019SAndroid Build Coastguard Worker  * to drmModeGetPropertyBlob() to get the contents of the blob.
3141*d83cc019SAndroid Build Coastguard Worker  */
igt_output_get_prop(igt_output_t * output,enum igt_atomic_connector_properties prop)3142*d83cc019SAndroid Build Coastguard Worker uint64_t igt_output_get_prop(igt_output_t *output, enum igt_atomic_connector_properties prop)
3143*d83cc019SAndroid Build Coastguard Worker {
3144*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_output_has_prop(output, prop));
3145*d83cc019SAndroid Build Coastguard Worker 
3146*d83cc019SAndroid Build Coastguard Worker 	return igt_mode_object_get_prop(output->display, DRM_MODE_OBJECT_CONNECTOR,
3147*d83cc019SAndroid Build Coastguard Worker 					output->id, output->props[prop]);
3148*d83cc019SAndroid Build Coastguard Worker }
3149*d83cc019SAndroid Build Coastguard Worker 
igt_output_try_prop_enum(igt_output_t * output,enum igt_atomic_connector_properties prop,const char * val)3150*d83cc019SAndroid Build Coastguard Worker bool igt_output_try_prop_enum(igt_output_t *output,
3151*d83cc019SAndroid Build Coastguard Worker 			      enum igt_atomic_connector_properties prop,
3152*d83cc019SAndroid Build Coastguard Worker 			      const char *val)
3153*d83cc019SAndroid Build Coastguard Worker {
3154*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = output->display;
3155*d83cc019SAndroid Build Coastguard Worker 	uint64_t uval;
3156*d83cc019SAndroid Build Coastguard Worker 
3157*d83cc019SAndroid Build Coastguard Worker 	igt_assert(output->props[prop]);
3158*d83cc019SAndroid Build Coastguard Worker 
3159*d83cc019SAndroid Build Coastguard Worker 	if (!igt_mode_object_get_prop_enum_value(display->drm_fd,
3160*d83cc019SAndroid Build Coastguard Worker 						 output->props[prop], val, &uval))
3161*d83cc019SAndroid Build Coastguard Worker 		return false;
3162*d83cc019SAndroid Build Coastguard Worker 
3163*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_prop_value(output, prop, uval);
3164*d83cc019SAndroid Build Coastguard Worker 	return true;
3165*d83cc019SAndroid Build Coastguard Worker }
3166*d83cc019SAndroid Build Coastguard Worker 
igt_output_set_prop_enum(igt_output_t * output,enum igt_atomic_connector_properties prop,const char * val)3167*d83cc019SAndroid Build Coastguard Worker void igt_output_set_prop_enum(igt_output_t *output,
3168*d83cc019SAndroid Build Coastguard Worker 			      enum igt_atomic_connector_properties prop,
3169*d83cc019SAndroid Build Coastguard Worker 			      const char *val)
3170*d83cc019SAndroid Build Coastguard Worker {
3171*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_output_try_prop_enum(output, prop, val));
3172*d83cc019SAndroid Build Coastguard Worker }
3173*d83cc019SAndroid Build Coastguard Worker 
3174*d83cc019SAndroid Build Coastguard Worker /**
3175*d83cc019SAndroid Build Coastguard Worker  * igt_output_replace_prop_blob:
3176*d83cc019SAndroid Build Coastguard Worker  * @output: output to set property on.
3177*d83cc019SAndroid Build Coastguard Worker  * @prop: property for which the blob will be replaced.
3178*d83cc019SAndroid Build Coastguard Worker  * @ptr: Pointer to contents for the property.
3179*d83cc019SAndroid Build Coastguard Worker  * @length: Length of contents.
3180*d83cc019SAndroid Build Coastguard Worker  *
3181*d83cc019SAndroid Build Coastguard Worker  * This function will destroy the old property blob for the given property,
3182*d83cc019SAndroid Build Coastguard Worker  * and will create a new property blob with the values passed to this function.
3183*d83cc019SAndroid Build Coastguard Worker  *
3184*d83cc019SAndroid Build Coastguard Worker  * The new property blob will be committed when you call igt_display_commit(),
3185*d83cc019SAndroid Build Coastguard Worker  * igt_display_commit2() or igt_display_commit_atomic().
3186*d83cc019SAndroid Build Coastguard Worker  */
3187*d83cc019SAndroid Build Coastguard Worker void
igt_output_replace_prop_blob(igt_output_t * output,enum igt_atomic_connector_properties prop,const void * ptr,size_t length)3188*d83cc019SAndroid Build Coastguard Worker igt_output_replace_prop_blob(igt_output_t *output, enum igt_atomic_connector_properties prop, const void *ptr, size_t length)
3189*d83cc019SAndroid Build Coastguard Worker {
3190*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = output->display;
3191*d83cc019SAndroid Build Coastguard Worker 	uint64_t *blob = &output->values[prop];
3192*d83cc019SAndroid Build Coastguard Worker 	uint32_t blob_id = 0;
3193*d83cc019SAndroid Build Coastguard Worker 
3194*d83cc019SAndroid Build Coastguard Worker 	if (*blob != 0)
3195*d83cc019SAndroid Build Coastguard Worker 		igt_assert(drmModeDestroyPropertyBlob(display->drm_fd,
3196*d83cc019SAndroid Build Coastguard Worker 						      *blob) == 0);
3197*d83cc019SAndroid Build Coastguard Worker 
3198*d83cc019SAndroid Build Coastguard Worker 	if (length > 0)
3199*d83cc019SAndroid Build Coastguard Worker 		igt_assert(drmModeCreatePropertyBlob(display->drm_fd,
3200*d83cc019SAndroid Build Coastguard Worker 						     ptr, length, &blob_id) == 0);
3201*d83cc019SAndroid Build Coastguard Worker 
3202*d83cc019SAndroid Build Coastguard Worker 	*blob = blob_id;
3203*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_prop_changed(output, prop);
3204*d83cc019SAndroid Build Coastguard Worker }
3205*d83cc019SAndroid Build Coastguard Worker 
3206*d83cc019SAndroid Build Coastguard Worker /**
3207*d83cc019SAndroid Build Coastguard Worker  * igt_pipe_obj_get_prop:
3208*d83cc019SAndroid Build Coastguard Worker  * @pipe: Target pipe.
3209*d83cc019SAndroid Build Coastguard Worker  * @prop: Property to return.
3210*d83cc019SAndroid Build Coastguard Worker  *
3211*d83cc019SAndroid Build Coastguard Worker  * Return current value on a pipe for a given property.
3212*d83cc019SAndroid Build Coastguard Worker  *
3213*d83cc019SAndroid Build Coastguard Worker  * Returns: The value the property is set to, if this
3214*d83cc019SAndroid Build Coastguard Worker  * is a blob, the blob id is returned. This can be passed
3215*d83cc019SAndroid Build Coastguard Worker  * to drmModeGetPropertyBlob() to get the contents of the blob.
3216*d83cc019SAndroid Build Coastguard Worker  */
igt_pipe_obj_get_prop(igt_pipe_t * pipe,enum igt_atomic_crtc_properties prop)3217*d83cc019SAndroid Build Coastguard Worker uint64_t igt_pipe_obj_get_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
3218*d83cc019SAndroid Build Coastguard Worker {
3219*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_pipe_obj_has_prop(pipe, prop));
3220*d83cc019SAndroid Build Coastguard Worker 
3221*d83cc019SAndroid Build Coastguard Worker 	return igt_mode_object_get_prop(pipe->display, DRM_MODE_OBJECT_CRTC,
3222*d83cc019SAndroid Build Coastguard Worker 					pipe->crtc_id, pipe->props[prop]);
3223*d83cc019SAndroid Build Coastguard Worker }
3224*d83cc019SAndroid Build Coastguard Worker 
igt_pipe_obj_try_prop_enum(igt_pipe_t * pipe_obj,enum igt_atomic_crtc_properties prop,const char * val)3225*d83cc019SAndroid Build Coastguard Worker bool igt_pipe_obj_try_prop_enum(igt_pipe_t *pipe_obj,
3226*d83cc019SAndroid Build Coastguard Worker 				enum igt_atomic_crtc_properties prop,
3227*d83cc019SAndroid Build Coastguard Worker 				const char *val)
3228*d83cc019SAndroid Build Coastguard Worker {
3229*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe_obj->display;
3230*d83cc019SAndroid Build Coastguard Worker 	uint64_t uval;
3231*d83cc019SAndroid Build Coastguard Worker 
3232*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pipe_obj->props[prop]);
3233*d83cc019SAndroid Build Coastguard Worker 
3234*d83cc019SAndroid Build Coastguard Worker 	if (!igt_mode_object_get_prop_enum_value(display->drm_fd,
3235*d83cc019SAndroid Build Coastguard Worker 						 pipe_obj->props[prop], val, &uval))
3236*d83cc019SAndroid Build Coastguard Worker 		return false;
3237*d83cc019SAndroid Build Coastguard Worker 
3238*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_obj_set_prop_value(pipe_obj, prop, uval);
3239*d83cc019SAndroid Build Coastguard Worker 	return true;
3240*d83cc019SAndroid Build Coastguard Worker }
3241*d83cc019SAndroid Build Coastguard Worker 
igt_pipe_obj_set_prop_enum(igt_pipe_t * pipe_obj,enum igt_atomic_crtc_properties prop,const char * val)3242*d83cc019SAndroid Build Coastguard Worker void igt_pipe_obj_set_prop_enum(igt_pipe_t *pipe_obj,
3243*d83cc019SAndroid Build Coastguard Worker 				enum igt_atomic_crtc_properties prop,
3244*d83cc019SAndroid Build Coastguard Worker 				const char *val)
3245*d83cc019SAndroid Build Coastguard Worker {
3246*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_pipe_obj_try_prop_enum(pipe_obj, prop, val));
3247*d83cc019SAndroid Build Coastguard Worker }
3248*d83cc019SAndroid Build Coastguard Worker 
3249*d83cc019SAndroid Build Coastguard Worker /**
3250*d83cc019SAndroid Build Coastguard Worker  * igt_pipe_obj_replace_prop_blob:
3251*d83cc019SAndroid Build Coastguard Worker  * @pipe: pipe to set property on.
3252*d83cc019SAndroid Build Coastguard Worker  * @prop: property for which the blob will be replaced.
3253*d83cc019SAndroid Build Coastguard Worker  * @ptr: Pointer to contents for the property.
3254*d83cc019SAndroid Build Coastguard Worker  * @length: Length of contents.
3255*d83cc019SAndroid Build Coastguard Worker  *
3256*d83cc019SAndroid Build Coastguard Worker  * This function will destroy the old property blob for the given property,
3257*d83cc019SAndroid Build Coastguard Worker  * and will create a new property blob with the values passed to this function.
3258*d83cc019SAndroid Build Coastguard Worker  *
3259*d83cc019SAndroid Build Coastguard Worker  * The new property blob will be committed when you call igt_display_commit(),
3260*d83cc019SAndroid Build Coastguard Worker  * igt_display_commit2() or igt_display_commit_atomic().
3261*d83cc019SAndroid Build Coastguard Worker  *
3262*d83cc019SAndroid Build Coastguard Worker  * Please use igt_output_override_mode() if you want to set #IGT_CRTC_MODE_ID,
3263*d83cc019SAndroid Build Coastguard Worker  * it works better with legacy commit.
3264*d83cc019SAndroid Build Coastguard Worker  */
3265*d83cc019SAndroid Build Coastguard Worker void
igt_pipe_obj_replace_prop_blob(igt_pipe_t * pipe,enum igt_atomic_crtc_properties prop,const void * ptr,size_t length)3266*d83cc019SAndroid Build Coastguard Worker igt_pipe_obj_replace_prop_blob(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop, const void *ptr, size_t length)
3267*d83cc019SAndroid Build Coastguard Worker {
3268*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
3269*d83cc019SAndroid Build Coastguard Worker 	uint64_t *blob = &pipe->values[prop];
3270*d83cc019SAndroid Build Coastguard Worker 	uint32_t blob_id = 0;
3271*d83cc019SAndroid Build Coastguard Worker 
3272*d83cc019SAndroid Build Coastguard Worker 	if (*blob != 0)
3273*d83cc019SAndroid Build Coastguard Worker 		igt_assert(drmModeDestroyPropertyBlob(display->drm_fd,
3274*d83cc019SAndroid Build Coastguard Worker 						      *blob) == 0);
3275*d83cc019SAndroid Build Coastguard Worker 
3276*d83cc019SAndroid Build Coastguard Worker 	if (length > 0)
3277*d83cc019SAndroid Build Coastguard Worker 		igt_assert(drmModeCreatePropertyBlob(display->drm_fd,
3278*d83cc019SAndroid Build Coastguard Worker 						     ptr, length, &blob_id) == 0);
3279*d83cc019SAndroid Build Coastguard Worker 
3280*d83cc019SAndroid Build Coastguard Worker 	*blob = blob_id;
3281*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_obj_set_prop_changed(pipe, prop);
3282*d83cc019SAndroid Build Coastguard Worker }
3283*d83cc019SAndroid Build Coastguard Worker 
3284*d83cc019SAndroid Build Coastguard Worker /*
3285*d83cc019SAndroid Build Coastguard Worker  * Add crtc property changes to the atomic property set
3286*d83cc019SAndroid Build Coastguard Worker  */
igt_atomic_prepare_crtc_commit(igt_pipe_t * pipe_obj,drmModeAtomicReq * req)3287*d83cc019SAndroid Build Coastguard Worker static void igt_atomic_prepare_crtc_commit(igt_pipe_t *pipe_obj, drmModeAtomicReq *req)
3288*d83cc019SAndroid Build Coastguard Worker {
3289*d83cc019SAndroid Build Coastguard Worker 	int i;
3290*d83cc019SAndroid Build Coastguard Worker 
3291*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
3292*d83cc019SAndroid Build Coastguard Worker 		if (!igt_pipe_obj_is_prop_changed(pipe_obj, i))
3293*d83cc019SAndroid Build Coastguard Worker 			continue;
3294*d83cc019SAndroid Build Coastguard Worker 
3295*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Pipe %s: Setting property \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
3296*d83cc019SAndroid Build Coastguard Worker 			kmstest_pipe_name(pipe_obj->pipe), igt_crtc_prop_names[i],
3297*d83cc019SAndroid Build Coastguard Worker 			pipe_obj->values[i], pipe_obj->values[i]);
3298*d83cc019SAndroid Build Coastguard Worker 
3299*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lt(0, drmModeAtomicAddProperty(req, pipe_obj->crtc_id, pipe_obj->props[i], pipe_obj->values[i]));
3300*d83cc019SAndroid Build Coastguard Worker 	}
3301*d83cc019SAndroid Build Coastguard Worker 
3302*d83cc019SAndroid Build Coastguard Worker 	if (pipe_obj->out_fence_fd != -1) {
3303*d83cc019SAndroid Build Coastguard Worker 		close(pipe_obj->out_fence_fd);
3304*d83cc019SAndroid Build Coastguard Worker 		pipe_obj->out_fence_fd = -1;
3305*d83cc019SAndroid Build Coastguard Worker 	}
3306*d83cc019SAndroid Build Coastguard Worker }
3307*d83cc019SAndroid Build Coastguard Worker 
3308*d83cc019SAndroid Build Coastguard Worker /*
3309*d83cc019SAndroid Build Coastguard Worker  * Add connector property changes to the atomic property set
3310*d83cc019SAndroid Build Coastguard Worker  */
igt_atomic_prepare_connector_commit(igt_output_t * output,drmModeAtomicReq * req)3311*d83cc019SAndroid Build Coastguard Worker static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAtomicReq *req)
3312*d83cc019SAndroid Build Coastguard Worker {
3313*d83cc019SAndroid Build Coastguard Worker 
3314*d83cc019SAndroid Build Coastguard Worker 	int i;
3315*d83cc019SAndroid Build Coastguard Worker 
3316*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < IGT_NUM_CONNECTOR_PROPS; i++) {
3317*d83cc019SAndroid Build Coastguard Worker 		if (!igt_output_is_prop_changed(output, i))
3318*d83cc019SAndroid Build Coastguard Worker 			continue;
3319*d83cc019SAndroid Build Coastguard Worker 
3320*d83cc019SAndroid Build Coastguard Worker 		/* it's an error to try an unsupported feature */
3321*d83cc019SAndroid Build Coastguard Worker 		igt_assert(output->props[i]);
3322*d83cc019SAndroid Build Coastguard Worker 
3323*d83cc019SAndroid Build Coastguard Worker 		igt_debug("%s: Setting property \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
3324*d83cc019SAndroid Build Coastguard Worker 			  igt_output_name(output), igt_connector_prop_names[i],
3325*d83cc019SAndroid Build Coastguard Worker 			  output->values[i], output->values[i]);
3326*d83cc019SAndroid Build Coastguard Worker 
3327*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lt(0, drmModeAtomicAddProperty(req,
3328*d83cc019SAndroid Build Coastguard Worker 					  output->config.connector->connector_id,
3329*d83cc019SAndroid Build Coastguard Worker 					  output->props[i],
3330*d83cc019SAndroid Build Coastguard Worker 					  output->values[i]));
3331*d83cc019SAndroid Build Coastguard Worker 	}
3332*d83cc019SAndroid Build Coastguard Worker }
3333*d83cc019SAndroid Build Coastguard Worker 
3334*d83cc019SAndroid Build Coastguard Worker /*
3335*d83cc019SAndroid Build Coastguard Worker  * Commit all the changes of all the planes,crtcs, connectors
3336*d83cc019SAndroid Build Coastguard Worker  * atomically using drmModeAtomicCommit()
3337*d83cc019SAndroid Build Coastguard Worker  */
igt_atomic_commit(igt_display_t * display,uint32_t flags,void * user_data)3338*d83cc019SAndroid Build Coastguard Worker static int igt_atomic_commit(igt_display_t *display, uint32_t flags, void *user_data)
3339*d83cc019SAndroid Build Coastguard Worker {
3340*d83cc019SAndroid Build Coastguard Worker 
3341*d83cc019SAndroid Build Coastguard Worker 	int ret = 0, i;
3342*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
3343*d83cc019SAndroid Build Coastguard Worker 	drmModeAtomicReq *req;
3344*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
3345*d83cc019SAndroid Build Coastguard Worker 
3346*d83cc019SAndroid Build Coastguard Worker 	if (display->is_atomic != 1)
3347*d83cc019SAndroid Build Coastguard Worker 		return -1;
3348*d83cc019SAndroid Build Coastguard Worker 	req = drmModeAtomicAlloc();
3349*d83cc019SAndroid Build Coastguard Worker 
3350*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe(display, pipe) {
3351*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_t *pipe_obj = &display->pipes[pipe];
3352*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane;
3353*d83cc019SAndroid Build Coastguard Worker 
3354*d83cc019SAndroid Build Coastguard Worker 		/*
3355*d83cc019SAndroid Build Coastguard Worker 		 * Add CRTC Properties to the property set
3356*d83cc019SAndroid Build Coastguard Worker 		 */
3357*d83cc019SAndroid Build Coastguard Worker 		if (pipe_obj->changed)
3358*d83cc019SAndroid Build Coastguard Worker 			igt_atomic_prepare_crtc_commit(pipe_obj, req);
3359*d83cc019SAndroid Build Coastguard Worker 
3360*d83cc019SAndroid Build Coastguard Worker 		for_each_plane_on_pipe(display, pipe, plane) {
3361*d83cc019SAndroid Build Coastguard Worker 			/* skip planes that are handled by another pipe */
3362*d83cc019SAndroid Build Coastguard Worker 			if (plane->ref->pipe != pipe_obj)
3363*d83cc019SAndroid Build Coastguard Worker 				continue;
3364*d83cc019SAndroid Build Coastguard Worker 
3365*d83cc019SAndroid Build Coastguard Worker 			if (plane->changed)
3366*d83cc019SAndroid Build Coastguard Worker 				igt_atomic_prepare_plane_commit(plane, pipe_obj, req);
3367*d83cc019SAndroid Build Coastguard Worker 		}
3368*d83cc019SAndroid Build Coastguard Worker 
3369*d83cc019SAndroid Build Coastguard Worker 	}
3370*d83cc019SAndroid Build Coastguard Worker 
3371*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++) {
3372*d83cc019SAndroid Build Coastguard Worker 		output = &display->outputs[i];
3373*d83cc019SAndroid Build Coastguard Worker 
3374*d83cc019SAndroid Build Coastguard Worker 		if (!output->config.connector || !output->changed)
3375*d83cc019SAndroid Build Coastguard Worker 			continue;
3376*d83cc019SAndroid Build Coastguard Worker 
3377*d83cc019SAndroid Build Coastguard Worker 		LOG(display, "%s: preparing atomic, pipe: %s\n",
3378*d83cc019SAndroid Build Coastguard Worker 		    igt_output_name(output),
3379*d83cc019SAndroid Build Coastguard Worker 		    kmstest_pipe_name(output->config.pipe));
3380*d83cc019SAndroid Build Coastguard Worker 
3381*d83cc019SAndroid Build Coastguard Worker 		igt_atomic_prepare_connector_commit(output, req);
3382*d83cc019SAndroid Build Coastguard Worker 	}
3383*d83cc019SAndroid Build Coastguard Worker 
3384*d83cc019SAndroid Build Coastguard Worker 	ret = drmModeAtomicCommit(display->drm_fd, req, flags, user_data);
3385*d83cc019SAndroid Build Coastguard Worker 
3386*d83cc019SAndroid Build Coastguard Worker 	drmModeAtomicFree(req);
3387*d83cc019SAndroid Build Coastguard Worker 	return ret;
3388*d83cc019SAndroid Build Coastguard Worker 
3389*d83cc019SAndroid Build Coastguard Worker }
3390*d83cc019SAndroid Build Coastguard Worker 
3391*d83cc019SAndroid Build Coastguard Worker static void
display_commit_changed(igt_display_t * display,enum igt_commit_style s)3392*d83cc019SAndroid Build Coastguard Worker display_commit_changed(igt_display_t *display, enum igt_commit_style s)
3393*d83cc019SAndroid Build Coastguard Worker {
3394*d83cc019SAndroid Build Coastguard Worker 	int i;
3395*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
3396*d83cc019SAndroid Build Coastguard Worker 
3397*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe(display, pipe) {
3398*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_t *pipe_obj = &display->pipes[pipe];
3399*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane;
3400*d83cc019SAndroid Build Coastguard Worker 
3401*d83cc019SAndroid Build Coastguard Worker 		if (s == COMMIT_ATOMIC) {
3402*d83cc019SAndroid Build Coastguard Worker 			if (igt_pipe_obj_is_prop_changed(pipe_obj, IGT_CRTC_OUT_FENCE_PTR))
3403*d83cc019SAndroid Build Coastguard Worker 				igt_assert(pipe_obj->out_fence_fd >= 0);
3404*d83cc019SAndroid Build Coastguard Worker 
3405*d83cc019SAndroid Build Coastguard Worker 			pipe_obj->values[IGT_CRTC_OUT_FENCE_PTR] = 0;
3406*d83cc019SAndroid Build Coastguard Worker 			pipe_obj->changed = 0;
3407*d83cc019SAndroid Build Coastguard Worker 		} else {
3408*d83cc019SAndroid Build Coastguard Worker 			for (i = 0; i < IGT_NUM_CRTC_PROPS; i++)
3409*d83cc019SAndroid Build Coastguard Worker 				if (!is_atomic_prop(i))
3410*d83cc019SAndroid Build Coastguard Worker 					igt_pipe_obj_clear_prop_changed(pipe_obj, i);
3411*d83cc019SAndroid Build Coastguard Worker 
3412*d83cc019SAndroid Build Coastguard Worker 			if (s != COMMIT_UNIVERSAL) {
3413*d83cc019SAndroid Build Coastguard Worker 				igt_pipe_obj_clear_prop_changed(pipe_obj, IGT_CRTC_MODE_ID);
3414*d83cc019SAndroid Build Coastguard Worker 				igt_pipe_obj_clear_prop_changed(pipe_obj, IGT_CRTC_ACTIVE);
3415*d83cc019SAndroid Build Coastguard Worker 			}
3416*d83cc019SAndroid Build Coastguard Worker 		}
3417*d83cc019SAndroid Build Coastguard Worker 
3418*d83cc019SAndroid Build Coastguard Worker 		for_each_plane_on_pipe(display, pipe, plane) {
3419*d83cc019SAndroid Build Coastguard Worker 			if (s == COMMIT_ATOMIC) {
3420*d83cc019SAndroid Build Coastguard Worker 				int fd;
3421*d83cc019SAndroid Build Coastguard Worker 				plane->changed = 0;
3422*d83cc019SAndroid Build Coastguard Worker 
3423*d83cc019SAndroid Build Coastguard Worker 				fd = plane->values[IGT_PLANE_IN_FENCE_FD];
3424*d83cc019SAndroid Build Coastguard Worker 				if (fd != -1)
3425*d83cc019SAndroid Build Coastguard Worker 					close(fd);
3426*d83cc019SAndroid Build Coastguard Worker 
3427*d83cc019SAndroid Build Coastguard Worker 				/* reset fence_fd to prevent it from being set for the next commit */
3428*d83cc019SAndroid Build Coastguard Worker 				plane->values[IGT_PLANE_IN_FENCE_FD] = -1;
3429*d83cc019SAndroid Build Coastguard Worker 			} else {
3430*d83cc019SAndroid Build Coastguard Worker 				plane->changed &= ~IGT_PLANE_COORD_CHANGED_MASK;
3431*d83cc019SAndroid Build Coastguard Worker 
3432*d83cc019SAndroid Build Coastguard Worker 				igt_plane_clear_prop_changed(plane, IGT_PLANE_CRTC_ID);
3433*d83cc019SAndroid Build Coastguard Worker 				igt_plane_clear_prop_changed(plane, IGT_PLANE_FB_ID);
3434*d83cc019SAndroid Build Coastguard Worker 
3435*d83cc019SAndroid Build Coastguard Worker 				if (s != COMMIT_LEGACY ||
3436*d83cc019SAndroid Build Coastguard Worker 				    !(plane->type == DRM_PLANE_TYPE_PRIMARY ||
3437*d83cc019SAndroid Build Coastguard Worker 				      plane->type == DRM_PLANE_TYPE_CURSOR))
3438*d83cc019SAndroid Build Coastguard Worker 					plane->changed &= ~LEGACY_PLANE_COMMIT_MASK;
3439*d83cc019SAndroid Build Coastguard Worker 
3440*d83cc019SAndroid Build Coastguard Worker 				if (display->first_commit)
3441*d83cc019SAndroid Build Coastguard Worker 					igt_plane_clear_prop_changed(plane, IGT_PLANE_ROTATION);
3442*d83cc019SAndroid Build Coastguard Worker 			}
3443*d83cc019SAndroid Build Coastguard Worker 		}
3444*d83cc019SAndroid Build Coastguard Worker 	}
3445*d83cc019SAndroid Build Coastguard Worker 
3446*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++) {
3447*d83cc019SAndroid Build Coastguard Worker 		igt_output_t *output = &display->outputs[i];
3448*d83cc019SAndroid Build Coastguard Worker 
3449*d83cc019SAndroid Build Coastguard Worker 		if (s != COMMIT_UNIVERSAL)
3450*d83cc019SAndroid Build Coastguard Worker 			output->changed = 0;
3451*d83cc019SAndroid Build Coastguard Worker 		else
3452*d83cc019SAndroid Build Coastguard Worker 			/* no modeset in universal commit, no change to crtc. */
3453*d83cc019SAndroid Build Coastguard Worker 			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
3454*d83cc019SAndroid Build Coastguard Worker 	}
3455*d83cc019SAndroid Build Coastguard Worker 
3456*d83cc019SAndroid Build Coastguard Worker 	if (display->first_commit) {
3457*d83cc019SAndroid Build Coastguard Worker 		igt_reset_fifo_underrun_reporting(display->drm_fd);
3458*d83cc019SAndroid Build Coastguard Worker 
3459*d83cc019SAndroid Build Coastguard Worker 		igt_display_drop_events(display);
3460*d83cc019SAndroid Build Coastguard Worker 
3461*d83cc019SAndroid Build Coastguard Worker 		display->first_commit = false;
3462*d83cc019SAndroid Build Coastguard Worker 	}
3463*d83cc019SAndroid Build Coastguard Worker }
3464*d83cc019SAndroid Build Coastguard Worker 
3465*d83cc019SAndroid Build Coastguard Worker /*
3466*d83cc019SAndroid Build Coastguard Worker  * Commit all plane changes across all outputs of the display.
3467*d83cc019SAndroid Build Coastguard Worker  *
3468*d83cc019SAndroid Build Coastguard Worker  * If @fail_on_error is true, any failure to commit plane state will lead
3469*d83cc019SAndroid Build Coastguard Worker  * to subtest failure in the specific function where the failure occurs.
3470*d83cc019SAndroid Build Coastguard Worker  * Otherwise, the first error code encountered will be returned and no
3471*d83cc019SAndroid Build Coastguard Worker  * further programming will take place, which may result in some changes
3472*d83cc019SAndroid Build Coastguard Worker  * taking effect and others not taking effect.
3473*d83cc019SAndroid Build Coastguard Worker  */
do_display_commit(igt_display_t * display,enum igt_commit_style s,bool fail_on_error)3474*d83cc019SAndroid Build Coastguard Worker static int do_display_commit(igt_display_t *display,
3475*d83cc019SAndroid Build Coastguard Worker 			     enum igt_commit_style s,
3476*d83cc019SAndroid Build Coastguard Worker 			     bool fail_on_error)
3477*d83cc019SAndroid Build Coastguard Worker {
3478*d83cc019SAndroid Build Coastguard Worker 	int i, ret = 0;
3479*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
3480*d83cc019SAndroid Build Coastguard Worker 	LOG_INDENT(display, "commit");
3481*d83cc019SAndroid Build Coastguard Worker 
3482*d83cc019SAndroid Build Coastguard Worker 	/* someone managed to bypass igt_display_require, catch them */
3483*d83cc019SAndroid Build Coastguard Worker 	assert(display->n_pipes && display->n_outputs);
3484*d83cc019SAndroid Build Coastguard Worker 
3485*d83cc019SAndroid Build Coastguard Worker 	igt_display_refresh(display);
3486*d83cc019SAndroid Build Coastguard Worker 
3487*d83cc019SAndroid Build Coastguard Worker 	if (s == COMMIT_ATOMIC) {
3488*d83cc019SAndroid Build Coastguard Worker 		ret = igt_atomic_commit(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
3489*d83cc019SAndroid Build Coastguard Worker 	} else {
3490*d83cc019SAndroid Build Coastguard Worker 		for_each_pipe(display, pipe) {
3491*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_t *pipe_obj = &display->pipes[pipe];
3492*d83cc019SAndroid Build Coastguard Worker 
3493*d83cc019SAndroid Build Coastguard Worker 			ret = igt_pipe_commit(pipe_obj, s, fail_on_error);
3494*d83cc019SAndroid Build Coastguard Worker 			if (ret)
3495*d83cc019SAndroid Build Coastguard Worker 				break;
3496*d83cc019SAndroid Build Coastguard Worker 		}
3497*d83cc019SAndroid Build Coastguard Worker 
3498*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; !ret && i < display->n_outputs; i++)
3499*d83cc019SAndroid Build Coastguard Worker 			ret = igt_output_commit(&display->outputs[i], s, fail_on_error);
3500*d83cc019SAndroid Build Coastguard Worker 	}
3501*d83cc019SAndroid Build Coastguard Worker 
3502*d83cc019SAndroid Build Coastguard Worker 	LOG_UNINDENT(display);
3503*d83cc019SAndroid Build Coastguard Worker 	CHECK_RETURN(ret, fail_on_error);
3504*d83cc019SAndroid Build Coastguard Worker 
3505*d83cc019SAndroid Build Coastguard Worker 	display_commit_changed(display, s);
3506*d83cc019SAndroid Build Coastguard Worker 
3507*d83cc019SAndroid Build Coastguard Worker 	igt_debug_wait_for_keypress("modeset");
3508*d83cc019SAndroid Build Coastguard Worker 
3509*d83cc019SAndroid Build Coastguard Worker 	return 0;
3510*d83cc019SAndroid Build Coastguard Worker }
3511*d83cc019SAndroid Build Coastguard Worker 
3512*d83cc019SAndroid Build Coastguard Worker /**
3513*d83cc019SAndroid Build Coastguard Worker  * igt_display_try_commit_atomic:
3514*d83cc019SAndroid Build Coastguard Worker  * @display: #igt_display_t to commit.
3515*d83cc019SAndroid Build Coastguard Worker  * @flags: Flags passed to drmModeAtomicCommit.
3516*d83cc019SAndroid Build Coastguard Worker  * @user_data: User defined pointer passed to drmModeAtomicCommit.
3517*d83cc019SAndroid Build Coastguard Worker  *
3518*d83cc019SAndroid Build Coastguard Worker  * This function is similar to #igt_display_try_commit2, but is
3519*d83cc019SAndroid Build Coastguard Worker  * used when you want to pass different flags to the actual commit.
3520*d83cc019SAndroid Build Coastguard Worker  *
3521*d83cc019SAndroid Build Coastguard Worker  * Useful flags can be DRM_MODE_ATOMIC_ALLOW_MODESET,
3522*d83cc019SAndroid Build Coastguard Worker  * DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT,
3523*d83cc019SAndroid Build Coastguard Worker  * or DRM_MODE_ATOMIC_TEST_ONLY.
3524*d83cc019SAndroid Build Coastguard Worker  *
3525*d83cc019SAndroid Build Coastguard Worker  * @user_data is returned in the event if you pass
3526*d83cc019SAndroid Build Coastguard Worker  * DRM_MODE_PAGE_FLIP_EVENT to @flags.
3527*d83cc019SAndroid Build Coastguard Worker  *
3528*d83cc019SAndroid Build Coastguard Worker  * This function will return an error if commit fails, instead of
3529*d83cc019SAndroid Build Coastguard Worker  * aborting the test.
3530*d83cc019SAndroid Build Coastguard Worker  */
igt_display_try_commit_atomic(igt_display_t * display,uint32_t flags,void * user_data)3531*d83cc019SAndroid Build Coastguard Worker int igt_display_try_commit_atomic(igt_display_t *display, uint32_t flags, void *user_data)
3532*d83cc019SAndroid Build Coastguard Worker {
3533*d83cc019SAndroid Build Coastguard Worker 	int ret;
3534*d83cc019SAndroid Build Coastguard Worker 
3535*d83cc019SAndroid Build Coastguard Worker 	/* someone managed to bypass igt_display_require, catch them */
3536*d83cc019SAndroid Build Coastguard Worker 	assert(display->n_pipes && display->n_outputs);
3537*d83cc019SAndroid Build Coastguard Worker 
3538*d83cc019SAndroid Build Coastguard Worker 	LOG_INDENT(display, "commit");
3539*d83cc019SAndroid Build Coastguard Worker 
3540*d83cc019SAndroid Build Coastguard Worker 	igt_display_refresh(display);
3541*d83cc019SAndroid Build Coastguard Worker 
3542*d83cc019SAndroid Build Coastguard Worker 	ret = igt_atomic_commit(display, flags, user_data);
3543*d83cc019SAndroid Build Coastguard Worker 
3544*d83cc019SAndroid Build Coastguard Worker 	LOG_UNINDENT(display);
3545*d83cc019SAndroid Build Coastguard Worker 
3546*d83cc019SAndroid Build Coastguard Worker 	if (ret || (flags & DRM_MODE_ATOMIC_TEST_ONLY))
3547*d83cc019SAndroid Build Coastguard Worker 		return ret;
3548*d83cc019SAndroid Build Coastguard Worker 
3549*d83cc019SAndroid Build Coastguard Worker 	if (display->first_commit)
3550*d83cc019SAndroid Build Coastguard Worker 		igt_fail_on_f(flags & (DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK),
3551*d83cc019SAndroid Build Coastguard Worker 			      "First commit has to drop all stale events\n");
3552*d83cc019SAndroid Build Coastguard Worker 
3553*d83cc019SAndroid Build Coastguard Worker 	display_commit_changed(display, COMMIT_ATOMIC);
3554*d83cc019SAndroid Build Coastguard Worker 
3555*d83cc019SAndroid Build Coastguard Worker 	igt_debug_wait_for_keypress("modeset");
3556*d83cc019SAndroid Build Coastguard Worker 
3557*d83cc019SAndroid Build Coastguard Worker 	return 0;
3558*d83cc019SAndroid Build Coastguard Worker }
3559*d83cc019SAndroid Build Coastguard Worker 
3560*d83cc019SAndroid Build Coastguard Worker /**
3561*d83cc019SAndroid Build Coastguard Worker  * igt_display_commit_atomic:
3562*d83cc019SAndroid Build Coastguard Worker  * @display: #igt_display_t to commit.
3563*d83cc019SAndroid Build Coastguard Worker  * @flags: Flags passed to drmModeAtomicCommit.
3564*d83cc019SAndroid Build Coastguard Worker  * @user_data: User defined pointer passed to drmModeAtomicCommit.
3565*d83cc019SAndroid Build Coastguard Worker  *
3566*d83cc019SAndroid Build Coastguard Worker  * This function is similar to #igt_display_commit2, but is
3567*d83cc019SAndroid Build Coastguard Worker  * used when you want to pass different flags to the actual commit.
3568*d83cc019SAndroid Build Coastguard Worker  *
3569*d83cc019SAndroid Build Coastguard Worker  * Useful flags can be DRM_MODE_ATOMIC_ALLOW_MODESET,
3570*d83cc019SAndroid Build Coastguard Worker  * DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT,
3571*d83cc019SAndroid Build Coastguard Worker  * or DRM_MODE_ATOMIC_TEST_ONLY.
3572*d83cc019SAndroid Build Coastguard Worker  *
3573*d83cc019SAndroid Build Coastguard Worker  * @user_data is returned in the event if you pass
3574*d83cc019SAndroid Build Coastguard Worker  * DRM_MODE_PAGE_FLIP_EVENT to @flags.
3575*d83cc019SAndroid Build Coastguard Worker  *
3576*d83cc019SAndroid Build Coastguard Worker  * This function will abort the test if commit fails.
3577*d83cc019SAndroid Build Coastguard Worker  */
igt_display_commit_atomic(igt_display_t * display,uint32_t flags,void * user_data)3578*d83cc019SAndroid Build Coastguard Worker void igt_display_commit_atomic(igt_display_t *display, uint32_t flags, void *user_data)
3579*d83cc019SAndroid Build Coastguard Worker {
3580*d83cc019SAndroid Build Coastguard Worker 	int ret = igt_display_try_commit_atomic(display, flags, user_data);
3581*d83cc019SAndroid Build Coastguard Worker 
3582*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
3583*d83cc019SAndroid Build Coastguard Worker }
3584*d83cc019SAndroid Build Coastguard Worker 
3585*d83cc019SAndroid Build Coastguard Worker /**
3586*d83cc019SAndroid Build Coastguard Worker  * igt_display_commit2:
3587*d83cc019SAndroid Build Coastguard Worker  * @display: DRM device handle
3588*d83cc019SAndroid Build Coastguard Worker  * @s: Commit style
3589*d83cc019SAndroid Build Coastguard Worker  *
3590*d83cc019SAndroid Build Coastguard Worker  * Commits framebuffer and positioning changes to all planes of each display
3591*d83cc019SAndroid Build Coastguard Worker  * pipe, using a specific API to perform the programming.  This function should
3592*d83cc019SAndroid Build Coastguard Worker  * be used to exercise a specific driver programming API; igt_display_commit
3593*d83cc019SAndroid Build Coastguard Worker  * should be used instead if the API used is unimportant to the test being run.
3594*d83cc019SAndroid Build Coastguard Worker  *
3595*d83cc019SAndroid Build Coastguard Worker  * This function should only be used to commit changes that are expected to
3596*d83cc019SAndroid Build Coastguard Worker  * succeed, since any failure during the commit process will cause the IGT
3597*d83cc019SAndroid Build Coastguard Worker  * subtest to fail.  To commit changes that are expected to fail, use
3598*d83cc019SAndroid Build Coastguard Worker  * @igt_try_display_commit2 instead.
3599*d83cc019SAndroid Build Coastguard Worker  *
3600*d83cc019SAndroid Build Coastguard Worker  * Returns: 0 upon success.  This function will never return upon failure
3601*d83cc019SAndroid Build Coastguard Worker  * since igt_fail() at lower levels will longjmp out of it.
3602*d83cc019SAndroid Build Coastguard Worker  */
igt_display_commit2(igt_display_t * display,enum igt_commit_style s)3603*d83cc019SAndroid Build Coastguard Worker int igt_display_commit2(igt_display_t *display,
3604*d83cc019SAndroid Build Coastguard Worker 		       enum igt_commit_style s)
3605*d83cc019SAndroid Build Coastguard Worker {
3606*d83cc019SAndroid Build Coastguard Worker 	do_display_commit(display, s, true);
3607*d83cc019SAndroid Build Coastguard Worker 
3608*d83cc019SAndroid Build Coastguard Worker 	return 0;
3609*d83cc019SAndroid Build Coastguard Worker }
3610*d83cc019SAndroid Build Coastguard Worker 
3611*d83cc019SAndroid Build Coastguard Worker /**
3612*d83cc019SAndroid Build Coastguard Worker  * igt_display_try_commit2:
3613*d83cc019SAndroid Build Coastguard Worker  * @display: DRM device handle
3614*d83cc019SAndroid Build Coastguard Worker  * @s: Commit style
3615*d83cc019SAndroid Build Coastguard Worker  *
3616*d83cc019SAndroid Build Coastguard Worker  * Attempts to commit framebuffer and positioning changes to all planes of each
3617*d83cc019SAndroid Build Coastguard Worker  * display pipe.  This function should be used to commit changes that are
3618*d83cc019SAndroid Build Coastguard Worker  * expected to fail, so that the error code can be checked for correctness.
3619*d83cc019SAndroid Build Coastguard Worker  * For changes that are expected to succeed, use @igt_display_commit instead.
3620*d83cc019SAndroid Build Coastguard Worker  *
3621*d83cc019SAndroid Build Coastguard Worker  * Note that in non-atomic commit styles, no display programming will be
3622*d83cc019SAndroid Build Coastguard Worker  * performed after the first failure is encountered, so only some of the
3623*d83cc019SAndroid Build Coastguard Worker  * operations requested by a test may have been completed.  Tests that catch
3624*d83cc019SAndroid Build Coastguard Worker  * errors returned by this function should take care to restore the display to
3625*d83cc019SAndroid Build Coastguard Worker  * a sane state after a failure is detected.
3626*d83cc019SAndroid Build Coastguard Worker  *
3627*d83cc019SAndroid Build Coastguard Worker  * Returns: 0 upon success, otherwise the error code of the first error
3628*d83cc019SAndroid Build Coastguard Worker  * encountered.
3629*d83cc019SAndroid Build Coastguard Worker  */
igt_display_try_commit2(igt_display_t * display,enum igt_commit_style s)3630*d83cc019SAndroid Build Coastguard Worker int igt_display_try_commit2(igt_display_t *display, enum igt_commit_style s)
3631*d83cc019SAndroid Build Coastguard Worker {
3632*d83cc019SAndroid Build Coastguard Worker 	return do_display_commit(display, s, false);
3633*d83cc019SAndroid Build Coastguard Worker }
3634*d83cc019SAndroid Build Coastguard Worker 
3635*d83cc019SAndroid Build Coastguard Worker /**
3636*d83cc019SAndroid Build Coastguard Worker  * igt_display_commit:
3637*d83cc019SAndroid Build Coastguard Worker  * @display: DRM device handle
3638*d83cc019SAndroid Build Coastguard Worker  *
3639*d83cc019SAndroid Build Coastguard Worker  * Commits framebuffer and positioning changes to all planes of each display
3640*d83cc019SAndroid Build Coastguard Worker  * pipe.
3641*d83cc019SAndroid Build Coastguard Worker  *
3642*d83cc019SAndroid Build Coastguard Worker  * Returns: 0 upon success.  This function will never return upon failure
3643*d83cc019SAndroid Build Coastguard Worker  * since igt_fail() at lower levels will longjmp out of it.
3644*d83cc019SAndroid Build Coastguard Worker  */
igt_display_commit(igt_display_t * display)3645*d83cc019SAndroid Build Coastguard Worker int igt_display_commit(igt_display_t *display)
3646*d83cc019SAndroid Build Coastguard Worker {
3647*d83cc019SAndroid Build Coastguard Worker 	return igt_display_commit2(display, COMMIT_LEGACY);
3648*d83cc019SAndroid Build Coastguard Worker }
3649*d83cc019SAndroid Build Coastguard Worker 
3650*d83cc019SAndroid Build Coastguard Worker /**
3651*d83cc019SAndroid Build Coastguard Worker  * igt_display_drop_events:
3652*d83cc019SAndroid Build Coastguard Worker  * @display: DRM device handle
3653*d83cc019SAndroid Build Coastguard Worker  *
3654*d83cc019SAndroid Build Coastguard Worker  * Nonblockingly reads all current events and drops them, for highest
3655*d83cc019SAndroid Build Coastguard Worker  * reliablility, call igt_display_commit2() first to flush all outstanding
3656*d83cc019SAndroid Build Coastguard Worker  * events.
3657*d83cc019SAndroid Build Coastguard Worker  *
3658*d83cc019SAndroid Build Coastguard Worker  * This will be called on the first commit after igt_display_reset() too,
3659*d83cc019SAndroid Build Coastguard Worker  * to make sure any stale events are flushed.
3660*d83cc019SAndroid Build Coastguard Worker  *
3661*d83cc019SAndroid Build Coastguard Worker  * Returns: Number of dropped events.
3662*d83cc019SAndroid Build Coastguard Worker  */
igt_display_drop_events(igt_display_t * display)3663*d83cc019SAndroid Build Coastguard Worker int igt_display_drop_events(igt_display_t *display)
3664*d83cc019SAndroid Build Coastguard Worker {
3665*d83cc019SAndroid Build Coastguard Worker 	int ret = 0;
3666*d83cc019SAndroid Build Coastguard Worker 
3667*d83cc019SAndroid Build Coastguard Worker 	/* Clear all events from drm fd. */
3668*d83cc019SAndroid Build Coastguard Worker 	struct pollfd pfd = {
3669*d83cc019SAndroid Build Coastguard Worker 		.fd = display->drm_fd,
3670*d83cc019SAndroid Build Coastguard Worker 		.events = POLLIN
3671*d83cc019SAndroid Build Coastguard Worker 	};
3672*d83cc019SAndroid Build Coastguard Worker 
3673*d83cc019SAndroid Build Coastguard Worker 	while (poll(&pfd, 1, 0) > 0) {
3674*d83cc019SAndroid Build Coastguard Worker 		struct drm_event *ev;
3675*d83cc019SAndroid Build Coastguard Worker 		char buf[4096];
3676*d83cc019SAndroid Build Coastguard Worker 		ssize_t retval;
3677*d83cc019SAndroid Build Coastguard Worker 
3678*d83cc019SAndroid Build Coastguard Worker 		retval = read(display->drm_fd, &buf, sizeof(buf));
3679*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lt(0, retval);
3680*d83cc019SAndroid Build Coastguard Worker 
3681*d83cc019SAndroid Build Coastguard Worker 		for (int i = 0; i < retval; i += ev->length) {
3682*d83cc019SAndroid Build Coastguard Worker 			ev = (struct drm_event *)&buf[i];
3683*d83cc019SAndroid Build Coastguard Worker 
3684*d83cc019SAndroid Build Coastguard Worker 			igt_info("Dropping event type %u length %u\n", ev->type, ev->length);
3685*d83cc019SAndroid Build Coastguard Worker 			igt_assert(ev->length + i <= sizeof(buf));
3686*d83cc019SAndroid Build Coastguard Worker 			ret++;
3687*d83cc019SAndroid Build Coastguard Worker 		}
3688*d83cc019SAndroid Build Coastguard Worker 	}
3689*d83cc019SAndroid Build Coastguard Worker 
3690*d83cc019SAndroid Build Coastguard Worker 	return ret;
3691*d83cc019SAndroid Build Coastguard Worker }
3692*d83cc019SAndroid Build Coastguard Worker 
3693*d83cc019SAndroid Build Coastguard Worker /**
3694*d83cc019SAndroid Build Coastguard Worker  * igt_output_name:
3695*d83cc019SAndroid Build Coastguard Worker  * @output: Target output
3696*d83cc019SAndroid Build Coastguard Worker  *
3697*d83cc019SAndroid Build Coastguard Worker  * Returns: String representing a connector's name, e.g. "DP-1".
3698*d83cc019SAndroid Build Coastguard Worker  */
igt_output_name(igt_output_t * output)3699*d83cc019SAndroid Build Coastguard Worker const char *igt_output_name(igt_output_t *output)
3700*d83cc019SAndroid Build Coastguard Worker {
3701*d83cc019SAndroid Build Coastguard Worker 	return output->name;
3702*d83cc019SAndroid Build Coastguard Worker }
3703*d83cc019SAndroid Build Coastguard Worker 
3704*d83cc019SAndroid Build Coastguard Worker /**
3705*d83cc019SAndroid Build Coastguard Worker  * igt_output_get_mode:
3706*d83cc019SAndroid Build Coastguard Worker  * @output: Target output
3707*d83cc019SAndroid Build Coastguard Worker  *
3708*d83cc019SAndroid Build Coastguard Worker  * Get the current mode of the given connector
3709*d83cc019SAndroid Build Coastguard Worker  *
3710*d83cc019SAndroid Build Coastguard Worker  * Returns: A #drmModeModeInfo struct representing the current mode
3711*d83cc019SAndroid Build Coastguard Worker  */
igt_output_get_mode(igt_output_t * output)3712*d83cc019SAndroid Build Coastguard Worker drmModeModeInfo *igt_output_get_mode(igt_output_t *output)
3713*d83cc019SAndroid Build Coastguard Worker {
3714*d83cc019SAndroid Build Coastguard Worker 	if (output->use_override_mode)
3715*d83cc019SAndroid Build Coastguard Worker 		return &output->override_mode;
3716*d83cc019SAndroid Build Coastguard Worker 	else
3717*d83cc019SAndroid Build Coastguard Worker 		return &output->config.default_mode;
3718*d83cc019SAndroid Build Coastguard Worker }
3719*d83cc019SAndroid Build Coastguard Worker 
3720*d83cc019SAndroid Build Coastguard Worker /**
3721*d83cc019SAndroid Build Coastguard Worker  * igt_output_override_mode:
3722*d83cc019SAndroid Build Coastguard Worker  * @output: Output of which the mode will be overridden
3723*d83cc019SAndroid Build Coastguard Worker  * @mode: New mode, or NULL to disable override.
3724*d83cc019SAndroid Build Coastguard Worker  *
3725*d83cc019SAndroid Build Coastguard Worker  * Overrides the output's mode with @mode, so that it is used instead of the
3726*d83cc019SAndroid Build Coastguard Worker  * mode obtained with get connectors. Note that the mode is used without
3727*d83cc019SAndroid Build Coastguard Worker  * checking if the output supports it, so this might lead to unexpected results.
3728*d83cc019SAndroid Build Coastguard Worker  */
igt_output_override_mode(igt_output_t * output,const drmModeModeInfo * mode)3729*d83cc019SAndroid Build Coastguard Worker void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
3730*d83cc019SAndroid Build Coastguard Worker {
3731*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = igt_output_get_driving_pipe(output);
3732*d83cc019SAndroid Build Coastguard Worker 
3733*d83cc019SAndroid Build Coastguard Worker 	if (mode)
3734*d83cc019SAndroid Build Coastguard Worker 		output->override_mode = *mode;
3735*d83cc019SAndroid Build Coastguard Worker 
3736*d83cc019SAndroid Build Coastguard Worker 	output->use_override_mode = !!mode;
3737*d83cc019SAndroid Build Coastguard Worker 
3738*d83cc019SAndroid Build Coastguard Worker 	if (pipe) {
3739*d83cc019SAndroid Build Coastguard Worker 		if (output->display->is_atomic)
3740*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
3741*d83cc019SAndroid Build Coastguard Worker 		else
3742*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_obj_set_prop_changed(pipe, IGT_CRTC_MODE_ID);
3743*d83cc019SAndroid Build Coastguard Worker 	}
3744*d83cc019SAndroid Build Coastguard Worker }
3745*d83cc019SAndroid Build Coastguard Worker 
3746*d83cc019SAndroid Build Coastguard Worker /*
3747*d83cc019SAndroid Build Coastguard Worker  * igt_output_set_pipe:
3748*d83cc019SAndroid Build Coastguard Worker  * @output: Target output for which the pipe is being set to
3749*d83cc019SAndroid Build Coastguard Worker  * @pipe: Display pipe to set to
3750*d83cc019SAndroid Build Coastguard Worker  *
3751*d83cc019SAndroid Build Coastguard Worker  * This function sets a @pipe to a specific @output connector by
3752*d83cc019SAndroid Build Coastguard Worker  * setting the CRTC_ID property of the @pipe. The pipe
3753*d83cc019SAndroid Build Coastguard Worker  * is only activated for all pipes except PIPE_NONE.
3754*d83cc019SAndroid Build Coastguard Worker  */
igt_output_set_pipe(igt_output_t * output,enum pipe pipe)3755*d83cc019SAndroid Build Coastguard Worker void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
3756*d83cc019SAndroid Build Coastguard Worker {
3757*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = output->display;
3758*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *old_pipe = NULL, *pipe_obj = NULL;;
3759*d83cc019SAndroid Build Coastguard Worker 
3760*d83cc019SAndroid Build Coastguard Worker 	igt_assert(output->name);
3761*d83cc019SAndroid Build Coastguard Worker 
3762*d83cc019SAndroid Build Coastguard Worker 	if (output->pending_pipe != PIPE_NONE)
3763*d83cc019SAndroid Build Coastguard Worker 		old_pipe = igt_output_get_driving_pipe(output);
3764*d83cc019SAndroid Build Coastguard Worker 
3765*d83cc019SAndroid Build Coastguard Worker 	if (pipe != PIPE_NONE)
3766*d83cc019SAndroid Build Coastguard Worker 		pipe_obj = &display->pipes[pipe];
3767*d83cc019SAndroid Build Coastguard Worker 
3768*d83cc019SAndroid Build Coastguard Worker 	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
3769*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(pipe));
3770*d83cc019SAndroid Build Coastguard Worker 	output->pending_pipe = pipe;
3771*d83cc019SAndroid Build Coastguard Worker 
3772*d83cc019SAndroid Build Coastguard Worker 	if (old_pipe) {
3773*d83cc019SAndroid Build Coastguard Worker 		igt_output_t *old_output;
3774*d83cc019SAndroid Build Coastguard Worker 
3775*d83cc019SAndroid Build Coastguard Worker 		old_output = igt_pipe_get_output(old_pipe);
3776*d83cc019SAndroid Build Coastguard Worker 		if (!old_output) {
3777*d83cc019SAndroid Build Coastguard Worker 			if (display->is_atomic)
3778*d83cc019SAndroid Build Coastguard Worker 				igt_pipe_obj_replace_prop_blob(old_pipe, IGT_CRTC_MODE_ID, NULL, 0);
3779*d83cc019SAndroid Build Coastguard Worker 			else
3780*d83cc019SAndroid Build Coastguard Worker 				igt_pipe_obj_set_prop_changed(old_pipe, IGT_CRTC_MODE_ID);
3781*d83cc019SAndroid Build Coastguard Worker 
3782*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_obj_set_prop_value(old_pipe, IGT_CRTC_ACTIVE, 0);
3783*d83cc019SAndroid Build Coastguard Worker 		}
3784*d83cc019SAndroid Build Coastguard Worker 	}
3785*d83cc019SAndroid Build Coastguard Worker 
3786*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, pipe == PIPE_NONE ? 0 : display->pipes[pipe].crtc_id);
3787*d83cc019SAndroid Build Coastguard Worker 
3788*d83cc019SAndroid Build Coastguard Worker 	igt_output_refresh(output);
3789*d83cc019SAndroid Build Coastguard Worker 
3790*d83cc019SAndroid Build Coastguard Worker 	if (pipe_obj) {
3791*d83cc019SAndroid Build Coastguard Worker 		if (display->is_atomic)
3792*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_obj_replace_prop_blob(pipe_obj, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(drmModeModeInfo));
3793*d83cc019SAndroid Build Coastguard Worker 		else
3794*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_obj_set_prop_changed(pipe_obj, IGT_CRTC_MODE_ID);
3795*d83cc019SAndroid Build Coastguard Worker 
3796*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_obj_set_prop_value(pipe_obj, IGT_CRTC_ACTIVE, 1);
3797*d83cc019SAndroid Build Coastguard Worker 	}
3798*d83cc019SAndroid Build Coastguard Worker }
3799*d83cc019SAndroid Build Coastguard Worker 
3800*d83cc019SAndroid Build Coastguard Worker /*
3801*d83cc019SAndroid Build Coastguard Worker  * igt_pipe_refresh:
3802*d83cc019SAndroid Build Coastguard Worker  * @display: a pointer to an #igt_display_t structure
3803*d83cc019SAndroid Build Coastguard Worker  * @pipe: Pipe to refresh
3804*d83cc019SAndroid Build Coastguard Worker  * @force: Should be set to true if mode_blob is no longer considered
3805*d83cc019SAndroid Build Coastguard Worker  * to be valid, for example after doing an atomic commit during fork or closing display fd.
3806*d83cc019SAndroid Build Coastguard Worker  *
3807*d83cc019SAndroid Build Coastguard Worker  * Requests the pipe to be part of the state on next update.
3808*d83cc019SAndroid Build Coastguard Worker  * This is useful when state may have been out of sync after
3809*d83cc019SAndroid Build Coastguard Worker  * a fork, or we just want to be sure the pipe is included
3810*d83cc019SAndroid Build Coastguard Worker  * in the next commit.
3811*d83cc019SAndroid Build Coastguard Worker  */
igt_pipe_refresh(igt_display_t * display,enum pipe pipe,bool force)3812*d83cc019SAndroid Build Coastguard Worker void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force)
3813*d83cc019SAndroid Build Coastguard Worker {
3814*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe_obj = &display->pipes[pipe];
3815*d83cc019SAndroid Build Coastguard Worker 
3816*d83cc019SAndroid Build Coastguard Worker 	if (force && display->is_atomic) {
3817*d83cc019SAndroid Build Coastguard Worker 		igt_output_t *output = igt_pipe_get_output(pipe_obj);
3818*d83cc019SAndroid Build Coastguard Worker 
3819*d83cc019SAndroid Build Coastguard Worker 		pipe_obj->values[IGT_CRTC_MODE_ID] = 0;
3820*d83cc019SAndroid Build Coastguard Worker 		if (output)
3821*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_obj_replace_prop_blob(pipe_obj, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(drmModeModeInfo));
3822*d83cc019SAndroid Build Coastguard Worker 	} else
3823*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_obj_set_prop_changed(pipe_obj, IGT_CRTC_MODE_ID);
3824*d83cc019SAndroid Build Coastguard Worker }
3825*d83cc019SAndroid Build Coastguard Worker 
igt_output_get_plane(igt_output_t * output,int plane_idx)3826*d83cc019SAndroid Build Coastguard Worker igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx)
3827*d83cc019SAndroid Build Coastguard Worker {
3828*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe;
3829*d83cc019SAndroid Build Coastguard Worker 
3830*d83cc019SAndroid Build Coastguard Worker 	pipe = igt_output_get_driving_pipe(output);
3831*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pipe);
3832*d83cc019SAndroid Build Coastguard Worker 
3833*d83cc019SAndroid Build Coastguard Worker 	return igt_pipe_get_plane(pipe, plane_idx);
3834*d83cc019SAndroid Build Coastguard Worker }
3835*d83cc019SAndroid Build Coastguard Worker 
3836*d83cc019SAndroid Build Coastguard Worker /**
3837*d83cc019SAndroid Build Coastguard Worker  * igt_output_get_plane_type:
3838*d83cc019SAndroid Build Coastguard Worker  * @output: Target output
3839*d83cc019SAndroid Build Coastguard Worker  * @plane_type: Cursor, primary or an overlay plane
3840*d83cc019SAndroid Build Coastguard Worker  *
3841*d83cc019SAndroid Build Coastguard Worker  * Finds a valid plane type for the given @output otherwise
3842*d83cc019SAndroid Build Coastguard Worker  * the test is skipped if the right combination of @output/@plane_type is not found
3843*d83cc019SAndroid Build Coastguard Worker  *
3844*d83cc019SAndroid Build Coastguard Worker  * Returns: A #igt_plane_t structure that matches the requested plane type
3845*d83cc019SAndroid Build Coastguard Worker  */
igt_output_get_plane_type(igt_output_t * output,int plane_type)3846*d83cc019SAndroid Build Coastguard Worker igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type)
3847*d83cc019SAndroid Build Coastguard Worker {
3848*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe;
3849*d83cc019SAndroid Build Coastguard Worker 
3850*d83cc019SAndroid Build Coastguard Worker 	pipe = igt_output_get_driving_pipe(output);
3851*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pipe);
3852*d83cc019SAndroid Build Coastguard Worker 
3853*d83cc019SAndroid Build Coastguard Worker 	return igt_pipe_get_plane_type(pipe, plane_type);
3854*d83cc019SAndroid Build Coastguard Worker }
3855*d83cc019SAndroid Build Coastguard Worker 
3856*d83cc019SAndroid Build Coastguard Worker /**
3857*d83cc019SAndroid Build Coastguard Worker  * igt_output_count_plane_type:
3858*d83cc019SAndroid Build Coastguard Worker  * @output: Target output
3859*d83cc019SAndroid Build Coastguard Worker  * @plane_type: Cursor, primary or an overlay plane
3860*d83cc019SAndroid Build Coastguard Worker  *
3861*d83cc019SAndroid Build Coastguard Worker  * Counts the number of planes of type @plane_type for the provided @output.
3862*d83cc019SAndroid Build Coastguard Worker  *
3863*d83cc019SAndroid Build Coastguard Worker  * Returns: The number of planes that match the requested plane type
3864*d83cc019SAndroid Build Coastguard Worker  */
igt_output_count_plane_type(igt_output_t * output,int plane_type)3865*d83cc019SAndroid Build Coastguard Worker int igt_output_count_plane_type(igt_output_t *output, int plane_type)
3866*d83cc019SAndroid Build Coastguard Worker {
3867*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = igt_output_get_driving_pipe(output);
3868*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pipe);
3869*d83cc019SAndroid Build Coastguard Worker 
3870*d83cc019SAndroid Build Coastguard Worker 	return igt_pipe_count_plane_type(pipe, plane_type);
3871*d83cc019SAndroid Build Coastguard Worker }
3872*d83cc019SAndroid Build Coastguard Worker 
3873*d83cc019SAndroid Build Coastguard Worker /**
3874*d83cc019SAndroid Build Coastguard Worker  * igt_output_get_plane_type_index:
3875*d83cc019SAndroid Build Coastguard Worker  * @output: Target output
3876*d83cc019SAndroid Build Coastguard Worker  * @plane_type: Cursor, primary or an overlay plane
3877*d83cc019SAndroid Build Coastguard Worker  * @index: the index of the plane among planes of the same type
3878*d83cc019SAndroid Build Coastguard Worker  *
3879*d83cc019SAndroid Build Coastguard Worker  * Get the @index th plane of type @plane_type for the provided @output.
3880*d83cc019SAndroid Build Coastguard Worker  *
3881*d83cc019SAndroid Build Coastguard Worker  * Returns: The @index th plane that matches the requested plane type
3882*d83cc019SAndroid Build Coastguard Worker  */
igt_output_get_plane_type_index(igt_output_t * output,int plane_type,int index)3883*d83cc019SAndroid Build Coastguard Worker igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
3884*d83cc019SAndroid Build Coastguard Worker 					     int plane_type, int index)
3885*d83cc019SAndroid Build Coastguard Worker {
3886*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = igt_output_get_driving_pipe(output);
3887*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pipe);
3888*d83cc019SAndroid Build Coastguard Worker 
3889*d83cc019SAndroid Build Coastguard Worker 	return igt_pipe_get_plane_type_index(pipe, plane_type, index);
3890*d83cc019SAndroid Build Coastguard Worker }
3891*d83cc019SAndroid Build Coastguard Worker 
3892*d83cc019SAndroid Build Coastguard Worker /**
3893*d83cc019SAndroid Build Coastguard Worker  * igt_plane_set_fb:
3894*d83cc019SAndroid Build Coastguard Worker  * @plane: Plane
3895*d83cc019SAndroid Build Coastguard Worker  * @fb: Framebuffer pointer
3896*d83cc019SAndroid Build Coastguard Worker  *
3897*d83cc019SAndroid Build Coastguard Worker  * Pairs a given @framebuffer to a @plane
3898*d83cc019SAndroid Build Coastguard Worker  *
3899*d83cc019SAndroid Build Coastguard Worker  * This function also sets a default size and position for the framebuffer
3900*d83cc019SAndroid Build Coastguard Worker  * to avoid crashes on applications that ignore to set these.
3901*d83cc019SAndroid Build Coastguard Worker  */
igt_plane_set_fb(igt_plane_t * plane,struct igt_fb * fb)3902*d83cc019SAndroid Build Coastguard Worker void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb)
3903*d83cc019SAndroid Build Coastguard Worker {
3904*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = plane->pipe;
3905*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
3906*d83cc019SAndroid Build Coastguard Worker 
3907*d83cc019SAndroid Build Coastguard Worker 	LOG(display, "%s.%d: plane_set_fb(%d)\n", kmstest_pipe_name(pipe->pipe),
3908*d83cc019SAndroid Build Coastguard Worker 	    plane->index, fb ? fb->fb_id : 0);
3909*d83cc019SAndroid Build Coastguard Worker 
3910*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, fb ? pipe->crtc_id : 0);
3911*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, fb ? fb->fb_id : 0);
3912*d83cc019SAndroid Build Coastguard Worker 
3913*d83cc019SAndroid Build Coastguard Worker 	if (plane->type == DRM_PLANE_TYPE_CURSOR && fb)
3914*d83cc019SAndroid Build Coastguard Worker 		plane->gem_handle = fb->gem_handle;
3915*d83cc019SAndroid Build Coastguard Worker 	else
3916*d83cc019SAndroid Build Coastguard Worker 		plane->gem_handle = 0;
3917*d83cc019SAndroid Build Coastguard Worker 
3918*d83cc019SAndroid Build Coastguard Worker 	/* hack to keep tests working that don't call igt_plane_set_size() */
3919*d83cc019SAndroid Build Coastguard Worker 	if (fb) {
3920*d83cc019SAndroid Build Coastguard Worker 		/* set default plane size as fb size */
3921*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_size(plane, fb->width, fb->height);
3922*d83cc019SAndroid Build Coastguard Worker 
3923*d83cc019SAndroid Build Coastguard Worker 		/* set default src pos/size as fb size */
3924*d83cc019SAndroid Build Coastguard Worker 		igt_fb_set_position(fb, plane, 0, 0);
3925*d83cc019SAndroid Build Coastguard Worker 		igt_fb_set_size(fb, plane, fb->width, fb->height);
3926*d83cc019SAndroid Build Coastguard Worker 
3927*d83cc019SAndroid Build Coastguard Worker 		if (igt_plane_has_prop(plane, IGT_PLANE_COLOR_ENCODING))
3928*d83cc019SAndroid Build Coastguard Worker 			igt_plane_set_prop_enum(plane, IGT_PLANE_COLOR_ENCODING,
3929*d83cc019SAndroid Build Coastguard Worker 				igt_color_encoding_to_str(fb->color_encoding));
3930*d83cc019SAndroid Build Coastguard Worker 		if (igt_plane_has_prop(plane, IGT_PLANE_COLOR_RANGE))
3931*d83cc019SAndroid Build Coastguard Worker 			igt_plane_set_prop_enum(plane, IGT_PLANE_COLOR_RANGE,
3932*d83cc019SAndroid Build Coastguard Worker 				igt_color_range_to_str(fb->color_range));
3933*d83cc019SAndroid Build Coastguard Worker 
3934*d83cc019SAndroid Build Coastguard Worker 		/* Hack to prioritize the plane on the pipe that last set fb */
3935*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_pipe(plane, pipe);
3936*d83cc019SAndroid Build Coastguard Worker 	} else {
3937*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_size(plane, 0, 0);
3938*d83cc019SAndroid Build Coastguard Worker 
3939*d83cc019SAndroid Build Coastguard Worker 		/* set default src pos/size as fb size */
3940*d83cc019SAndroid Build Coastguard Worker 		igt_fb_set_position(fb, plane, 0, 0);
3941*d83cc019SAndroid Build Coastguard Worker 		igt_fb_set_size(fb, plane, 0, 0);
3942*d83cc019SAndroid Build Coastguard Worker 	}
3943*d83cc019SAndroid Build Coastguard Worker }
3944*d83cc019SAndroid Build Coastguard Worker 
3945*d83cc019SAndroid Build Coastguard Worker /**
3946*d83cc019SAndroid Build Coastguard Worker  * igt_plane_set_fence_fd:
3947*d83cc019SAndroid Build Coastguard Worker  * @plane: plane
3948*d83cc019SAndroid Build Coastguard Worker  * @fence_fd: fence fd, disable fence_fd by setting it to -1
3949*d83cc019SAndroid Build Coastguard Worker  *
3950*d83cc019SAndroid Build Coastguard Worker  * This function sets a fence fd to enable a commit to wait for some event to
3951*d83cc019SAndroid Build Coastguard Worker  * occur before completing.
3952*d83cc019SAndroid Build Coastguard Worker  */
igt_plane_set_fence_fd(igt_plane_t * plane,int fence_fd)3953*d83cc019SAndroid Build Coastguard Worker void igt_plane_set_fence_fd(igt_plane_t *plane, int fence_fd)
3954*d83cc019SAndroid Build Coastguard Worker {
3955*d83cc019SAndroid Build Coastguard Worker 	int64_t fd;
3956*d83cc019SAndroid Build Coastguard Worker 
3957*d83cc019SAndroid Build Coastguard Worker 	fd = plane->values[IGT_PLANE_IN_FENCE_FD];
3958*d83cc019SAndroid Build Coastguard Worker 	if (fd != -1)
3959*d83cc019SAndroid Build Coastguard Worker 		close(fd);
3960*d83cc019SAndroid Build Coastguard Worker 
3961*d83cc019SAndroid Build Coastguard Worker 	if (fence_fd != -1) {
3962*d83cc019SAndroid Build Coastguard Worker 		fd = dup(fence_fd);
3963*d83cc019SAndroid Build Coastguard Worker 		igt_fail_on(fd == -1);
3964*d83cc019SAndroid Build Coastguard Worker 	} else
3965*d83cc019SAndroid Build Coastguard Worker 		fd = -1;
3966*d83cc019SAndroid Build Coastguard Worker 
3967*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_IN_FENCE_FD, fd);
3968*d83cc019SAndroid Build Coastguard Worker }
3969*d83cc019SAndroid Build Coastguard Worker 
3970*d83cc019SAndroid Build Coastguard Worker /**
3971*d83cc019SAndroid Build Coastguard Worker  * igt_plane_set_pipe:
3972*d83cc019SAndroid Build Coastguard Worker  * @plane: Target plane pointer
3973*d83cc019SAndroid Build Coastguard Worker  * @pipe: The pipe to assign the plane to
3974*d83cc019SAndroid Build Coastguard Worker  *
3975*d83cc019SAndroid Build Coastguard Worker  */
igt_plane_set_pipe(igt_plane_t * plane,igt_pipe_t * pipe)3976*d83cc019SAndroid Build Coastguard Worker void igt_plane_set_pipe(igt_plane_t *plane, igt_pipe_t *pipe)
3977*d83cc019SAndroid Build Coastguard Worker {
3978*d83cc019SAndroid Build Coastguard Worker 	/*
3979*d83cc019SAndroid Build Coastguard Worker 	 * HACK: Point the global plane back to the local plane.
3980*d83cc019SAndroid Build Coastguard Worker 	 * This is used to help apply the correct atomic state while
3981*d83cc019SAndroid Build Coastguard Worker 	 * we're moving away from the single pipe per plane model.
3982*d83cc019SAndroid Build Coastguard Worker 	 */
3983*d83cc019SAndroid Build Coastguard Worker 	plane->ref->ref = plane;
3984*d83cc019SAndroid Build Coastguard Worker 	plane->ref->pipe = pipe;
3985*d83cc019SAndroid Build Coastguard Worker }
3986*d83cc019SAndroid Build Coastguard Worker 
3987*d83cc019SAndroid Build Coastguard Worker /**
3988*d83cc019SAndroid Build Coastguard Worker  * igt_plane_set_position:
3989*d83cc019SAndroid Build Coastguard Worker  * @plane: Plane pointer for which position is to be set
3990*d83cc019SAndroid Build Coastguard Worker  * @x: X coordinate
3991*d83cc019SAndroid Build Coastguard Worker  * @y: Y coordinate
3992*d83cc019SAndroid Build Coastguard Worker  *
3993*d83cc019SAndroid Build Coastguard Worker  * This function sets a new (x,y) position for the given plane.
3994*d83cc019SAndroid Build Coastguard Worker  * New position will be committed at plane commit time via drmModeSetPlane().
3995*d83cc019SAndroid Build Coastguard Worker  */
igt_plane_set_position(igt_plane_t * plane,int x,int y)3996*d83cc019SAndroid Build Coastguard Worker void igt_plane_set_position(igt_plane_t *plane, int x, int y)
3997*d83cc019SAndroid Build Coastguard Worker {
3998*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = plane->pipe;
3999*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
4000*d83cc019SAndroid Build Coastguard Worker 
4001*d83cc019SAndroid Build Coastguard Worker 	LOG(display, "%s.%d: plane_set_position(%d,%d)\n",
4002*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(pipe->pipe), plane->index, x, y);
4003*d83cc019SAndroid Build Coastguard Worker 
4004*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_X, x);
4005*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_Y, y);
4006*d83cc019SAndroid Build Coastguard Worker }
4007*d83cc019SAndroid Build Coastguard Worker 
4008*d83cc019SAndroid Build Coastguard Worker /**
4009*d83cc019SAndroid Build Coastguard Worker  * igt_plane_set_size:
4010*d83cc019SAndroid Build Coastguard Worker  * @plane: plane pointer for which size to be set
4011*d83cc019SAndroid Build Coastguard Worker  * @w: width
4012*d83cc019SAndroid Build Coastguard Worker  * @h: height
4013*d83cc019SAndroid Build Coastguard Worker  *
4014*d83cc019SAndroid Build Coastguard Worker  * This function sets width and height for requested plane.
4015*d83cc019SAndroid Build Coastguard Worker  * New size will be committed at plane commit time via
4016*d83cc019SAndroid Build Coastguard Worker  * drmModeSetPlane().
4017*d83cc019SAndroid Build Coastguard Worker  */
igt_plane_set_size(igt_plane_t * plane,int w,int h)4018*d83cc019SAndroid Build Coastguard Worker void igt_plane_set_size(igt_plane_t *plane, int w, int h)
4019*d83cc019SAndroid Build Coastguard Worker {
4020*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = plane->pipe;
4021*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
4022*d83cc019SAndroid Build Coastguard Worker 
4023*d83cc019SAndroid Build Coastguard Worker 	LOG(display, "%s.%d: plane_set_size (%dx%d)\n",
4024*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(pipe->pipe), plane->index, w, h);
4025*d83cc019SAndroid Build Coastguard Worker 
4026*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_W, w);
4027*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_H, h);
4028*d83cc019SAndroid Build Coastguard Worker }
4029*d83cc019SAndroid Build Coastguard Worker 
4030*d83cc019SAndroid Build Coastguard Worker /**
4031*d83cc019SAndroid Build Coastguard Worker  * igt_fb_set_position:
4032*d83cc019SAndroid Build Coastguard Worker  * @fb: framebuffer pointer
4033*d83cc019SAndroid Build Coastguard Worker  * @plane: plane
4034*d83cc019SAndroid Build Coastguard Worker  * @x: X position
4035*d83cc019SAndroid Build Coastguard Worker  * @y: Y position
4036*d83cc019SAndroid Build Coastguard Worker  *
4037*d83cc019SAndroid Build Coastguard Worker  * This function sets position for requested framebuffer as src to plane.
4038*d83cc019SAndroid Build Coastguard Worker  * New position will be committed at plane commit time via drmModeSetPlane().
4039*d83cc019SAndroid Build Coastguard Worker  */
igt_fb_set_position(struct igt_fb * fb,igt_plane_t * plane,uint32_t x,uint32_t y)4040*d83cc019SAndroid Build Coastguard Worker void igt_fb_set_position(struct igt_fb *fb, igt_plane_t *plane,
4041*d83cc019SAndroid Build Coastguard Worker 	uint32_t x, uint32_t y)
4042*d83cc019SAndroid Build Coastguard Worker {
4043*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = plane->pipe;
4044*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
4045*d83cc019SAndroid Build Coastguard Worker 
4046*d83cc019SAndroid Build Coastguard Worker 	LOG(display, "%s.%d: fb_set_position(%d,%d)\n",
4047*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(pipe->pipe), plane->index, x, y);
4048*d83cc019SAndroid Build Coastguard Worker 
4049*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_X, IGT_FIXED(x, 0));
4050*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_Y, IGT_FIXED(y, 0));
4051*d83cc019SAndroid Build Coastguard Worker }
4052*d83cc019SAndroid Build Coastguard Worker 
4053*d83cc019SAndroid Build Coastguard Worker /**
4054*d83cc019SAndroid Build Coastguard Worker  * igt_fb_set_size:
4055*d83cc019SAndroid Build Coastguard Worker  * @fb: framebuffer pointer
4056*d83cc019SAndroid Build Coastguard Worker  * @plane: plane
4057*d83cc019SAndroid Build Coastguard Worker  * @w: width
4058*d83cc019SAndroid Build Coastguard Worker  * @h: height
4059*d83cc019SAndroid Build Coastguard Worker  *
4060*d83cc019SAndroid Build Coastguard Worker  * This function sets fetch rect size from requested framebuffer as src
4061*d83cc019SAndroid Build Coastguard Worker  * to plane. New size will be committed at plane commit time via
4062*d83cc019SAndroid Build Coastguard Worker  * drmModeSetPlane().
4063*d83cc019SAndroid Build Coastguard Worker  */
igt_fb_set_size(struct igt_fb * fb,igt_plane_t * plane,uint32_t w,uint32_t h)4064*d83cc019SAndroid Build Coastguard Worker void igt_fb_set_size(struct igt_fb *fb, igt_plane_t *plane,
4065*d83cc019SAndroid Build Coastguard Worker 	uint32_t w, uint32_t h)
4066*d83cc019SAndroid Build Coastguard Worker {
4067*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = plane->pipe;
4068*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
4069*d83cc019SAndroid Build Coastguard Worker 
4070*d83cc019SAndroid Build Coastguard Worker 	LOG(display, "%s.%d: fb_set_size(%dx%d)\n",
4071*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(pipe->pipe), plane->index, w, h);
4072*d83cc019SAndroid Build Coastguard Worker 
4073*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_W, IGT_FIXED(w, 0));
4074*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_H, IGT_FIXED(h, 0));
4075*d83cc019SAndroid Build Coastguard Worker }
4076*d83cc019SAndroid Build Coastguard Worker 
rotation_name(igt_rotation_t rotation)4077*d83cc019SAndroid Build Coastguard Worker static const char *rotation_name(igt_rotation_t rotation)
4078*d83cc019SAndroid Build Coastguard Worker {
4079*d83cc019SAndroid Build Coastguard Worker 	switch (rotation & IGT_ROTATION_MASK) {
4080*d83cc019SAndroid Build Coastguard Worker 	case IGT_ROTATION_0:
4081*d83cc019SAndroid Build Coastguard Worker 		return "0°";
4082*d83cc019SAndroid Build Coastguard Worker 	case IGT_ROTATION_90:
4083*d83cc019SAndroid Build Coastguard Worker 		return "90°";
4084*d83cc019SAndroid Build Coastguard Worker 	case IGT_ROTATION_180:
4085*d83cc019SAndroid Build Coastguard Worker 		return "180°";
4086*d83cc019SAndroid Build Coastguard Worker 	case IGT_ROTATION_270:
4087*d83cc019SAndroid Build Coastguard Worker 		return "270°";
4088*d83cc019SAndroid Build Coastguard Worker 	default:
4089*d83cc019SAndroid Build Coastguard Worker 		igt_assert(0);
4090*d83cc019SAndroid Build Coastguard Worker 	}
4091*d83cc019SAndroid Build Coastguard Worker }
4092*d83cc019SAndroid Build Coastguard Worker 
4093*d83cc019SAndroid Build Coastguard Worker /**
4094*d83cc019SAndroid Build Coastguard Worker  * igt_plane_set_rotation:
4095*d83cc019SAndroid Build Coastguard Worker  * @plane: Plane pointer for which rotation is to be set
4096*d83cc019SAndroid Build Coastguard Worker  * @rotation: Plane rotation value (0, 90, 180, 270)
4097*d83cc019SAndroid Build Coastguard Worker  *
4098*d83cc019SAndroid Build Coastguard Worker  * This function sets a new rotation for the requested @plane.
4099*d83cc019SAndroid Build Coastguard Worker  * New @rotation will be committed at plane commit time via
4100*d83cc019SAndroid Build Coastguard Worker  * drmModeSetPlane().
4101*d83cc019SAndroid Build Coastguard Worker  */
igt_plane_set_rotation(igt_plane_t * plane,igt_rotation_t rotation)4102*d83cc019SAndroid Build Coastguard Worker void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation)
4103*d83cc019SAndroid Build Coastguard Worker {
4104*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_t *pipe = plane->pipe;
4105*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = pipe->display;
4106*d83cc019SAndroid Build Coastguard Worker 
4107*d83cc019SAndroid Build Coastguard Worker 	LOG(display, "%s.%d: plane_set_rotation(%s)\n",
4108*d83cc019SAndroid Build Coastguard Worker 	    kmstest_pipe_name(pipe->pipe),
4109*d83cc019SAndroid Build Coastguard Worker 	    plane->index, rotation_name(rotation));
4110*d83cc019SAndroid Build Coastguard Worker 
4111*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_prop_value(plane, IGT_PLANE_ROTATION, rotation);
4112*d83cc019SAndroid Build Coastguard Worker }
4113*d83cc019SAndroid Build Coastguard Worker 
4114*d83cc019SAndroid Build Coastguard Worker /**
4115*d83cc019SAndroid Build Coastguard Worker  * igt_pipe_request_out_fence:
4116*d83cc019SAndroid Build Coastguard Worker  * @pipe: pipe which out fence will be requested for
4117*d83cc019SAndroid Build Coastguard Worker  *
4118*d83cc019SAndroid Build Coastguard Worker  * Marks this pipe for requesting an out fence at the next atomic commit
4119*d83cc019SAndroid Build Coastguard Worker  * will contain the fd number of the out fence created by KMS.
4120*d83cc019SAndroid Build Coastguard Worker  */
igt_pipe_request_out_fence(igt_pipe_t * pipe)4121*d83cc019SAndroid Build Coastguard Worker void igt_pipe_request_out_fence(igt_pipe_t *pipe)
4122*d83cc019SAndroid Build Coastguard Worker {
4123*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
4124*d83cc019SAndroid Build Coastguard Worker }
4125*d83cc019SAndroid Build Coastguard Worker 
4126*d83cc019SAndroid Build Coastguard Worker /**
4127*d83cc019SAndroid Build Coastguard Worker  * igt_wait_for_vblank_count:
4128*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: A drm file descriptor
4129*d83cc019SAndroid Build Coastguard Worker  * @pipe: Pipe to wait_for_vblank on
4130*d83cc019SAndroid Build Coastguard Worker  * @count: Number of vblanks to wait on
4131*d83cc019SAndroid Build Coastguard Worker  *
4132*d83cc019SAndroid Build Coastguard Worker  * Waits for a given number of vertical blank intervals
4133*d83cc019SAndroid Build Coastguard Worker  */
igt_wait_for_vblank_count(int drm_fd,enum pipe pipe,int count)4134*d83cc019SAndroid Build Coastguard Worker void igt_wait_for_vblank_count(int drm_fd, enum pipe pipe, int count)
4135*d83cc019SAndroid Build Coastguard Worker {
4136*d83cc019SAndroid Build Coastguard Worker 	drmVBlank wait_vbl;
4137*d83cc019SAndroid Build Coastguard Worker 	uint32_t pipe_id_flag;
4138*d83cc019SAndroid Build Coastguard Worker 
4139*d83cc019SAndroid Build Coastguard Worker 	memset(&wait_vbl, 0, sizeof(wait_vbl));
4140*d83cc019SAndroid Build Coastguard Worker 	pipe_id_flag = kmstest_get_vbl_flag(pipe);
4141*d83cc019SAndroid Build Coastguard Worker 
4142*d83cc019SAndroid Build Coastguard Worker 	wait_vbl.request.type = DRM_VBLANK_RELATIVE;
4143*d83cc019SAndroid Build Coastguard Worker 	wait_vbl.request.type |= pipe_id_flag;
4144*d83cc019SAndroid Build Coastguard Worker 	wait_vbl.request.sequence = count;
4145*d83cc019SAndroid Build Coastguard Worker 
4146*d83cc019SAndroid Build Coastguard Worker 	igt_assert(drmWaitVBlank(drm_fd, &wait_vbl) == 0);
4147*d83cc019SAndroid Build Coastguard Worker }
4148*d83cc019SAndroid Build Coastguard Worker 
4149*d83cc019SAndroid Build Coastguard Worker /**
4150*d83cc019SAndroid Build Coastguard Worker  * igt_wait_for_vblank:
4151*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: A drm file descriptor
4152*d83cc019SAndroid Build Coastguard Worker  * @pipe: Pipe to wait_for_vblank on
4153*d83cc019SAndroid Build Coastguard Worker  *
4154*d83cc019SAndroid Build Coastguard Worker  * Waits for 1 vertical blank intervals
4155*d83cc019SAndroid Build Coastguard Worker  */
igt_wait_for_vblank(int drm_fd,enum pipe pipe)4156*d83cc019SAndroid Build Coastguard Worker void igt_wait_for_vblank(int drm_fd, enum pipe pipe)
4157*d83cc019SAndroid Build Coastguard Worker {
4158*d83cc019SAndroid Build Coastguard Worker 	igt_wait_for_vblank_count(drm_fd, pipe, 1);
4159*d83cc019SAndroid Build Coastguard Worker }
4160*d83cc019SAndroid Build Coastguard Worker 
4161*d83cc019SAndroid Build Coastguard Worker /**
4162*d83cc019SAndroid Build Coastguard Worker  * igt_enable_connectors:
4163*d83cc019SAndroid Build Coastguard Worker  * @drm_fd: A drm file descriptor
4164*d83cc019SAndroid Build Coastguard Worker  *
4165*d83cc019SAndroid Build Coastguard Worker  * Force connectors to be enabled where this is known to work well. Use
4166*d83cc019SAndroid Build Coastguard Worker  * #igt_reset_connectors to revert the changes.
4167*d83cc019SAndroid Build Coastguard Worker  *
4168*d83cc019SAndroid Build Coastguard Worker  * An exit handler is installed to ensure connectors are reset when the test
4169*d83cc019SAndroid Build Coastguard Worker  * exits.
4170*d83cc019SAndroid Build Coastguard Worker  */
igt_enable_connectors(int drm_fd)4171*d83cc019SAndroid Build Coastguard Worker void igt_enable_connectors(int drm_fd)
4172*d83cc019SAndroid Build Coastguard Worker {
4173*d83cc019SAndroid Build Coastguard Worker 	drmModeRes *res;
4174*d83cc019SAndroid Build Coastguard Worker 
4175*d83cc019SAndroid Build Coastguard Worker 	res = drmModeGetResources(drm_fd);
4176*d83cc019SAndroid Build Coastguard Worker 	if (!res)
4177*d83cc019SAndroid Build Coastguard Worker 		return;
4178*d83cc019SAndroid Build Coastguard Worker 
4179*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < res->count_connectors; i++) {
4180*d83cc019SAndroid Build Coastguard Worker 		drmModeConnector *c;
4181*d83cc019SAndroid Build Coastguard Worker 
4182*d83cc019SAndroid Build Coastguard Worker 		/* Do a probe. This may be the first action after booting */
4183*d83cc019SAndroid Build Coastguard Worker 		c = drmModeGetConnector(drm_fd, res->connectors[i]);
4184*d83cc019SAndroid Build Coastguard Worker 		if (!c) {
4185*d83cc019SAndroid Build Coastguard Worker 			igt_warn("Could not read connector %u: %m\n", res->connectors[i]);
4186*d83cc019SAndroid Build Coastguard Worker 			continue;
4187*d83cc019SAndroid Build Coastguard Worker 		}
4188*d83cc019SAndroid Build Coastguard Worker 
4189*d83cc019SAndroid Build Coastguard Worker 		/* don't attempt to force connectors that are already connected
4190*d83cc019SAndroid Build Coastguard Worker 		 */
4191*d83cc019SAndroid Build Coastguard Worker 		if (c->connection == DRM_MODE_CONNECTED)
4192*d83cc019SAndroid Build Coastguard Worker 			continue;
4193*d83cc019SAndroid Build Coastguard Worker 
4194*d83cc019SAndroid Build Coastguard Worker 		/* just enable VGA for now */
4195*d83cc019SAndroid Build Coastguard Worker 		if (c->connector_type == DRM_MODE_CONNECTOR_VGA) {
4196*d83cc019SAndroid Build Coastguard Worker 			if (!kmstest_force_connector(drm_fd, c, FORCE_CONNECTOR_ON))
4197*d83cc019SAndroid Build Coastguard Worker 				igt_info("Unable to force state on %s-%d\n",
4198*d83cc019SAndroid Build Coastguard Worker 					 kmstest_connector_type_str(c->connector_type),
4199*d83cc019SAndroid Build Coastguard Worker 					 c->connector_type_id);
4200*d83cc019SAndroid Build Coastguard Worker 		}
4201*d83cc019SAndroid Build Coastguard Worker 
4202*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeConnector(c);
4203*d83cc019SAndroid Build Coastguard Worker 	}
4204*d83cc019SAndroid Build Coastguard Worker }
4205*d83cc019SAndroid Build Coastguard Worker 
4206*d83cc019SAndroid Build Coastguard Worker /**
4207*d83cc019SAndroid Build Coastguard Worker  * igt_reset_connectors:
4208*d83cc019SAndroid Build Coastguard Worker  *
4209*d83cc019SAndroid Build Coastguard Worker  * Remove any forced state from the connectors.
4210*d83cc019SAndroid Build Coastguard Worker  */
igt_reset_connectors(void)4211*d83cc019SAndroid Build Coastguard Worker void igt_reset_connectors(void)
4212*d83cc019SAndroid Build Coastguard Worker {
4213*d83cc019SAndroid Build Coastguard Worker 	/* reset the connectors stored in forced_connectors, avoiding any
4214*d83cc019SAndroid Build Coastguard Worker 	 * functions that are not safe to call in signal handlers */
4215*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; forced_connectors[i]; i++)
4216*d83cc019SAndroid Build Coastguard Worker 		igt_sysfs_set(forced_connectors_device[i],
4217*d83cc019SAndroid Build Coastguard Worker 			      forced_connectors[i],
4218*d83cc019SAndroid Build Coastguard Worker 			      "detect");
4219*d83cc019SAndroid Build Coastguard Worker }
4220*d83cc019SAndroid Build Coastguard Worker 
4221*d83cc019SAndroid Build Coastguard Worker #if !defined(ANDROID)
4222*d83cc019SAndroid Build Coastguard Worker /**
4223*d83cc019SAndroid Build Coastguard Worker  * igt_watch_hotplug:
4224*d83cc019SAndroid Build Coastguard Worker  *
4225*d83cc019SAndroid Build Coastguard Worker  * Begin monitoring udev for sysfs hotplug events.
4226*d83cc019SAndroid Build Coastguard Worker  *
4227*d83cc019SAndroid Build Coastguard Worker  * Returns: a udev monitor for detecting hotplugs on
4228*d83cc019SAndroid Build Coastguard Worker  */
igt_watch_hotplug(void)4229*d83cc019SAndroid Build Coastguard Worker struct udev_monitor *igt_watch_hotplug(void)
4230*d83cc019SAndroid Build Coastguard Worker {
4231*d83cc019SAndroid Build Coastguard Worker 	struct udev *udev;
4232*d83cc019SAndroid Build Coastguard Worker 	struct udev_monitor *mon;
4233*d83cc019SAndroid Build Coastguard Worker 	int ret, flags, fd;
4234*d83cc019SAndroid Build Coastguard Worker 
4235*d83cc019SAndroid Build Coastguard Worker 	udev = udev_new();
4236*d83cc019SAndroid Build Coastguard Worker 	igt_assert(udev != NULL);
4237*d83cc019SAndroid Build Coastguard Worker 
4238*d83cc019SAndroid Build Coastguard Worker 	mon = udev_monitor_new_from_netlink(udev, "udev");
4239*d83cc019SAndroid Build Coastguard Worker 	igt_assert(mon != NULL);
4240*d83cc019SAndroid Build Coastguard Worker 
4241*d83cc019SAndroid Build Coastguard Worker 	ret = udev_monitor_filter_add_match_subsystem_devtype(mon,
4242*d83cc019SAndroid Build Coastguard Worker 							      "drm",
4243*d83cc019SAndroid Build Coastguard Worker 							      "drm_minor");
4244*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
4245*d83cc019SAndroid Build Coastguard Worker 	ret = udev_monitor_filter_update(mon);
4246*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
4247*d83cc019SAndroid Build Coastguard Worker 	ret = udev_monitor_enable_receiving(mon);
4248*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
4249*d83cc019SAndroid Build Coastguard Worker 
4250*d83cc019SAndroid Build Coastguard Worker 	/* Set the fd for udev as non blocking */
4251*d83cc019SAndroid Build Coastguard Worker 	fd = udev_monitor_get_fd(mon);
4252*d83cc019SAndroid Build Coastguard Worker 	flags = fcntl(fd, F_GETFL, 0);
4253*d83cc019SAndroid Build Coastguard Worker 	igt_assert(flags);
4254*d83cc019SAndroid Build Coastguard Worker 
4255*d83cc019SAndroid Build Coastguard Worker 	flags |= O_NONBLOCK;
4256*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(fcntl(fd, F_SETFL, flags), -1);
4257*d83cc019SAndroid Build Coastguard Worker 
4258*d83cc019SAndroid Build Coastguard Worker 	return mon;
4259*d83cc019SAndroid Build Coastguard Worker }
4260*d83cc019SAndroid Build Coastguard Worker 
event_detected(struct udev_monitor * mon,int timeout_secs,const char * property)4261*d83cc019SAndroid Build Coastguard Worker static bool event_detected(struct udev_monitor *mon, int timeout_secs,
4262*d83cc019SAndroid Build Coastguard Worker 			   const char *property)
4263*d83cc019SAndroid Build Coastguard Worker {
4264*d83cc019SAndroid Build Coastguard Worker 	struct udev_device *dev;
4265*d83cc019SAndroid Build Coastguard Worker 	const char *hotplug_val;
4266*d83cc019SAndroid Build Coastguard Worker 	struct pollfd fd = {
4267*d83cc019SAndroid Build Coastguard Worker 		.fd = udev_monitor_get_fd(mon),
4268*d83cc019SAndroid Build Coastguard Worker 		.events = POLLIN
4269*d83cc019SAndroid Build Coastguard Worker 	};
4270*d83cc019SAndroid Build Coastguard Worker 	bool hotplug_received = false;
4271*d83cc019SAndroid Build Coastguard Worker 
4272*d83cc019SAndroid Build Coastguard Worker 	/* Go through all of the events pending on the udev monitor. Once we
4273*d83cc019SAndroid Build Coastguard Worker 	 * receive a hotplug, we continue going through the rest of the events
4274*d83cc019SAndroid Build Coastguard Worker 	 * so that redundant hotplug events don't change the results of future
4275*d83cc019SAndroid Build Coastguard Worker 	 * checks
4276*d83cc019SAndroid Build Coastguard Worker 	 */
4277*d83cc019SAndroid Build Coastguard Worker 	while (!hotplug_received && poll(&fd, 1, timeout_secs * 1000)) {
4278*d83cc019SAndroid Build Coastguard Worker 		dev = udev_monitor_receive_device(mon);
4279*d83cc019SAndroid Build Coastguard Worker 
4280*d83cc019SAndroid Build Coastguard Worker 		hotplug_val = udev_device_get_property_value(dev, property);
4281*d83cc019SAndroid Build Coastguard Worker 		if (hotplug_val && atoi(hotplug_val) == 1)
4282*d83cc019SAndroid Build Coastguard Worker 			hotplug_received = true;
4283*d83cc019SAndroid Build Coastguard Worker 
4284*d83cc019SAndroid Build Coastguard Worker 		udev_device_unref(dev);
4285*d83cc019SAndroid Build Coastguard Worker 	}
4286*d83cc019SAndroid Build Coastguard Worker 
4287*d83cc019SAndroid Build Coastguard Worker 	return hotplug_received;
4288*d83cc019SAndroid Build Coastguard Worker }
4289*d83cc019SAndroid Build Coastguard Worker 
4290*d83cc019SAndroid Build Coastguard Worker /**
4291*d83cc019SAndroid Build Coastguard Worker  * igt_hotplug_detected:
4292*d83cc019SAndroid Build Coastguard Worker  * @mon: A udev monitor initialized with #igt_watch_hotplug
4293*d83cc019SAndroid Build Coastguard Worker  * @timeout_secs: How long to wait for a hotplug event to occur.
4294*d83cc019SAndroid Build Coastguard Worker  *
4295*d83cc019SAndroid Build Coastguard Worker  * Assert that a hotplug event was received since we last checked the monitor.
4296*d83cc019SAndroid Build Coastguard Worker  *
4297*d83cc019SAndroid Build Coastguard Worker  * Returns: true if a sysfs hotplug event was received, false if we timed out
4298*d83cc019SAndroid Build Coastguard Worker  */
igt_hotplug_detected(struct udev_monitor * mon,int timeout_secs)4299*d83cc019SAndroid Build Coastguard Worker bool igt_hotplug_detected(struct udev_monitor *mon, int timeout_secs)
4300*d83cc019SAndroid Build Coastguard Worker {
4301*d83cc019SAndroid Build Coastguard Worker 	return event_detected(mon, timeout_secs, "HOTPLUG");
4302*d83cc019SAndroid Build Coastguard Worker }
4303*d83cc019SAndroid Build Coastguard Worker 
4304*d83cc019SAndroid Build Coastguard Worker /**
4305*d83cc019SAndroid Build Coastguard Worker  * igt_lease_change_detected:
4306*d83cc019SAndroid Build Coastguard Worker  * @mon: A udev monitor initialized with #igt_watch_hotplug
4307*d83cc019SAndroid Build Coastguard Worker  * @timeout_secs: How long to wait for a lease change event to occur.
4308*d83cc019SAndroid Build Coastguard Worker  *
4309*d83cc019SAndroid Build Coastguard Worker  * Assert that a lease change event was received since we last checked the monitor.
4310*d83cc019SAndroid Build Coastguard Worker  *
4311*d83cc019SAndroid Build Coastguard Worker  * Returns: true if a sysfs lease change event was received, false if we timed out
4312*d83cc019SAndroid Build Coastguard Worker  */
igt_lease_change_detected(struct udev_monitor * mon,int timeout_secs)4313*d83cc019SAndroid Build Coastguard Worker bool igt_lease_change_detected(struct udev_monitor *mon, int timeout_secs)
4314*d83cc019SAndroid Build Coastguard Worker {
4315*d83cc019SAndroid Build Coastguard Worker 	return event_detected(mon, timeout_secs, "LEASE");
4316*d83cc019SAndroid Build Coastguard Worker }
4317*d83cc019SAndroid Build Coastguard Worker 
4318*d83cc019SAndroid Build Coastguard Worker /**
4319*d83cc019SAndroid Build Coastguard Worker  * igt_flush_hotplugs:
4320*d83cc019SAndroid Build Coastguard Worker  * @mon: A udev monitor initialized with #igt_watch_hotplug
4321*d83cc019SAndroid Build Coastguard Worker  *
4322*d83cc019SAndroid Build Coastguard Worker  * Get rid of any pending hotplug events
4323*d83cc019SAndroid Build Coastguard Worker  */
igt_flush_hotplugs(struct udev_monitor * mon)4324*d83cc019SAndroid Build Coastguard Worker void igt_flush_hotplugs(struct udev_monitor *mon)
4325*d83cc019SAndroid Build Coastguard Worker {
4326*d83cc019SAndroid Build Coastguard Worker 	struct udev_device *dev;
4327*d83cc019SAndroid Build Coastguard Worker 
4328*d83cc019SAndroid Build Coastguard Worker 	while ((dev = udev_monitor_receive_device(mon)))
4329*d83cc019SAndroid Build Coastguard Worker 		udev_device_unref(dev);
4330*d83cc019SAndroid Build Coastguard Worker }
4331*d83cc019SAndroid Build Coastguard Worker 
4332*d83cc019SAndroid Build Coastguard Worker /**
4333*d83cc019SAndroid Build Coastguard Worker  * igt_cleanup_hotplug:
4334*d83cc019SAndroid Build Coastguard Worker  * @mon: A udev monitor initialized with #igt_watch_hotplug
4335*d83cc019SAndroid Build Coastguard Worker  *
4336*d83cc019SAndroid Build Coastguard Worker  * Cleanup the resources allocated by #igt_watch_hotplug
4337*d83cc019SAndroid Build Coastguard Worker  */
igt_cleanup_hotplug(struct udev_monitor * mon)4338*d83cc019SAndroid Build Coastguard Worker void igt_cleanup_hotplug(struct udev_monitor *mon)
4339*d83cc019SAndroid Build Coastguard Worker {
4340*d83cc019SAndroid Build Coastguard Worker 	struct udev *udev = udev_monitor_get_udev(mon);
4341*d83cc019SAndroid Build Coastguard Worker 
4342*d83cc019SAndroid Build Coastguard Worker 	udev_monitor_unref(mon);
4343*d83cc019SAndroid Build Coastguard Worker 	mon = NULL;
4344*d83cc019SAndroid Build Coastguard Worker 	udev_unref(udev);
4345*d83cc019SAndroid Build Coastguard Worker }
4346*d83cc019SAndroid Build Coastguard Worker #endif /*!defined(ANDROID)*/
4347*d83cc019SAndroid Build Coastguard Worker 
4348*d83cc019SAndroid Build Coastguard Worker /**
4349*d83cc019SAndroid Build Coastguard Worker  * kmstest_get_vbl_flag:
4350*d83cc019SAndroid Build Coastguard Worker  * @pipe_id: Pipe to convert to flag representation.
4351*d83cc019SAndroid Build Coastguard Worker  *
4352*d83cc019SAndroid Build Coastguard Worker  * Convert a pipe id into the flag representation
4353*d83cc019SAndroid Build Coastguard Worker  * expected in DRM while processing DRM_IOCTL_WAIT_VBLANK.
4354*d83cc019SAndroid Build Coastguard Worker  */
kmstest_get_vbl_flag(uint32_t pipe_id)4355*d83cc019SAndroid Build Coastguard Worker uint32_t kmstest_get_vbl_flag(uint32_t pipe_id)
4356*d83cc019SAndroid Build Coastguard Worker {
4357*d83cc019SAndroid Build Coastguard Worker 	if (pipe_id == 0)
4358*d83cc019SAndroid Build Coastguard Worker 		return 0;
4359*d83cc019SAndroid Build Coastguard Worker 	else if (pipe_id == 1)
4360*d83cc019SAndroid Build Coastguard Worker 		return _DRM_VBLANK_SECONDARY;
4361*d83cc019SAndroid Build Coastguard Worker 	else {
4362*d83cc019SAndroid Build Coastguard Worker 		uint32_t pipe_flag = pipe_id << 1;
4363*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!(pipe_flag & ~DRM_VBLANK_HIGH_CRTC_MASK));
4364*d83cc019SAndroid Build Coastguard Worker 		return pipe_flag;
4365*d83cc019SAndroid Build Coastguard Worker 	}
4366*d83cc019SAndroid Build Coastguard Worker }
4367*d83cc019SAndroid Build Coastguard Worker 
4368*d83cc019SAndroid Build Coastguard Worker static inline const uint32_t *
formats_ptr(const struct drm_format_modifier_blob * blob)4369*d83cc019SAndroid Build Coastguard Worker formats_ptr(const struct drm_format_modifier_blob *blob)
4370*d83cc019SAndroid Build Coastguard Worker {
4371*d83cc019SAndroid Build Coastguard Worker 	return (const uint32_t *)((const char *)blob + blob->formats_offset);
4372*d83cc019SAndroid Build Coastguard Worker }
4373*d83cc019SAndroid Build Coastguard Worker 
4374*d83cc019SAndroid Build Coastguard Worker static inline const struct drm_format_modifier *
modifiers_ptr(const struct drm_format_modifier_blob * blob)4375*d83cc019SAndroid Build Coastguard Worker modifiers_ptr(const struct drm_format_modifier_blob *blob)
4376*d83cc019SAndroid Build Coastguard Worker {
4377*d83cc019SAndroid Build Coastguard Worker 	return (const struct drm_format_modifier *)((const char *)blob + blob->modifiers_offset);
4378*d83cc019SAndroid Build Coastguard Worker }
4379*d83cc019SAndroid Build Coastguard Worker 
igt_count_plane_format_mod(const struct drm_format_modifier_blob * blob_data)4380*d83cc019SAndroid Build Coastguard Worker static int igt_count_plane_format_mod(const struct drm_format_modifier_blob *blob_data)
4381*d83cc019SAndroid Build Coastguard Worker {
4382*d83cc019SAndroid Build Coastguard Worker 	const struct drm_format_modifier *modifiers;
4383*d83cc019SAndroid Build Coastguard Worker 	int count = 0;
4384*d83cc019SAndroid Build Coastguard Worker 
4385*d83cc019SAndroid Build Coastguard Worker 	modifiers = modifiers_ptr(blob_data);
4386*d83cc019SAndroid Build Coastguard Worker 
4387*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < blob_data->count_modifiers; i++)
4388*d83cc019SAndroid Build Coastguard Worker 		count += igt_hweight(modifiers[i].formats);
4389*d83cc019SAndroid Build Coastguard Worker 
4390*d83cc019SAndroid Build Coastguard Worker 	return count;
4391*d83cc019SAndroid Build Coastguard Worker }
4392*d83cc019SAndroid Build Coastguard Worker 
igt_fill_plane_format_mod(igt_display_t * display,igt_plane_t * plane)4393*d83cc019SAndroid Build Coastguard Worker static void igt_fill_plane_format_mod(igt_display_t *display, igt_plane_t *plane)
4394*d83cc019SAndroid Build Coastguard Worker {
4395*d83cc019SAndroid Build Coastguard Worker 	const struct drm_format_modifier_blob *blob_data;
4396*d83cc019SAndroid Build Coastguard Worker 	drmModePropertyBlobPtr blob;
4397*d83cc019SAndroid Build Coastguard Worker 	uint64_t blob_id;
4398*d83cc019SAndroid Build Coastguard Worker 	int idx = 0;
4399*d83cc019SAndroid Build Coastguard Worker 	int count;
4400*d83cc019SAndroid Build Coastguard Worker 
4401*d83cc019SAndroid Build Coastguard Worker 	if (!igt_plane_has_prop(plane, IGT_PLANE_IN_FORMATS)) {
4402*d83cc019SAndroid Build Coastguard Worker 		drmModePlanePtr p = plane->drm_plane;
4403*d83cc019SAndroid Build Coastguard Worker 
4404*d83cc019SAndroid Build Coastguard Worker 		count = p->count_formats;
4405*d83cc019SAndroid Build Coastguard Worker 
4406*d83cc019SAndroid Build Coastguard Worker 		plane->format_mod_count = count;
4407*d83cc019SAndroid Build Coastguard Worker 		plane->formats = calloc(count, sizeof(plane->formats[0]));
4408*d83cc019SAndroid Build Coastguard Worker 		igt_assert(plane->formats);
4409*d83cc019SAndroid Build Coastguard Worker 		plane->modifiers = calloc(count, sizeof(plane->modifiers[0]));
4410*d83cc019SAndroid Build Coastguard Worker 		igt_assert(plane->modifiers);
4411*d83cc019SAndroid Build Coastguard Worker 
4412*d83cc019SAndroid Build Coastguard Worker 		/*
4413*d83cc019SAndroid Build Coastguard Worker 		 * We don't know which modifiers are
4414*d83cc019SAndroid Build Coastguard Worker 		 * supported, so we'll assume linear only.
4415*d83cc019SAndroid Build Coastguard Worker 		 */
4416*d83cc019SAndroid Build Coastguard Worker 		for (int i = 0; i < count; i++) {
4417*d83cc019SAndroid Build Coastguard Worker 			plane->formats[i] = p->formats[i];
4418*d83cc019SAndroid Build Coastguard Worker 			plane->modifiers[i] = DRM_FORMAT_MOD_LINEAR;
4419*d83cc019SAndroid Build Coastguard Worker 		}
4420*d83cc019SAndroid Build Coastguard Worker 
4421*d83cc019SAndroid Build Coastguard Worker 		return;
4422*d83cc019SAndroid Build Coastguard Worker 	}
4423*d83cc019SAndroid Build Coastguard Worker 
4424*d83cc019SAndroid Build Coastguard Worker 	blob_id = igt_plane_get_prop(plane, IGT_PLANE_IN_FORMATS);
4425*d83cc019SAndroid Build Coastguard Worker 
4426*d83cc019SAndroid Build Coastguard Worker 	blob = drmModeGetPropertyBlob(display->drm_fd, blob_id);
4427*d83cc019SAndroid Build Coastguard Worker 	if (!blob)
4428*d83cc019SAndroid Build Coastguard Worker 		return;
4429*d83cc019SAndroid Build Coastguard Worker 
4430*d83cc019SAndroid Build Coastguard Worker 	blob_data = (const struct drm_format_modifier_blob *) blob->data;
4431*d83cc019SAndroid Build Coastguard Worker 
4432*d83cc019SAndroid Build Coastguard Worker 	count = igt_count_plane_format_mod(blob_data);
4433*d83cc019SAndroid Build Coastguard Worker 	if (!count)
4434*d83cc019SAndroid Build Coastguard Worker 		return;
4435*d83cc019SAndroid Build Coastguard Worker 
4436*d83cc019SAndroid Build Coastguard Worker 	plane->format_mod_count = count;
4437*d83cc019SAndroid Build Coastguard Worker 	plane->formats = calloc(count, sizeof(plane->formats[0]));
4438*d83cc019SAndroid Build Coastguard Worker 	igt_assert(plane->formats);
4439*d83cc019SAndroid Build Coastguard Worker 	plane->modifiers = calloc(count, sizeof(plane->modifiers[0]));
4440*d83cc019SAndroid Build Coastguard Worker 	igt_assert(plane->modifiers);
4441*d83cc019SAndroid Build Coastguard Worker 
4442*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < blob_data->count_modifiers; i++) {
4443*d83cc019SAndroid Build Coastguard Worker 		for (int j = 0; j < 64; j++) {
4444*d83cc019SAndroid Build Coastguard Worker 			const struct drm_format_modifier *modifiers =
4445*d83cc019SAndroid Build Coastguard Worker 				modifiers_ptr(blob_data);
4446*d83cc019SAndroid Build Coastguard Worker 			const uint32_t *formats = formats_ptr(blob_data);
4447*d83cc019SAndroid Build Coastguard Worker 
4448*d83cc019SAndroid Build Coastguard Worker 			if (!(modifiers[i].formats & (1ULL << j)))
4449*d83cc019SAndroid Build Coastguard Worker 				continue;
4450*d83cc019SAndroid Build Coastguard Worker 
4451*d83cc019SAndroid Build Coastguard Worker 			plane->formats[idx] = formats[modifiers[i].offset + j];
4452*d83cc019SAndroid Build Coastguard Worker 			plane->modifiers[idx] = modifiers[i].modifier;
4453*d83cc019SAndroid Build Coastguard Worker 			idx++;
4454*d83cc019SAndroid Build Coastguard Worker 			igt_assert_lte(idx, plane->format_mod_count);
4455*d83cc019SAndroid Build Coastguard Worker 		}
4456*d83cc019SAndroid Build Coastguard Worker 	}
4457*d83cc019SAndroid Build Coastguard Worker 
4458*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(idx, plane->format_mod_count);
4459*d83cc019SAndroid Build Coastguard Worker }
4460*d83cc019SAndroid Build Coastguard Worker 
igt_plane_has_format_mod(igt_plane_t * plane,uint32_t format,uint64_t modifier)4461*d83cc019SAndroid Build Coastguard Worker bool igt_plane_has_format_mod(igt_plane_t *plane, uint32_t format,
4462*d83cc019SAndroid Build Coastguard Worker 			      uint64_t modifier)
4463*d83cc019SAndroid Build Coastguard Worker {
4464*d83cc019SAndroid Build Coastguard Worker 	int i;
4465*d83cc019SAndroid Build Coastguard Worker 
4466*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < plane->format_mod_count; i++) {
4467*d83cc019SAndroid Build Coastguard Worker 		if (plane->formats[i] == format &&
4468*d83cc019SAndroid Build Coastguard Worker 		    plane->modifiers[i] == modifier)
4469*d83cc019SAndroid Build Coastguard Worker 			return true;
4470*d83cc019SAndroid Build Coastguard Worker 
4471*d83cc019SAndroid Build Coastguard Worker 	}
4472*d83cc019SAndroid Build Coastguard Worker 
4473*d83cc019SAndroid Build Coastguard Worker 	return false;
4474*d83cc019SAndroid Build Coastguard Worker }
4475*d83cc019SAndroid Build Coastguard Worker 
igt_count_display_format_mod(igt_display_t * display)4476*d83cc019SAndroid Build Coastguard Worker static int igt_count_display_format_mod(igt_display_t *display)
4477*d83cc019SAndroid Build Coastguard Worker {
4478*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
4479*d83cc019SAndroid Build Coastguard Worker 	int count = 0;
4480*d83cc019SAndroid Build Coastguard Worker 
4481*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe(display, pipe) {
4482*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane;
4483*d83cc019SAndroid Build Coastguard Worker 
4484*d83cc019SAndroid Build Coastguard Worker 		for_each_plane_on_pipe(display, pipe, plane) {
4485*d83cc019SAndroid Build Coastguard Worker 			count += plane->format_mod_count;
4486*d83cc019SAndroid Build Coastguard Worker 		}
4487*d83cc019SAndroid Build Coastguard Worker 	}
4488*d83cc019SAndroid Build Coastguard Worker 
4489*d83cc019SAndroid Build Coastguard Worker 	return count;
4490*d83cc019SAndroid Build Coastguard Worker }
4491*d83cc019SAndroid Build Coastguard Worker 
4492*d83cc019SAndroid Build Coastguard Worker static void
igt_add_display_format_mod(igt_display_t * display,uint32_t format,uint64_t modifier)4493*d83cc019SAndroid Build Coastguard Worker igt_add_display_format_mod(igt_display_t *display, uint32_t format,
4494*d83cc019SAndroid Build Coastguard Worker 			   uint64_t modifier)
4495*d83cc019SAndroid Build Coastguard Worker {
4496*d83cc019SAndroid Build Coastguard Worker 	int i;
4497*d83cc019SAndroid Build Coastguard Worker 
4498*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->format_mod_count; i++) {
4499*d83cc019SAndroid Build Coastguard Worker 		if (display->formats[i] == format &&
4500*d83cc019SAndroid Build Coastguard Worker 		    display->modifiers[i] == modifier)
4501*d83cc019SAndroid Build Coastguard Worker 			return;
4502*d83cc019SAndroid Build Coastguard Worker 
4503*d83cc019SAndroid Build Coastguard Worker 	}
4504*d83cc019SAndroid Build Coastguard Worker 
4505*d83cc019SAndroid Build Coastguard Worker 	display->formats[i] = format;
4506*d83cc019SAndroid Build Coastguard Worker 	display->modifiers[i] = modifier;
4507*d83cc019SAndroid Build Coastguard Worker 	display->format_mod_count++;
4508*d83cc019SAndroid Build Coastguard Worker }
4509*d83cc019SAndroid Build Coastguard Worker 
igt_fill_display_format_mod(igt_display_t * display)4510*d83cc019SAndroid Build Coastguard Worker static void igt_fill_display_format_mod(igt_display_t *display)
4511*d83cc019SAndroid Build Coastguard Worker {
4512*d83cc019SAndroid Build Coastguard Worker 	int count = igt_count_display_format_mod(display);
4513*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
4514*d83cc019SAndroid Build Coastguard Worker 
4515*d83cc019SAndroid Build Coastguard Worker 	if (!count)
4516*d83cc019SAndroid Build Coastguard Worker 		return;
4517*d83cc019SAndroid Build Coastguard Worker 
4518*d83cc019SAndroid Build Coastguard Worker 	display->formats = calloc(count, sizeof(display->formats[0]));
4519*d83cc019SAndroid Build Coastguard Worker 	igt_assert(display->formats);
4520*d83cc019SAndroid Build Coastguard Worker 	display->modifiers = calloc(count, sizeof(display->modifiers[0]));
4521*d83cc019SAndroid Build Coastguard Worker 	igt_assert(display->modifiers);
4522*d83cc019SAndroid Build Coastguard Worker 
4523*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe(display, pipe) {
4524*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane;
4525*d83cc019SAndroid Build Coastguard Worker 
4526*d83cc019SAndroid Build Coastguard Worker 		for_each_plane_on_pipe(display, pipe, plane) {
4527*d83cc019SAndroid Build Coastguard Worker 			for (int i = 0; i < plane->format_mod_count; i++) {
4528*d83cc019SAndroid Build Coastguard Worker 				igt_add_display_format_mod(display,
4529*d83cc019SAndroid Build Coastguard Worker 							   plane->formats[i],
4530*d83cc019SAndroid Build Coastguard Worker 							   plane->modifiers[i]);
4531*d83cc019SAndroid Build Coastguard Worker 				igt_assert_lte(display->format_mod_count, count);
4532*d83cc019SAndroid Build Coastguard Worker 			}
4533*d83cc019SAndroid Build Coastguard Worker 		}
4534*d83cc019SAndroid Build Coastguard Worker 	}
4535*d83cc019SAndroid Build Coastguard Worker }
4536*d83cc019SAndroid Build Coastguard Worker 
igt_display_has_format_mod(igt_display_t * display,uint32_t format,uint64_t modifier)4537*d83cc019SAndroid Build Coastguard Worker bool igt_display_has_format_mod(igt_display_t *display, uint32_t format,
4538*d83cc019SAndroid Build Coastguard Worker 				uint64_t modifier)
4539*d83cc019SAndroid Build Coastguard Worker {
4540*d83cc019SAndroid Build Coastguard Worker 	int i;
4541*d83cc019SAndroid Build Coastguard Worker 
4542*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->format_mod_count; i++) {
4543*d83cc019SAndroid Build Coastguard Worker 		if (display->formats[i] == format &&
4544*d83cc019SAndroid Build Coastguard Worker 		    display->modifiers[i] == modifier)
4545*d83cc019SAndroid Build Coastguard Worker 			return true;
4546*d83cc019SAndroid Build Coastguard Worker 
4547*d83cc019SAndroid Build Coastguard Worker 	}
4548*d83cc019SAndroid Build Coastguard Worker 
4549*d83cc019SAndroid Build Coastguard Worker 	return false;
4550*d83cc019SAndroid Build Coastguard Worker }
4551