modetest.c revision 8e56579b203a11c718c5e3da6fdb03b4f9b9fe56
1731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/*
2731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * DRM based mode setting test program
3731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Copyright 2008 Tungsten Graphics
4731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *   Jakob Bornecrantz <jakob@tungstengraphics.com>
5731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Copyright 2008 Intel Corporation
6731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *   Jesse Barnes <jesse.barnes@intel.com>
7731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *
8731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Permission is hereby granted, free of charge, to any person obtaining a
9731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * copy of this software and associated documentation files (the "Software"),
10731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * to deal in the Software without restriction, including without limitation
11731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * and/or sell copies of the Software, and to permit persons to whom the
13731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Software is furnished to do so, subject to the following conditions:
14731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *
15731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * The above copyright notice and this permission notice shall be included in
16731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * all copies or substantial portions of the Software.
17731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *
18731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * IN THE SOFTWARE.
25731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */
26731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
27731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/*
28731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * This fairly simple test program dumps output in a similar format to the
29731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * "xrandr" tool everyone knows & loves.  It's necessarily slightly different
30731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * since the kernel separates outputs into encoder and connector structures,
31731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * each with their own unique ID.  The program also allows test testing of the
32731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * memory management and mode setting APIs by allowing the user to specify a
33731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * connector and mode to use for mode setting.  If all works as expected, a
34731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * blue background should be painted on the monitor attached to the specified
35731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * connector after the selected mode is set.
36731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *
37731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * TODO: use cairo to write the mode info on the selected output once
38731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *       the mode has been programmed, along with possible test patterns.
39731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */
407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include "config.h"
417a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
42731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <assert.h>
43731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdio.h>
44731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdlib.h>
45731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdint.h>
46d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni#include <inttypes.h>
47731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <unistd.h>
48731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <string.h>
49731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <errno.h>
501e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg#include <sys/poll.h>
51e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell#include <sys/time.h>
52731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
53731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drm.h"
54731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drmMode.h"
55d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark#include "drm_fourcc.h"
568fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#include "libkms.h"
57731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
58db004badef9315ba6a5f165d0974dd5afd5a6178Laurent Pinchart#include "buffers.h"
597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
60731cd5526e5c732d51307b26e784f454a724a699Jesse BarnesdrmModeRes *resources;
61731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint fd, modes;
62731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
63731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
64731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
65731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name {
66731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int type;
67731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	char *name;
68731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
69731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
70731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define type_name_fn(res) \
71731cd5526e5c732d51307b26e784f454a724a699Jesse Barneschar * res##_str(int type) {			\
729b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	unsigned int i;					\
73731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
74731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (res##_names[i].type == type)	\
75731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			return res##_names[i].name;	\
76731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}						\
77731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return "(invalid)";				\
78731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
79731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
80731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name encoder_type_names[] = {
81731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_NONE, "none" },
82731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_DAC, "DAC" },
83731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
84731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
85731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_TVDAC, "TVDAC" },
86731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
87731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
88731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(encoder_type)
89731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
90731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_status_names[] = {
91731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTED, "connected" },
92731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_DISCONNECTED, "disconnected" },
93731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_UNKNOWNCONNECTION, "unknown" },
94731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
95731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
96731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_status)
97731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
98731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_type_names[] = {
99731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Unknown, "unknown" },
100731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_VGA, "VGA" },
101731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
102731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
103731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
104731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Composite, "composite" },
105731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
106731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
107731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Component, "component" },
108731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
109731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DisplayPort, "displayport" },
110731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
111731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
112b8abe6139e5c6779ee87d983346f0f65bf67462eJesse Barnes	{ DRM_MODE_CONNECTOR_TV, "TV" },
113b8abe6139e5c6779ee87d983346f0f65bf67462eJesse Barnes	{ DRM_MODE_CONNECTOR_eDP, "embedded displayport" },
114731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
115731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
116731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_type)
117731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
118c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg#define bit_name_fn(res)					\
119c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergchar * res##_str(int type) {					\
120c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	int i;							\
121c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	const char *sep = "";					\
122c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	for (i = 0; i < ARRAY_SIZE(res##_names); i++) {		\
123c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg		if (type & (1 << i)) {				\
124c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg			printf("%s%s", sep, res##_names[i]);	\
125c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg			sep = ", ";				\
126c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg		}						\
127c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	}							\
1286fa2b29d226306870eebe93afb2106ca7d79569bTobias Klausmann	return NULL;						\
129c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg}
130c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
131c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_type_names[] = {
132c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"builtin",
133c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"clock_c",
134c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"crtc_c",
135c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"preferred",
136c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"default",
137c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"userdef",
138c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"driver",
139c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg};
140c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
141c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergbit_name_fn(mode_type)
142c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
143c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_flag_names[] = {
144c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"phsync",
145c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"nhsync",
146c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"pvsync",
147c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"nvsync",
148c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"interlace",
149c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"dblscan",
150c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"csync",
151c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"pcsync",
152c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"ncsync",
153c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"hskew",
154c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"bcast",
155c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"pixmux",
156c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"dblclk",
157c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"clkdiv2"
158c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg};
159c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
160c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergbit_name_fn(mode_flag)
161c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
162731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_encoders(void)
163731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
164731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeEncoder *encoder;
165731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
166731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
167731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("Encoders:\n");
168731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n");
169731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_encoders; i++) {
170731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		encoder = drmModeGetEncoder(fd, resources->encoders[i]);
171731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
172731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!encoder) {
173731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get encoder %i: %s\n",
174731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->encoders[i], strerror(errno));
175731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
176731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
177731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("%d\t%d\t%s\t0x%08x\t0x%08x\n",
178731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->encoder_id,
179731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->crtc_id,
180731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder_type_str(encoder->encoder_type),
181731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->possible_crtcs,
182731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->possible_clones);
183731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeEncoder(encoder);
184731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1850243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
1860243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg}
1870243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
1889fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergvoid dump_mode(drmModeModeInfo *mode)
1890243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg{
190c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	printf("  %s %d %d %d %d %d %d %d %d %d",
1910243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->name,
192694ef59532253727176ed0ce9077ae3ec41dd457Marcin Kościelnicki	       mode->vrefresh,
1930243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hdisplay,
1940243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hsync_start,
1950243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hsync_end,
1960243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->htotal,
1970243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vdisplay,
1980243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vsync_start,
1990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vsync_end,
2000243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vtotal);
201c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
202c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	printf(" flags: ");
203c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	mode_flag_str(mode->flags);
204c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	printf("; type: ");
205c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	mode_type_str(mode->type);
206c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	printf("\n");
207731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
208731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2099fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergstatic void
210d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonidump_blob(uint32_t blob_id)
211d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni{
212d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	uint32_t i;
213d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	unsigned char *blob_data;
214d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	drmModePropertyBlobPtr blob;
215d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
216d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	blob = drmModeGetPropertyBlob(fd, blob_id);
217d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (!blob)
218d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		return;
219d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
220d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	blob_data = blob->data;
221d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
222d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	for (i = 0; i < blob->length; i++) {
223d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		if (i % 16 == 0)
224d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			printf("\n\t\t\t");
225d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("%.2hhx", blob_data[i]);
226d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	}
227d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\n");
228d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
229d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	drmModeFreePropertyBlob(blob);
230d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni}
231d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
232d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonistatic void
233d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonidump_prop(uint32_t prop_id, uint64_t value)
2349fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg{
2359fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	int i;
236d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	drmModePropertyPtr prop;
237d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
238d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	prop = drmModeGetProperty(fd, prop_id);
239d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
240d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\t%d", prop_id);
241d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (!prop) {
242d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\n");
243d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		return;
244d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	}
245d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
246d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf(" %s:\n", prop->name);
247d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
248d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\t\tflags:");
249d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_PENDING)
250d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" pending");
251d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_RANGE)
252d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" range");
253d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_IMMUTABLE)
254d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" immutable");
255d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_ENUM)
256d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" enum");
2576df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark	if (prop->flags & DRM_MODE_PROP_BITMASK)
2586df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark		printf(" bitmask");
259d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_BLOB)
260d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" blob");
261d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\n");
2629fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg
263d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_RANGE) {
264d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\t\tvalues:");
265d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		for (i = 0; i < prop->count_values; i++)
266d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			printf(" %"PRIu64, prop->values[i]);
267d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\n");
2689fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	}
269d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
270d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_ENUM) {
271d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\t\tenums:");
272d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		for (i = 0; i < prop->count_enums; i++)
273d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			printf(" %s=%llu", prop->enums[i].name,
274d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			       prop->enums[i].value);
275d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\n");
2766df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark	} else if (prop->flags & DRM_MODE_PROP_BITMASK) {
2776df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark		printf("\t\tvalues:");
2786df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark		for (i = 0; i < prop->count_enums; i++)
2796df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark			printf(" %s=0x%llx", prop->enums[i].name,
2806df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark			       (1LL << prop->enums[i].value));
2816df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark		printf("\n");
282d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	} else {
283d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		assert(prop->count_enums == 0);
284d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	}
285d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
286d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_BLOB) {
287d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\t\tblobs:\n");
288d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		for (i = 0; i < prop->count_blobs; i++)
289d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			dump_blob(prop->blob_ids[i]);
290d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\n");
291d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	} else {
292d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		assert(prop->count_blobs == 0);
293d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	}
294d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
295d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\t\tvalue:");
296d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_BLOB)
297d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		dump_blob(value);
298d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	else
299d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" %"PRIu64"\n", value);
300d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
301d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	drmModeFreeProperty(prop);
3029fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg}
3039fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg
304731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_connectors(void)
305731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
306731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeConnector *connector;
307731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i, j;
308731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
309731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("Connectors:\n");
3101e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n");
311731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_connectors; i++) {
312731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		connector = drmModeGetConnector(fd, resources->connectors[i]);
313731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
314731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector) {
315731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get connector %i: %s\n",
316731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->connectors[i], strerror(errno));
317731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
318731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
319731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3201e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t",
321731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->connector_id,
322731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->encoder_id,
323731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector_status_str(connector->connection),
324731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector_type_str(connector->connector_type),
325731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->mmWidth, connector->mmHeight,
326731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->count_modes);
327731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3281e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		for (j = 0; j < connector->count_encoders; j++)
3291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]);
3301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		printf("\n");
3311e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
332a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni		if (connector->count_modes) {
333a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni			printf("  modes:\n");
334d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			printf("\tname refresh (Hz) hdisp hss hse htot vdisp "
335a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni			       "vss vse vtot)\n");
336a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni			for (j = 0; j < connector->count_modes; j++)
337a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni				dump_mode(&connector->modes[j]);
338a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni
339a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni			printf("  props:\n");
340d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			for (j = 0; j < connector->count_props; j++)
341d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni				dump_prop(connector->props[j],
342d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni					  connector->prop_values[j]);
343a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni		}
3449a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki
3459a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki		drmModeFreeConnector(connector);
346731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
3470243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
348731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
349731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
350731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_crtcs(void)
351731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
352731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeCrtc *crtc;
35386dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni	drmModeObjectPropertiesPtr props;
354731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
35586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni	uint32_t j;
356731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3570243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("CRTCs:\n");
3580243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("id\tfb\tpos\tsize\n");
359731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_crtcs; i++) {
360731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		crtc = drmModeGetCrtc(fd, resources->crtcs[i]);
361731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
362731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!crtc) {
363731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get crtc %i: %s\n",
364731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->crtcs[i], strerror(errno));
365731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
366731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
3670243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		printf("%d\t%d\t(%d,%d)\t(%dx%d)\n",
3680243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->crtc_id,
3690243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->buffer_id,
3700243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->x, crtc->y,
3710243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->width, crtc->height);
3720243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		dump_mode(&crtc->mode);
3730243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
37486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		printf("  props:\n");
37586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		props = drmModeObjectGetProperties(fd, crtc->crtc_id,
37686dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni						   DRM_MODE_OBJECT_CRTC);
37786dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		if (props) {
37886dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni			for (j = 0; j < props->count_props; j++)
37986dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni				dump_prop(props->props[j],
38086dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni					  props->prop_values[j]);
38186dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni			drmModeFreeObjectProperties(props);
38286dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		} else {
38386dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni			printf("\tcould not get crtc properties: %s\n",
38486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni			       strerror(errno));
38586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		}
38686dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni
387731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeCrtc(crtc);
388731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
3890243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
390731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
391731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
392731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_framebuffers(void)
393731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
394731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeFB *fb;
395731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
396731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3970243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("Frame buffers:\n");
3980243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("id\tsize\tpitch\n");
399731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_fbs; i++) {
400731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fb = drmModeGetFB(fd, resources->fbs[i]);
401731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
402731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!fb) {
403731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get fb %i: %s\n",
404731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->fbs[i], strerror(errno));
405731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
406731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
407e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		printf("%u\t(%ux%u)\t%u\n",
4080243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       fb->fb_id,
409e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		       fb->width, fb->height,
410e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		       fb->pitch);
4110243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
412731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeFB(fb);
413731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
4140243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
415731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
416731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
417d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic void dump_planes(void)
418d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{
41925e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark	drmModeObjectPropertiesPtr props;
420d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlaneRes *plane_resources;
421d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlane *ovr;
4229b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	unsigned int i, j;
423d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
424d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	plane_resources = drmModeGetPlaneResources(fd);
425d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_resources) {
426d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
427d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
428d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return;
429d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
430d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
431d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	printf("Planes:\n");
4328e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä	printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\tpossible crtcs\n");
433d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < plane_resources->count_planes; i++) {
434d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
435d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr) {
436d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			fprintf(stderr, "drmModeGetPlane failed: %s\n",
437d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				strerror(errno));
438d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			continue;
439d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
440d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
4418e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä		printf("%d\t%d\t%d\t%d,%d\t\t%d,%d\t%-8d\t0x%08x\n",
442d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		       ovr->plane_id, ovr->crtc_id, ovr->fb_id,
443d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		       ovr->crtc_x, ovr->crtc_y, ovr->x, ovr->y,
4448e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä		       ovr->gamma_size, ovr->possible_crtcs);
445d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
446d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr->count_formats)
447d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			continue;
448d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
449d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		printf("  formats:");
450d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		for (j = 0; j < ovr->count_formats; j++)
451d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			printf(" %4.4s", (char *)&ovr->formats[j]);
452d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		printf("\n");
453d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
45425e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		printf("  props:\n");
45525e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		props = drmModeObjectGetProperties(fd, ovr->plane_id,
45625e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark						   DRM_MODE_OBJECT_PLANE);
45725e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		if (props) {
45825e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark			for (j = 0; j < props->count_props; j++)
45925e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark				dump_prop(props->props[j],
46025e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark					  props->prop_values[j]);
46125e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark			drmModeFreeObjectProperties(props);
46225e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		} else {
46325e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark			printf("\tcould not get plane properties: %s\n",
46425e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark			       strerror(errno));
46525e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		}
46625e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark
467d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		drmModeFreePlane(ovr);
468d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
469d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	printf("\n");
470d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
4710ef7644fe5161d3b50f9550ebbf8cbbabd51706fPaulo Zanoni	drmModeFreePlaneResources(plane_resources);
472d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	return;
473d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}
474d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
475a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* -----------------------------------------------------------------------------
476a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Connectors and planes
477a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */
478a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
479731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/*
480731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Mode setting with the kernel interfaces is a bit of a chore.
481731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * First you have to find the connector in question and make sure the
482731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * requested mode is available.
483731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Then you need to find the encoder attached to that connector so you
484731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * can bind it with a free crtc.
485731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */
486669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstruct connector {
487e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	uint32_t id;
488669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	char mode_str[64];
489cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	char format_str[5];
490cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	unsigned int fourcc;
4919fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	drmModeModeInfo *mode;
492669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	drmModeEncoder *encoder;
4938b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	int crtc;
494d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	int pipe;
4951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	unsigned int fb_id[2], current_fb_id;
4961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	struct timeval start;
4971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
4981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	int swap_count;
499d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark};
500d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
501d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstruct plane {
502d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t con_id;  /* the id of connector to bind to */
503d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t w, h;
504d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	unsigned int fb_id;
505b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	char format_str[5]; /* need to leave room for terminating \0 */
5060375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	unsigned int fourcc;
507d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark};
508669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
509669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstatic void
510669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergconnector_find_mode(struct connector *c)
511731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
512731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeConnector *connector;
513e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	int i, j;
514731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
515731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* First, find the connector & mode */
516669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	c->mode = NULL;
517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_connectors; i++) {
518731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		connector = drmModeGetConnector(fd, resources->connectors[i]);
519731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
520731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector) {
521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get connector %i: %s\n",
522731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->connectors[i], strerror(errno));
523731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
524731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
526731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
527731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector->count_modes) {
528731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
529731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
530731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
531731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
532669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (connector->connector_id != c->id) {
533731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
534731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
535731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
536731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
537731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		for (j = 0; j < connector->count_modes; j++) {
538669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			c->mode = &connector->modes[j];
539669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			if (!strcmp(c->mode->name, c->mode_str))
540731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				break;
541731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
542731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
543731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		/* Found it, break out */
544669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c->mode)
545731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
546731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
547731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeConnector(connector);
548731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
549731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
550669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	if (!c->mode) {
551669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
552731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return;
553731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
554731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
555731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* Now get the encoder */
556731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_encoders; i++) {
557669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);
558731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
559669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (!c->encoder) {
560731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get encoder %i: %s\n",
561731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->encoders[i], strerror(errno));
562669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			drmModeFreeEncoder(c->encoder);
563731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
564731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
565731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
566669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c->encoder->encoder_id  == connector->encoder_id)
567731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
568731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
569669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		drmModeFreeEncoder(c->encoder);
570669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	}
5718b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
5728b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	if (c->crtc == -1)
5738b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		c->crtc = c->encoder->crtc_id;
574d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
575d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* and figure out which crtc index it is: */
576d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < resources->count_crtcs; i++) {
577d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (c->crtc == resources->crtcs[i]) {
578d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			c->pipe = i;
579d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			break;
580d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
581d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
582d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
583669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg}
584669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
5853fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart/* -------------------------------------------------------------------------- */
5863fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
5873fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartvoid
5883fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartpage_flip_handler(int fd, unsigned int frame,
5893fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		  unsigned int sec, unsigned int usec, void *data)
5903fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart{
5913fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	struct connector *c;
5923fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	unsigned int new_fb_id;
5933fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	struct timeval end;
5943fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	double t;
5953fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
5963fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	c = data;
5973fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (c->current_fb_id == c->fb_id[0])
5983fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		new_fb_id = c->fb_id[1];
5993fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	else
6003fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		new_fb_id = c->fb_id[0];
6013fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
6023fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	drmModePageFlip(fd, c->crtc, new_fb_id,
6033fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart			DRM_MODE_PAGE_FLIP_EVENT, c);
6043fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	c->current_fb_id = new_fb_id;
6053fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	c->swap_count++;
6063fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (c->swap_count == 60) {
6073fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		gettimeofday(&end, NULL);
6083fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		t = end.tv_sec + end.tv_usec * 1e-6 -
6093fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart			(c->start.tv_sec + c->start.tv_usec * 1e-6);
6103fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t);
6113fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		c->swap_count = 0;
6123fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		c->start = end;
6133fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	}
6143fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart}
6153fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
616d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic int
617d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_plane(struct kms_driver *kms, struct connector *c, struct plane *p)
618d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{
619d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlaneRes *plane_resources;
620d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlane *ovr;
621d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
622d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t plane_id = 0;
623d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	struct kms_bo *plane_bo;
6240375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	uint32_t plane_flags = 0;
6259b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	int ret, crtc_x, crtc_y, crtc_w, crtc_h;
6269b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	unsigned int i;
627d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
628d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* find an unused plane which can be connected to our crtc */
629d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	plane_resources = drmModeGetPlaneResources(fd);
630d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_resources) {
631d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
632d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
633d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
634d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
635d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
636d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < plane_resources->count_planes && !plane_id; i++) {
637d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
638d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr) {
639d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			fprintf(stderr, "drmModeGetPlane failed: %s\n",
640d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				strerror(errno));
641d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			return -1;
642d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
643d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
644d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if ((ovr->possible_crtcs & (1 << c->pipe)) && !ovr->crtc_id)
645d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			plane_id = ovr->plane_id;
646d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
647d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		drmModeFreePlane(ovr);
648d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
649d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
650b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	fprintf(stderr, "testing %dx%d@%s overlay plane\n",
651b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			p->w, p->h, p->format_str);
652b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
653d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_id) {
654d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to find plane!\n");
655d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
656d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
657d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
6580375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	plane_bo = create_test_buffer(kms, p->fourcc, p->w, p->h, handles,
659a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				      pitches, offsets, PATTERN_TILES);
6603fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (plane_bo == NULL)
6613fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		return -1;
662d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
663d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* just use single plane format for now.. */
6640375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	if (drmModeAddFB2(fd, p->w, p->h, p->fourcc,
665d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			handles, pitches, offsets, &p->fb_id, plane_flags)) {
666d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
667d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
668d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
669d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
670d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* ok, boring.. but for now put in middle of screen: */
671d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_x = c->mode->hdisplay / 3;
672d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_y = c->mode->vdisplay / 3;
673d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_w = crtc_x;
674d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_h = crtc_y;
675d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
676d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* note src coords (last 4 args) are in Q16 format */
677d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (drmModeSetPlane(fd, plane_id, c->crtc, p->fb_id,
678d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			    plane_flags, crtc_x, crtc_y, crtc_w, crtc_h,
679d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			    0, 0, p->w << 16, p->h << 16)) {
680d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to enable plane: %s\n",
681d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
682d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
683d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
684d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
685d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	return 0;
686d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}
687d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
6887a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic void
689d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_mode(struct connector *c, int count, struct plane *p, int plane_count,
690d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		int page_flip)
6917a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{
6928fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_driver *kms;
6938fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_bo *bo, *other_bo;
6941e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	unsigned int fb_id, other_fb_id;
6953fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	int i, j, ret, width, height, x;
6963fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
6971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	drmEventContext evctx;
6987a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
6997a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	width = 0;
7007a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	height = 0;
7017a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	for (i = 0; i < count; i++) {
7027a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		connector_find_mode(&c[i]);
7037a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		if (c[i].mode == NULL)
7047a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			continue;
7057a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		width += c[i].mode->hdisplay;
7067a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		if (height < c[i].mode->vdisplay)
7077a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			height = c[i].mode->vdisplay;
7087a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	}
7097a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
7108fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	ret = kms_create(fd, &kms);
7118fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (ret) {
7128fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		fprintf(stderr, "failed to create kms driver: %s\n",
7138fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke			strerror(-ret));
7147a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return;
7157a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	}
7167a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
717cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	bo = create_test_buffer(kms, c->fourcc, width, height, handles,
718a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				pitches, offsets, PATTERN_SMPTE);
7193fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (bo == NULL)
7207a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return;
721731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
722cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	ret = drmModeAddFB2(fd, width, height, c->fourcc,
723cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart			    handles, pitches, offsets, &fb_id, 0);
724731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (ret) {
725680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz		fprintf(stderr, "failed to add fb (%ux%u): %s\n",
726680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz			width, height, strerror(errno));
727731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return;
728731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
729731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
730669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	x = 0;
731669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	for (i = 0; i < count; i++) {
732669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c[i].mode == NULL)
733669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			continue;
7348b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
735cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart		printf("setting mode %s@%s on connector %d, crtc %d\n",
736cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart		       c[i].mode_str, c[i].format_str, c[i].id, c[i].crtc);
7378b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
7388b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		ret = drmModeSetCrtc(fd, c[i].crtc, fb_id, x, 0,
739669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				     &c[i].id, 1, c[i].mode);
740d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz
741d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz		/* XXX: Actually check if this is needed */
742d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz		drmModeDirtyFB(fd, fb_id, NULL, 0);
743d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz
744669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		x += c[i].mode->hdisplay;
745669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
746669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (ret) {
747669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
748669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			return;
749669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		}
750d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
751d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		/* if we have a plane/overlay to show, set that up now: */
752d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		for (j = 0; j < plane_count; j++)
753d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			if (p[j].con_id == c[i].id)
754d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				if (set_plane(kms, &c[i], &p[j]))
755d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					return;
756731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
7571e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
7581e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (!page_flip)
7591e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
7608fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
761cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	other_bo = create_test_buffer(kms, c->fourcc, width, height, handles,
762a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				      pitches, offsets, PATTERN_PLAIN);
7633fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (other_bo == NULL)
7641e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
7651e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
766cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	ret = drmModeAddFB2(fd, width, height, c->fourcc, handles, pitches, offsets,
767cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart			    &other_fb_id, 0);
7681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (ret) {
7691e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
7701e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
7711e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
7721e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
7731e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	for (i = 0; i < count; i++) {
7741e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (c[i].mode == NULL)
7751e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			continue;
7761e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
7773c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		ret = drmModePageFlip(fd, c[i].crtc, other_fb_id,
7783c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz				      DRM_MODE_PAGE_FLIP_EVENT, &c[i]);
7793c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		if (ret) {
7803c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz			fprintf(stderr, "failed to page flip: %s\n", strerror(errno));
7813c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz			return;
7823c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		}
7831e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		gettimeofday(&c[i].start, NULL);
7841e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		c[i].swap_count = 0;
785e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		c[i].fb_id[0] = fb_id;
786e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		c[i].fb_id[1] = other_fb_id;
787a697fb6acad7992c3d23bb6a663663694782eb7bBenjamin Franzke		c[i].current_fb_id = other_fb_id;
7881e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
7891e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
7901e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	memset(&evctx, 0, sizeof evctx);
7911e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	evctx.version = DRM_EVENT_CONTEXT_VERSION;
7921e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	evctx.vblank_handler = NULL;
7936f1eba0548cd6a96e91a4e8be7b91ba6a936eb98Jesse Barnes	evctx.page_flip_handler = page_flip_handler;
7941e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
7951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	while (1) {
796e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#if 0
7971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		struct pollfd pfd[2];
7981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
7991e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[0].fd = 0;
8001e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[0].events = POLLIN;
8011e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[1].fd = fd;
8021e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[1].events = POLLIN;
8031e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8041e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (poll(pfd, 2, -1) < 0) {
8051e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			fprintf(stderr, "poll error\n");
8061e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
8071e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		}
8081e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8091e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (pfd[0].revents)
8101e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
811e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#else
812e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
813e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		fd_set fds;
814e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		int ret;
815e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes
816e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_ZERO(&fds);
817e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_SET(0, &fds);
818e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_SET(fd, &fds);
819e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		ret = select(fd + 1, &fds, NULL, NULL, &timeout);
820e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes
821e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		if (ret <= 0) {
822e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			fprintf(stderr, "select timed out or error (ret %d)\n",
823e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes				ret);
824e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			continue;
825e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		} else if (FD_ISSET(0, &fds)) {
826e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			break;
827e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		}
828e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#endif
8291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		drmHandleEvent(fd, &evctx);
8311e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
8328fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
8338fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_destroy(&bo);
8348fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_destroy(&other_bo);
8358fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_destroy(&kms);
836731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
837731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
838731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern char *optarg;
839731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern int optind, opterr, optopt;
840d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic char optstr[] = "ecpmfs:P:v";
841731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
842cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart#define min(a, b)	((a) < (b) ? (a) : (b))
843cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart
8440375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchartstatic int parse_connector(struct connector *c, const char *arg)
8450375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart{
846cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	unsigned int len;
847cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	const char *p;
848cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	char *endp;
849cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart
8500375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	c->crtc = -1;
851cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	strcpy(c->format_str, "XR24");
852cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart
853cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	c->id = strtoul(arg, &endp, 10);
854cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	if (*endp == '@') {
855cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart		arg = endp + 1;
856cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart		c->crtc = strtoul(arg, &endp, 10);
857cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	}
858cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	if (*endp != ':')
859cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart		return -1;
8600375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart
861cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	arg = endp + 1;
8620375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart
863cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	p = strchrnul(arg, '@');
864cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	len = min(sizeof c->mode_str - 1, p - arg);
865cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	strncpy(c->mode_str, arg, len);
866cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	c->mode_str[len] = '\0';
8670375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart
868cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	if (*p == '@') {
869cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart		strncpy(c->format_str, p + 1, 4);
870cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart		c->format_str[4] = '\0';
871ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark	}
872cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart
873ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark	c->fourcc = format_fourcc(c->format_str);
874ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark	if (c->fourcc == 0)  {
875ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark		fprintf(stderr, "unknown format %s\n", c->format_str);
876ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark		return -1;
877cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	}
878cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart
879cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	return 0;
8800375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart}
8810375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart
8820375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchartstatic int parse_plane(struct plane *p, const char *arg)
8830375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart{
8840375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	strcpy(p->format_str, "XR24");
8850375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart
8860375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	if (sscanf(arg, "%d:%dx%d@%4s", &p->con_id, &p->w, &p->h, &p->format_str) != 4 &&
8870375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	    sscanf(arg, "%d:%dx%d", &p->con_id, &p->w, &p->h) != 3)
8880375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart		return -1;
8890375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart
8900375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	p->fourcc = format_fourcc(p->format_str);
8910375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	if (p->fourcc == 0) {
8920375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart		fprintf(stderr, "unknown format %s\n", p->format_str);
8930375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart		return -1;
8940375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	}
8950375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart
8960375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart	return 0;
8970375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart}
8980375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart
899731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid usage(char *name)
900731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
901731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "usage: %s [-ecpmf]\n", name);
902731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-e\tlist encoders\n");
903731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-c\tlist connectors\n");
904d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n");
905731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-m\tlist modes\n");
906731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-f\tlist framebuffers\n");
9071e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
908cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	fprintf(stderr, "\t-s <connector_id>[@<crtc_id>]:<mode>[@<format>]\tset a mode\n");
909cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart	fprintf(stderr, "\t-P <connector_id>:<w>x<h>[@<format>]\tset a plane\n");
910731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\n\tDefault is to dump all info.\n");
911731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	exit(0);
912731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
913731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
914731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define dump_resource(res) if (res) dump_##res()
915731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
9169b44fbd393b8db571badae41881f490145404ae0Paulo Zanonistatic int page_flipping_supported(void)
91759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg{
9188fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	/*FIXME: generic ioctl needed? */
9198fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	return 1;
9208fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#if 0
92159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	int ret, value;
92259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	struct drm_i915_getparam gp;
92359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
92459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	gp.param = I915_PARAM_HAS_PAGEFLIPPING;
92559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	gp.value = &value;
92659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
92759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
92859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	if (ret) {
92959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		fprintf(stderr, "drm_i915_getparam: %m\n");
93059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		return 0;
93159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	}
93259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
933e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	return *gp.value;
9348fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#endif
93559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg}
93659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
937731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv)
938731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
939731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int c;
940d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0;
9411e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	int test_vsync = 0;
942e07b650662ea0529d99741691c47856ef1034c9cInki Dae	char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" };
9439b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	unsigned int i;
9449b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	int count = 0, plane_count = 0;
945669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	struct connector con_args[2];
946b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	struct plane plane_args[2] = {0};
947669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
948731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	opterr = 0;
949731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	while ((c = getopt(argc, argv, optstr)) != -1) {
950731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		switch (c) {
951731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'e':
952731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			encoders = 1;
953731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
954731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'c':
955731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			connectors = 1;
956731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
957731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'p':
958731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			crtcs = 1;
959d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			planes = 1;
960731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
961731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'm':
962731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			modes = 1;
963731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
964731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'f':
965731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			framebuffers = 1;
966731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
9671e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		case 'v':
9681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			test_vsync = 1;
9691e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
970731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 's':
9710375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart			if (parse_connector(&con_args[count], optarg) < 0)
972669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				usage(argv[0]);
973669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			count++;
974731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
975d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		case 'P':
9760375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart			if (parse_plane(&plane_args[plane_count], optarg) < 0)
977d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				usage(argv[0]);
978d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			plane_count++;
979d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			break;
980731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		default:
981731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			usage(argv[0]);
982731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
983731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
984731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
985731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
986731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (argc == 1)
987d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		encoders = connectors = crtcs = planes = modes = framebuffers = 1;
988731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
989731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < ARRAY_SIZE(modules); i++) {
990731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("trying to load module %s...", modules[i]);
991731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fd = drmOpen(modules[i], NULL);
992731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (fd < 0) {
993731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			printf("failed.\n");
994731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		} else {
995731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			printf("success.\n");
996731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
997731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
998731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
999731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
10009b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	if (test_vsync && !page_flipping_supported()) {
100159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		fprintf(stderr, "page flipping not supported by drm.\n");
100259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		return -1;
100359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	}
100459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
1005731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (i == ARRAY_SIZE(modules)) {
1006731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "failed to load any modules, aborting.\n");
1007731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return -1;
1008731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1009731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1010731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	resources = drmModeGetResources(fd);
1011731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (!resources) {
1012731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "drmModeGetResources failed: %s\n",
1013731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			strerror(errno));
1014731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmClose(fd);
1015731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return 1;
1016731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1017731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1018731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(encoders);
1019731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(connectors);
1020731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(crtcs);
1021d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	dump_resource(planes);
1022731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(framebuffers);
1023731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1024669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	if (count > 0) {
1025d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		set_mode(con_args, count, plane_args, plane_count, test_vsync);
10262c113a1b159f57ab94b54316ece49c677cfe04ceKristian Høgsberg		getchar();
1027731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1028731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1029731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeFreeResources(resources);
1030731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1031731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return 0;
1032731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
1033