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