modetest.c revision a94ee624292bff96ea1d38e8a0a3fbeefec42fb6
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
587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#ifdef HAVE_CAIRO
597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include <math.h>
607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include <cairo.h>
617a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#endif
627a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
63731cd5526e5c732d51307b26e784f454a724a699Jesse BarnesdrmModeRes *resources;
64731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint fd, modes;
65731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
66731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
67731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
68731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name {
69731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int type;
70731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	char *name;
71731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
72731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
73731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define type_name_fn(res) \
74731cd5526e5c732d51307b26e784f454a724a699Jesse Barneschar * res##_str(int type) {			\
759b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	unsigned int i;					\
76731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
77731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (res##_names[i].type == type)	\
78731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			return res##_names[i].name;	\
79731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}						\
80731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return "(invalid)";				\
81731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
82731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
83731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name encoder_type_names[] = {
84731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_NONE, "none" },
85731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_DAC, "DAC" },
86731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
87731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
88731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_TVDAC, "TVDAC" },
89731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
90731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
91731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(encoder_type)
92731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
93731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_status_names[] = {
94731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTED, "connected" },
95731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_DISCONNECTED, "disconnected" },
96731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_UNKNOWNCONNECTION, "unknown" },
97731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
98731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
99731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_status)
100731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
101731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_type_names[] = {
102731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Unknown, "unknown" },
103731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_VGA, "VGA" },
104731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
105731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
106731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
107731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Composite, "composite" },
108731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
109731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
110731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Component, "component" },
111731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
112731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DisplayPort, "displayport" },
113731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
114731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
115b8abe6139e5c6779ee87d983346f0f65bf67462eJesse Barnes	{ DRM_MODE_CONNECTOR_TV, "TV" },
116b8abe6139e5c6779ee87d983346f0f65bf67462eJesse Barnes	{ DRM_MODE_CONNECTOR_eDP, "embedded displayport" },
117731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
118731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
119731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_type)
120731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
121c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg#define bit_name_fn(res)					\
122c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergchar * res##_str(int type) {					\
123c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	int i;							\
124c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	const char *sep = "";					\
125c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	for (i = 0; i < ARRAY_SIZE(res##_names); i++) {		\
126c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg		if (type & (1 << i)) {				\
127c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg			printf("%s%s", sep, res##_names[i]);	\
128c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg			sep = ", ";				\
129c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg		}						\
130c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	}							\
131c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg}
132c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
133c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_type_names[] = {
134c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"builtin",
135c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"clock_c",
136c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"crtc_c",
137c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"preferred",
138c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"default",
139c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"userdef",
140c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"driver",
141c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg};
142c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
143c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergbit_name_fn(mode_type)
144c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
145c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_flag_names[] = {
146c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"phsync",
147c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"nhsync",
148c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"pvsync",
149c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"nvsync",
150c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"interlace",
151c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"dblscan",
152c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"csync",
153c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"pcsync",
154c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"ncsync",
155c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"hskew",
156c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"bcast",
157c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"pixmux",
158c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"dblclk",
159c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	"clkdiv2"
160c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg};
161c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
162c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergbit_name_fn(mode_flag)
163c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
164731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_encoders(void)
165731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
166731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeEncoder *encoder;
167731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
168731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
169731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("Encoders:\n");
170731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n");
171731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_encoders; i++) {
172731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		encoder = drmModeGetEncoder(fd, resources->encoders[i]);
173731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
174731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!encoder) {
175731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get encoder %i: %s\n",
176731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->encoders[i], strerror(errno));
177731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
178731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
179731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("%d\t%d\t%s\t0x%08x\t0x%08x\n",
180731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->encoder_id,
181731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->crtc_id,
182731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder_type_str(encoder->encoder_type),
183731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->possible_crtcs,
184731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->possible_clones);
185731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeEncoder(encoder);
186731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1870243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
1880243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg}
1890243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
1909fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergvoid dump_mode(drmModeModeInfo *mode)
1910243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg{
192c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	printf("  %s %d %d %d %d %d %d %d %d %d",
1930243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->name,
194694ef59532253727176ed0ce9077ae3ec41dd457Marcin Kościelnicki	       mode->vrefresh,
1950243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hdisplay,
1960243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hsync_start,
1970243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hsync_end,
1980243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->htotal,
1990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vdisplay,
2000243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vsync_start,
2010243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vsync_end,
2020243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vtotal);
203c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg
204c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	printf(" flags: ");
205c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	mode_flag_str(mode->flags);
206c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	printf("; type: ");
207c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	mode_type_str(mode->type);
208c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg	printf("\n");
209731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
210731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2119fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergstatic void
212d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonidump_blob(uint32_t blob_id)
213d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni{
214d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	uint32_t i;
215d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	unsigned char *blob_data;
216d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	drmModePropertyBlobPtr blob;
217d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
218d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	blob = drmModeGetPropertyBlob(fd, blob_id);
219d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (!blob)
220d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		return;
221d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
222d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	blob_data = blob->data;
223d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
224d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	for (i = 0; i < blob->length; i++) {
225d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		if (i % 16 == 0)
226d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			printf("\n\t\t\t");
227d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("%.2hhx", blob_data[i]);
228d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	}
229d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\n");
230d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
231d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	drmModeFreePropertyBlob(blob);
232d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni}
233d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
234d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonistatic void
235d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonidump_prop(uint32_t prop_id, uint64_t value)
2369fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg{
2379fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	int i;
238d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	drmModePropertyPtr prop;
239d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
240d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	prop = drmModeGetProperty(fd, prop_id);
241d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
242d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\t%d", prop_id);
243d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (!prop) {
244d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\n");
245d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		return;
246d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	}
247d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
248d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf(" %s:\n", prop->name);
249d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
250d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\t\tflags:");
251d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_PENDING)
252d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" pending");
253d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_RANGE)
254d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" range");
255d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_IMMUTABLE)
256d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" immutable");
257d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_ENUM)
258d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" enum");
2596df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark	if (prop->flags & DRM_MODE_PROP_BITMASK)
2606df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark		printf(" bitmask");
261d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_BLOB)
262d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" blob");
263d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\n");
2649fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg
265d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_RANGE) {
266d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\t\tvalues:");
267d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		for (i = 0; i < prop->count_values; i++)
268d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			printf(" %"PRIu64, prop->values[i]);
269d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\n");
2709fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	}
271d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
272d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_ENUM) {
273d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\t\tenums:");
274d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		for (i = 0; i < prop->count_enums; i++)
275d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			printf(" %s=%llu", prop->enums[i].name,
276d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			       prop->enums[i].value);
277d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\n");
2786df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark	} else if (prop->flags & DRM_MODE_PROP_BITMASK) {
2796df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark		printf("\t\tvalues:");
2806df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark		for (i = 0; i < prop->count_enums; i++)
2816df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark			printf(" %s=0x%llx", prop->enums[i].name,
2826df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark			       (1LL << prop->enums[i].value));
2836df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark		printf("\n");
284d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	} else {
285d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		assert(prop->count_enums == 0);
286d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	}
287d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
288d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_BLOB) {
289d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\t\tblobs:\n");
290d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		for (i = 0; i < prop->count_blobs; i++)
291d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			dump_blob(prop->blob_ids[i]);
292d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf("\n");
293d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	} else {
294d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		assert(prop->count_blobs == 0);
295d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	}
296d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
297d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	printf("\t\tvalue:");
298d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_BLOB)
299d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		dump_blob(value);
300d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	else
301d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni		printf(" %"PRIu64"\n", value);
302d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni
303d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni	drmModeFreeProperty(prop);
3049fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg}
3059fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg
306731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_connectors(void)
307731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
308731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeConnector *connector;
309731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i, j;
310731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
311731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("Connectors:\n");
3121e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n");
313731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_connectors; i++) {
314731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		connector = drmModeGetConnector(fd, resources->connectors[i]);
315731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
316731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector) {
317731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get connector %i: %s\n",
318731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->connectors[i], strerror(errno));
319731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
320731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
321731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3221e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t",
323731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->connector_id,
324731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->encoder_id,
325731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector_status_str(connector->connection),
326731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector_type_str(connector->connector_type),
327731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->mmWidth, connector->mmHeight,
328731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->count_modes);
329731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		for (j = 0; j < connector->count_encoders; j++)
3311e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]);
3321e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		printf("\n");
3331e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
334a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni		if (connector->count_modes) {
335a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni			printf("  modes:\n");
336d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			printf("\tname refresh (Hz) hdisp hss hse htot vdisp "
337a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni			       "vss vse vtot)\n");
338a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni			for (j = 0; j < connector->count_modes; j++)
339a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni				dump_mode(&connector->modes[j]);
340a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni
341a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni			printf("  props:\n");
342d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni			for (j = 0; j < connector->count_props; j++)
343d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni				dump_prop(connector->props[j],
344d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni					  connector->prop_values[j]);
345a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni		}
3469a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki
3479a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki		drmModeFreeConnector(connector);
348731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
3490243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
350731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
351731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
352731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_crtcs(void)
353731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
354731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeCrtc *crtc;
35586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni	drmModeObjectPropertiesPtr props;
356731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
35786dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni	uint32_t j;
358731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3590243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("CRTCs:\n");
3600243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("id\tfb\tpos\tsize\n");
361731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_crtcs; i++) {
362731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		crtc = drmModeGetCrtc(fd, resources->crtcs[i]);
363731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
364731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!crtc) {
365731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get crtc %i: %s\n",
366731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->crtcs[i], strerror(errno));
367731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
368731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
3690243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		printf("%d\t%d\t(%d,%d)\t(%dx%d)\n",
3700243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->crtc_id,
3710243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->buffer_id,
3720243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->x, crtc->y,
3730243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->width, crtc->height);
3740243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		dump_mode(&crtc->mode);
3750243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
37686dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		printf("  props:\n");
37786dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		props = drmModeObjectGetProperties(fd, crtc->crtc_id,
37886dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni						   DRM_MODE_OBJECT_CRTC);
37986dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		if (props) {
38086dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni			for (j = 0; j < props->count_props; j++)
38186dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni				dump_prop(props->props[j],
38286dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni					  props->prop_values[j]);
38386dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni			drmModeFreeObjectProperties(props);
38486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		} else {
38586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni			printf("\tcould not get crtc properties: %s\n",
38686dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni			       strerror(errno));
38786dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni		}
38886dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni
389731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeCrtc(crtc);
390731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
3910243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
392731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
393731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
394731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_framebuffers(void)
395731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
396731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeFB *fb;
397731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
398731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("Frame buffers:\n");
4000243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("id\tsize\tpitch\n");
401731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_fbs; i++) {
402731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fb = drmModeGetFB(fd, resources->fbs[i]);
403731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
404731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!fb) {
405731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get fb %i: %s\n",
406731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->fbs[i], strerror(errno));
407731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
408731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
409e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		printf("%u\t(%ux%u)\t%u\n",
4100243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       fb->fb_id,
411e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		       fb->width, fb->height,
412e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		       fb->pitch);
4130243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
414731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeFB(fb);
415731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
4160243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
417731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
418731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
419d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic void dump_planes(void)
420d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{
42125e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark	drmModeObjectPropertiesPtr props;
422d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlaneRes *plane_resources;
423d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlane *ovr;
4249b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	unsigned int i, j;
425d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
426d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	plane_resources = drmModeGetPlaneResources(fd);
427d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_resources) {
428d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
429d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
430d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return;
431d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
432d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
433d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	printf("Planes:\n");
434d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\n");
435d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < plane_resources->count_planes; i++) {
436d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
437d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr) {
438d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			fprintf(stderr, "drmModeGetPlane failed: %s\n",
439d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				strerror(errno));
440d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			continue;
441d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
442d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
443d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		printf("%d\t%d\t%d\t%d,%d\t\t%d,%d\t%d\n",
444d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		       ovr->plane_id, ovr->crtc_id, ovr->fb_id,
445d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		       ovr->crtc_x, ovr->crtc_y, ovr->x, ovr->y,
446d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		       ovr->gamma_size);
447d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
448d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr->count_formats)
449d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			continue;
450d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
451d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		printf("  formats:");
452d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		for (j = 0; j < ovr->count_formats; j++)
453d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			printf(" %4.4s", (char *)&ovr->formats[j]);
454d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		printf("\n");
455d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
45625e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		printf("  props:\n");
45725e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		props = drmModeObjectGetProperties(fd, ovr->plane_id,
45825e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark						   DRM_MODE_OBJECT_PLANE);
45925e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		if (props) {
46025e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark			for (j = 0; j < props->count_props; j++)
46125e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark				dump_prop(props->props[j],
46225e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark					  props->prop_values[j]);
46325e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark			drmModeFreeObjectProperties(props);
46425e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		} else {
46525e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark			printf("\tcould not get plane properties: %s\n",
46625e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark			       strerror(errno));
46725e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark		}
46825e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark
469d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		drmModeFreePlane(ovr);
470d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
471d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	printf("\n");
472d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
4730ef7644fe5161d3b50f9550ebbf8cbbabd51706fPaulo Zanoni	drmModeFreePlaneResources(plane_resources);
474d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	return;
475d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}
476d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
477a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* -----------------------------------------------------------------------------
478a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Connectors and planes
479a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */
480a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
481731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/*
482731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Mode setting with the kernel interfaces is a bit of a chore.
483731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * First you have to find the connector in question and make sure the
484731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * requested mode is available.
485731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Then you need to find the encoder attached to that connector so you
486731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * can bind it with a free crtc.
487731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */
488669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstruct connector {
489e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	uint32_t id;
490669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	char mode_str[64];
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 */
506d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark};
507669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
508669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstatic void
509669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergconnector_find_mode(struct connector *c)
510731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
511731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeConnector *connector;
512e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	int i, j;
513731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
514731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* First, find the connector & mode */
515669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	c->mode = NULL;
516731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_connectors; i++) {
517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		connector = drmModeGetConnector(fd, resources->connectors[i]);
518731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
519731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector) {
520731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get connector %i: %s\n",
521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->connectors[i], strerror(errno));
522731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
523731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
524731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
526731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector->count_modes) {
527731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
528731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
529731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
530731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
531669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (connector->connector_id != c->id) {
532731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
533731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
534731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
535731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
536731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		for (j = 0; j < connector->count_modes; j++) {
537669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			c->mode = &connector->modes[j];
538669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			if (!strcmp(c->mode->name, c->mode_str))
539731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				break;
540731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
541731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
542731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		/* Found it, break out */
543669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c->mode)
544731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
545731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
546731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeConnector(connector);
547731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
548731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
549669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	if (!c->mode) {
550669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
551731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return;
552731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
553731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
554731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* Now get the encoder */
555731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_encoders; i++) {
556669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);
557731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
558669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (!c->encoder) {
559731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get encoder %i: %s\n",
560731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->encoders[i], strerror(errno));
561669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			drmModeFreeEncoder(c->encoder);
562731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
563731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
564731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
565669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c->encoder->encoder_id  == connector->encoder_id)
566731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
567731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
568669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		drmModeFreeEncoder(c->encoder);
569669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	}
5708b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
5718b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	if (c->crtc == -1)
5728b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		c->crtc = c->encoder->crtc_id;
573d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
574d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* and figure out which crtc index it is: */
575d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < resources->count_crtcs; i++) {
576d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (c->crtc == resources->crtcs[i]) {
577d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			c->pipe = i;
578d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			break;
579d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
580d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
581d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
582669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg}
583669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
584a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* -----------------------------------------------------------------------------
585a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Formats
586a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */
587a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
588a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstruct color_component {
589a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int length;
590a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int offset;
591a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart};
592a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
593a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstruct rgb_info {
594a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	struct color_component red;
595a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	struct color_component green;
596a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	struct color_component blue;
597a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	struct color_component alpha;
598a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart};
599a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
600a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartenum yuv_order {
601a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	YUV_YCbCr = 1,
602a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	YUV_YCrCb = 2,
603a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	YUV_YC = 4,
604a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	YUV_CY = 8,
605a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart};
606a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
607a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstruct yuv_info {
608a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	enum yuv_order order;
609a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int xsub;
610a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int ysub;
611a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int chroma_stride;
612a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart};
613a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
614a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstruct format_info {
615a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int format;
616a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const char *name;
617a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct rgb_info rgb;
618a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct yuv_info yuv;
619a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart};
620a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
621a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define MAKE_RGB_INFO(rl, ro, bl, bo, gl, go, al, ao) \
622a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	.rgb = { { (rl), (ro) }, { (bl), (bo) }, { (gl), (go) }, { (al), (ao) } }
623a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
624a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define MAKE_YUV_INFO(order, xsub, ysub, chroma_stride) \
625a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	.yuv = { (order), (xsub), (ysub), (chroma_stride) }
626a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
627a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic const struct format_info format_info[] = {
628a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	{ DRM_FORMAT_YUYV, "YUYV", MAKE_YUV_INFO(YUV_YCbCr | YUV_YC, 2, 2, 2) },
629a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	{ DRM_FORMAT_NV12, "NV12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 2) },
630a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	{ DRM_FORMAT_NV21, "NV21", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 2) },
631a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	{ DRM_FORMAT_YVU420, "YV12", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 1) },
632a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	{ DRM_FORMAT_XRGB1555, "XR15", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 0, 0) },
633a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	{ DRM_FORMAT_XRGB8888, "XR24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },
634a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	{ DRM_FORMAT_ARGB1555, "AR15", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 1, 15) },
635a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart};
636a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
637a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartunsigned int format_fourcc(const char *name)
6387ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson{
639a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int i;
640a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (i = 0; i < ARRAY_SIZE(format_info); i++) {
641a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		if (!strcmp(format_info[i].name, name))
642a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			return format_info[i].format;
643a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
644a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	return 0;
645a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart}
646a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
647a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* -----------------------------------------------------------------------------
648a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Test patterns
649a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */
650a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
651a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartenum fill_pattern {
652a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	PATTERN_TILES = 0,
653a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	PATTERN_PLAIN = 1,
654a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	PATTERN_SMPTE = 2,
655a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart};
656a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
657a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstruct color_rgb24 {
658a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int value:24;
659a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart} __attribute__((__packed__));
660a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
661a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstruct color_yuv {
662a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned char y;
663a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned char u;
664a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned char v;
665a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart};
666a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
667a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define MAKE_YUV_601_Y(r, g, b) \
668a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	((( 66 * (r) + 129 * (g) +  25 * (b) + 128) >> 8) + 16)
669a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define MAKE_YUV_601_U(r, g, b) \
670a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	(((-38 * (r) -  74 * (g) + 112 * (b) + 128) >> 8) + 128)
671a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define MAKE_YUV_601_V(r, g, b) \
672a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	(((112 * (r) -  94 * (g) -  18 * (b) + 128) >> 8) + 128)
673a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
674a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define MAKE_YUV_601(r, g, b) \
675a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	{ .y = MAKE_YUV_601_Y(r, g, b), \
676a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	  .u = MAKE_YUV_601_U(r, g, b), \
677a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	  .v = MAKE_YUV_601_V(r, g, b) }
678a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
679a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define MAKE_RGBA(rgb, r, g, b, a) \
680a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	((((r) >> (8 - (rgb)->red.length)) << (rgb)->red.offset) | \
681a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	 (((g) >> (8 - (rgb)->green.length)) << (rgb)->green.offset) | \
682a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	 (((b) >> (8 - (rgb)->blue.length)) << (rgb)->blue.offset) | \
683a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	 (((a) >> (8 - (rgb)->alpha.length)) << (rgb)->alpha.offset))
684a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
685a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic void
686a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_smpte_yuv_planar(const struct yuv_info *yuv,
687a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned char *y_mem, unsigned char *u_mem,
688a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned char *v_mem, unsigned int width,
689a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned int height, unsigned int stride)
690a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart{
691a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct color_yuv colors_top[] = {
692a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(191, 192, 192),	/* grey */
693a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 192, 0),	/* yellow */
694a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 192, 192),	/* cyan */
695a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 192, 0),	/* green */
696a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 0, 192),	/* magenta */
697a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 0, 0),	/* red */
698a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 0, 192),	/* blue */
6998fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	};
700a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct color_yuv colors_middle[] = {
701a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 0, 192),	/* blue */
702a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
703a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 0, 192),	/* magenta */
704a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
705a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 192, 192),	/* cyan */
706a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
707a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 192, 192),	/* grey */
708a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
709a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct color_yuv colors_bottom[] = {
710a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 33, 76),	/* in-phase */
711a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(255, 255, 255),	/* super white */
712a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(50, 0, 106),	/* quadrature */
713a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
714a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(9, 9, 9),		/* 3.5% */
715a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* 7.5% */
716a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(29, 29, 29),	/* 11.5% */
717a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
718a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
719a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int cs = yuv->chroma_stride;
720a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int xsub = yuv->xsub;
721a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int ysub = yuv->ysub;
722a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int x;
723a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int y;
724a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
725a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	/* Luma */
726a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (y = 0; y < height * 6 / 9; ++y) {
727a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; ++x)
728a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[x] = colors_top[x * 7 / width].y;
729a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		y_mem += stride;
730a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
7318fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
732a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height * 7 / 9; ++y) {
733a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; ++x)
734a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[x] = colors_middle[x * 7 / width].y;
735a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		y_mem += stride;
736a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
7378fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
738a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height; ++y) {
739a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width * 5 / 7; ++x)
740a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
741a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width * 6 / 7; ++x)
742a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[x] = colors_bottom[(x - width * 5 / 7) * 3
743a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart						 / (width / 7) + 4].y;
744a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width; ++x)
745a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[x] = colors_bottom[7].y;
746a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		y_mem += stride;
7478fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	}
7487a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
749a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	/* Chroma */
750a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (y = 0; y < height / ysub * 6 / 9; ++y) {
751a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; x += xsub) {
752a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			u_mem[x*cs/xsub] = colors_top[x * 7 / width].u;
753a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			v_mem[x*cs/xsub] = colors_top[x * 7 / width].v;
754a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
755a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		u_mem += stride * cs / xsub;
756a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		v_mem += stride * cs / xsub;
7578fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	}
7587ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
759a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height / ysub * 7 / 9; ++y) {
760a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; x += xsub) {
761a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			u_mem[x*cs/xsub] = colors_middle[x * 7 / width].u;
762a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			v_mem[x*cs/xsub] = colors_middle[x * 7 / width].v;
763a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
764a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		u_mem += stride * cs / xsub;
765a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		v_mem += stride * cs / xsub;
766a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
767a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
768a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height / ysub; ++y) {
769a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width * 5 / 7; x += xsub) {
770a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			u_mem[x*cs/xsub] =
771a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				colors_bottom[x * 4 / (width * 5 / 7)].u;
772a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			v_mem[x*cs/xsub] =
773a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				colors_bottom[x * 4 / (width * 5 / 7)].v;
774a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
775a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width * 6 / 7; x += xsub) {
776a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			u_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
777a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart							 3 / (width / 7) + 4].u;
778a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			v_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
779a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart							 3 / (width / 7) + 4].v;
780a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
781a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width; x += xsub) {
782a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			u_mem[x*cs/xsub] = colors_bottom[7].u;
783a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			v_mem[x*cs/xsub] = colors_bottom[7].v;
784a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
785a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		u_mem += stride * cs / xsub;
786a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		v_mem += stride * cs / xsub;
787a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
788a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart}
789a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
790a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic void
791a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_smpte_yuv_packed(const struct yuv_info *yuv, unsigned char *mem,
792a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned int width, unsigned int height,
793a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned int stride)
794a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart{
795a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct color_yuv colors_top[] = {
796a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(191, 192, 192),	/* grey */
797a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 192, 0),	/* yellow */
798a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 192, 192),	/* cyan */
799a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 192, 0),	/* green */
800a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 0, 192),	/* magenta */
801a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 0, 0),	/* red */
802a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 0, 192),	/* blue */
803a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
804a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct color_yuv colors_middle[] = {
805a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 0, 192),	/* blue */
806a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
807a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 0, 192),	/* magenta */
808a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
809a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 192, 192),	/* cyan */
810a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
811a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(192, 192, 192),	/* grey */
812a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
813a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct color_yuv colors_bottom[] = {
814a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(0, 33, 76),	/* in-phase */
815a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(255, 255, 255),	/* super white */
816a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(50, 0, 106),	/* quadrature */
817a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
818a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(9, 9, 9),		/* 3.5% */
819a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* 7.5% */
820a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(29, 29, 29),	/* 11.5% */
821a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_YUV_601(19, 19, 19),	/* black */
822a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
823a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
824a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
825a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
826a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
827a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int x;
828a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int y;
829a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
830a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	/* Luma */
831a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (y = 0; y < height * 6 / 9; ++y) {
832a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; ++x)
833a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[2*x] = colors_top[x * 7 / width].y;
834a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		y_mem += stride * 2;
835a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
836a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
837a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height * 7 / 9; ++y) {
838a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; ++x)
839a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[2*x] = colors_middle[x * 7 / width].y;
840a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		y_mem += stride * 2;
841a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
842a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
843a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height; ++y) {
844a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width * 5 / 7; ++x)
845a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[2*x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
846a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width * 6 / 7; ++x)
847a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[2*x] = colors_bottom[(x - width * 5 / 7) * 3
848a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart						   / (width / 7) + 4].y;
849a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width; ++x)
850a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			y_mem[2*x] = colors_bottom[7].y;
851a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		y_mem += stride * 2;
852a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
853a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
854a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	/* Chroma */
855a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (y = 0; y < height * 6 / 9; ++y) {
856a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; x += 2) {
857a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+u] = colors_top[x * 7 / width].u;
858a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+v] = colors_top[x * 7 / width].v;
859a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
860a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		c_mem += stride * 2;
861a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
862a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
863a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height * 7 / 9; ++y) {
864a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; x += 2) {
865a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+u] = colors_middle[x * 7 / width].u;
866a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+v] = colors_middle[x * 7 / width].v;
867a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
868a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		c_mem += stride * 2;
869a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
870a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
871a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height; ++y) {
872a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width * 5 / 7; x += 2) {
873a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+u] = colors_bottom[x * 4 / (width * 5 / 7)].u;
874a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+v] = colors_bottom[x * 4 / (width * 5 / 7)].v;
875a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
876a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width * 6 / 7; x += 2) {
877a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+u] = colors_bottom[(x - width * 5 / 7) *
878a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart						     3 / (width / 7) + 4].u;
879a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+v] = colors_bottom[(x - width * 5 / 7) *
880a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart						     3 / (width / 7) + 4].v;
881a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
882a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width; x += 2) {
883a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+u] = colors_bottom[7].u;
884a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			c_mem[2*x+v] = colors_bottom[7].v;
885a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
886a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		c_mem += stride * 2;
887a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
888a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart}
889a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
890a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic void
891a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_smpte_rgb16(const struct rgb_info *rgb, unsigned char *mem,
892a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		 unsigned int width, unsigned int height, unsigned int stride)
893a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart{
894a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const uint16_t colors_top[] = {
895a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 192, 192, 255),	/* grey */
896a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 192, 0, 255),	/* yellow */
897a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 192, 192, 255),	/* cyan */
898a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 192, 0, 255),		/* green */
899a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 0, 192, 255),	/* magenta */
900a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 0, 0, 255),		/* red */
901a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 0, 192, 255),		/* blue */
902a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
903a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const uint16_t colors_middle[] = {
904a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 0, 192, 255),		/* blue */
905a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
906a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 0, 192, 255),	/* magenta */
907a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
908a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 192, 192, 255),	/* cyan */
909a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
910a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 192, 192, 255),	/* grey */
911a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
912a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const uint16_t colors_bottom[] = {
913a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 33, 76, 255),		/* in-phase */
914a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 255, 255, 255, 255),	/* super white */
915a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 50, 0, 106, 255),	/* quadrature */
916a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
917a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 9, 9, 9, 255),		/* 3.5% */
918a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* 7.5% */
919a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 29, 29, 29, 255),	/* 11.5% */
920a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
921a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
922a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int x;
923a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int y;
924a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
925a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (y = 0; y < height * 6 / 9; ++y) {
926a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; ++x)
927a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint16_t *)mem)[x] = colors_top[x * 7 / width];
928a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		mem += stride;
929a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
930a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
931a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height * 7 / 9; ++y) {
932a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; ++x)
933a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint16_t *)mem)[x] = colors_middle[x * 7 / width];
934a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		mem += stride;
935a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
936a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
937a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height; ++y) {
938a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width * 5 / 7; ++x)
939a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint16_t *)mem)[x] =
940a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				colors_bottom[x * 4 / (width * 5 / 7)];
941a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width * 6 / 7; ++x)
942a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint16_t *)mem)[x] =
943a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				colors_bottom[(x - width * 5 / 7) * 3
944a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					      / (width / 7) + 4];
945a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width; ++x)
946a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint16_t *)mem)[x] = colors_bottom[7];
947a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		mem += stride;
948a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
9497ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson}
9507ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
9517ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilsonstatic void
952a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_smpte_rgb32(const struct rgb_info *rgb, unsigned char *mem,
953a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		 unsigned int width, unsigned int height, unsigned int stride)
954a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart{
955a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const uint32_t colors_top[] = {
956a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 192, 192, 255),	/* grey */
957a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 192, 0, 255),	/* yellow */
958a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 192, 192, 255),	/* cyan */
959a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 192, 0, 255),		/* green */
960a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 0, 192, 255),	/* magenta */
961a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 0, 0, 255),		/* red */
962a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 0, 192, 255),		/* blue */
963a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
964a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const uint32_t colors_middle[] = {
965a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 0, 192, 255),		/* blue */
966a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
967a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 0, 192, 255),	/* magenta */
968a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
969a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 192, 192, 255),	/* cyan */
970a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
971a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 192, 192, 192, 255),	/* grey */
972a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
973a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const uint32_t colors_bottom[] = {
974a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 0, 33, 76, 255),		/* in-phase */
975a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 255, 255, 255, 255),	/* super white */
976a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 50, 0, 106, 255),	/* quadrature */
977a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
978a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 9, 9, 9, 255),		/* 3.5% */
979a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* 7.5% */
980a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 29, 29, 29, 255),	/* 11.5% */
981a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
982a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
983a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int x;
984a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int y;
985a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
986a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (y = 0; y < height * 6 / 9; ++y) {
987a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; ++x)
988a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint32_t *)mem)[x] = colors_top[x * 7 / width];
989a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		mem += stride;
990a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
991a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
992a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height * 7 / 9; ++y) {
993a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width; ++x)
994a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint32_t *)mem)[x] = colors_middle[x * 7 / width];
995a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		mem += stride;
996a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
997a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
998a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (; y < height; ++y) {
999a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (x = 0; x < width * 5 / 7; ++x)
1000a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint32_t *)mem)[x] =
1001a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				colors_bottom[x * 4 / (width * 5 / 7)];
1002a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width * 6 / 7; ++x)
1003a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint32_t *)mem)[x] =
1004a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				colors_bottom[(x - width * 5 / 7) * 3
1005a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					      / (width / 7) + 4];
1006a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		for (; x < width; ++x)
1007a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			((uint32_t *)mem)[x] = colors_bottom[7];
1008a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		mem += stride;
1009a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
1010a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart}
1011a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1012a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic void
1013a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_smpte(const struct format_info *info, void *planes[3], unsigned int width,
1014a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	   unsigned int height, unsigned int stride)
1015a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart{
1016a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned char *u, *v;
1017a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1018a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	switch (info->format) {
1019a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_YUYV:
1020a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
1021a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					     height, stride);
1022a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1023a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_NV12:
1024a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_NV21:
1025a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
1026a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
1027a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
1028a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					     width, height, stride);
1029a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_YVU420:
1030a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
1031a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					     planes[2], width, height, stride);
1032a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1033a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_ARGB1555:
1034a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_XRGB1555:
1035a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_smpte_rgb16(&info->rgb, planes[0],
1036a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					width, height, stride);
1037a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_XRGB8888:
1038a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_smpte_rgb32(&info->rgb, planes[0],
1039a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					width, height, stride);
1040a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
1041a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart}
1042a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1043a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* swap these for big endian.. */
1044a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define RED   2
1045a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define GREEN 1
1046a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart#define BLUE  0
1047a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1048a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic void
10498fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzkemake_pwetty(void *data, int width, int height, int stride)
1050669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg{
10517ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson#ifdef HAVE_CAIRO
10527a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_surface_t *surface;
10537a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_t *cr;
10547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	int x, y;
1055669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
10568fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	surface = cairo_image_surface_create_for_data(data,
10577ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson						      CAIRO_FORMAT_ARGB32,
10587ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson						      width, height,
10597ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson						      stride);
10607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cr = cairo_create(surface);
10617ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson	cairo_surface_destroy(surface);
10627ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
10637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
10647a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	for (x = 0; x < width; x += 250)
10657a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		for (y = 0; y < height; y += 250) {
10667ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson			char buf[64];
10677ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
10687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x, y - 20);
10697a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_line_to(cr, x, y + 20);
10707a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x - 20, y);
10717a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_line_to(cr, x + 20, y);
10727a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_new_sub_path(cr);
10737a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_arc(cr, x, y, 10, 0, M_PI * 2);
10747a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_line_width(cr, 4);
10757a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 0, 0, 0);
10767a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke_preserve(cr);
10777a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 1, 1, 1);
10787a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_line_width(cr, 2);
10797a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke(cr);
10807ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
10817a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			snprintf(buf, sizeof buf, "%d, %d", x, y);
10827a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x + 20, y + 20);
10837a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_text_path(cr, buf);
10847a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 0, 0, 0);
10857a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke_preserve(cr);
10867a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 1, 1, 1);
10877a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_fill(cr);
10887a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		}
10897a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
10907a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_destroy(cr);
10917ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson#endif
10927a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg}
10937a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
1094b83ad866220911e5be1704e6df085705e5ba8eaeRob Clarkstatic void
1095a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_tiles_yuv_planar(const struct yuv_info *yuv,
1096a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned char *y_mem, unsigned char *u_mem,
1097a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned char *v_mem, unsigned int width,
1098a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned int height, unsigned int stride)
1099b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark{
1100a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int cs = yuv->chroma_stride;
1101a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int i, j;
1102b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
1103b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	for (j = 0; j < height; j+=2) {
1104a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		unsigned char *y1p = y_mem + j * stride;
1105b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		unsigned char *y2p = y1p + stride;
1106a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		unsigned char *up = u_mem + (j/2) * stride * cs / 2;
1107a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		unsigned char *vp = v_mem + (j/2) * stride * cs / 2;
1108b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
1109b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		for (i = 0; i < width; i+=2) {
1110a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			div_t d = div(i+j, width);
1111b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
1112b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			unsigned char *rgbp = (unsigned char *)&rgb;
1113b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			unsigned char y = (0.299 * rgbp[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]);
1114b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
1115b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(y2p++) = *(y1p++) = y;
1116b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(y2p++) = *(y1p++) = y;
1117b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
1118b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*up = (rgbp[BLUE] - y) * 0.565 + 128;
1119b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*vp = (rgbp[RED] - y) * 0.713 + 128;
1120b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			up += cs;
1121b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			vp += cs;
1122b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		}
1123b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	}
1124b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark}
1125b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
1126b83ad866220911e5be1704e6df085705e5ba8eaeRob Clarkstatic void
1127a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_tiles_yuv_packed(const struct yuv_info *yuv, unsigned char *mem,
1128a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned int width, unsigned int height,
1129a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		      unsigned int stride)
1130b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark{
1131a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int i, j;
1132a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1133b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	for (j = 0; j < height; j++) {
1134a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		uint8_t *ptr = (uint8_t*)((char*)mem + j * stride);
1135b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		for (i = 0; i < width; i++) {
1136a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			div_t d = div(i+j, width);
1137b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
1138b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			unsigned char *rgbp = (unsigned char *)&rgb;
1139b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			unsigned char y = (0.299 * rgbp[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]);
1140b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
1141b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(ptr++) = y;
1142b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(ptr++) = (rgbp[BLUE] - y) * 0.565 + 128;
1143b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(ptr++) = y;
1144b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(ptr++) = (rgbp[RED] - y) * 0.713 + 128;
1145b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		}
1146b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	}
1147b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark}
1148b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
11492f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clarkstatic void
1150a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_tiles_rgb16(const struct rgb_info *rgb, unsigned char *mem,
1151a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		 unsigned int width, unsigned int height, unsigned int stride)
11522f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark{
1153a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int i, j;
1154a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
11552f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark	for (j = 0; j < height; j++) {
1156a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		uint16_t *ptr = (uint16_t*)((char*)mem + j * stride);
11572f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark		for (i = 0; i < width; i++) {
1158a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			div_t d = div(i+j, width);
11592f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark			uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
11602f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark			unsigned char *rgbp = (unsigned char *)&rgb;
11612f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark
11622f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark			*(ptr++) = 0x8000 |
11632f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark					(rgbp[RED] >> 3) << 10 |
11642f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark					(rgbp[GREEN] >> 3) << 5 |
11652f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark					(rgbp[BLUE] >> 3);
11662f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark		}
11672f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark	}
11682f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark}
11692f1e2101b4dc0a6dc1c1d1c59c5cc5fbc54b90cfRob Clark
11703fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartstatic void
1171a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_tiles_rgb32(const struct rgb_info *rgb, unsigned char *mem,
1172a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		 unsigned int width, unsigned int height, unsigned int stride)
11733fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart{
1174a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int i, j;
1175a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
11763fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	for (j = 0; j < height; j++) {
1177a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		uint32_t *ptr = (uint32_t*)((char*)mem + j * stride);
11783fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		for (i = 0; i < width; i++) {
11793fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart			div_t d = div(i, width);
11803fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart			ptr[i] =
11813fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart				0x00130502 * (d.quot >> 6) +
11823fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart				0x000a1120 * (d.rem >> 6);
11833fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		}
11843fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	}
11853fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1186a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	make_pwetty(mem, width, height, stride);
1187a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart}
1188a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1189a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic void
1190a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_tiles(const struct format_info *info, void *planes[3], unsigned int width,
1191a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	   unsigned int height, unsigned int stride)
1192a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart{
1193a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned char *u, *v;
1194a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1195a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	switch (info->format) {
1196a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_YUYV:
1197a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_tiles_yuv_packed(&info->yuv, planes[0],
1198a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					     width, height, stride);
1199a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1200a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_NV12:
1201a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_NV21:
1202a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
1203a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
1204a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_tiles_yuv_planar(&info->yuv, planes[0], u, v,
1205a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					     width, height, stride);
1206a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_YVU420:
1207a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_tiles_yuv_planar(&info->yuv, planes[0], planes[1],
1208a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					     planes[2], width, height, stride);
1209a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1210a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_ARGB1555:
1211a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_XRGB1555:
1212a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_tiles_rgb16(&info->rgb, planes[0],
1213a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					width, height, stride);
1214a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_XRGB8888:
1215a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_tiles_rgb32(&info->rgb, planes[0],
1216a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart					width, height, stride);
1217a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
1218a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart}
1219a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1220a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic void
1221a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_plain(const struct format_info *info, void *planes[3], unsigned int width,
1222a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	   unsigned int height, unsigned int stride)
1223a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart{
1224a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	memset(planes[0], 0x77, stride * height);
12253fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart}
12263fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1227a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/*
1228a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * fill_pattern - Fill a buffer with a test pattern
1229a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * @format: Pixel format
1230a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * @pattern: Test pattern
1231a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * @buffer: Buffer memory
1232a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * @width: Width in pixels
1233a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * @height: Height in pixels
1234a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * @stride: Line stride (pitch) in bytes
1235a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart *
1236a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Fill the buffer with the test pattern specified by the pattern parameter.
1237a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Supported formats vary depending on the selected pattern.
1238a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */
12393fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartstatic void
1240a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartfill_pattern(unsigned int format, enum fill_pattern pattern,
1241a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	     void *planes[3],
1242a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	     unsigned int width, unsigned int height, unsigned int stride)
1243a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart{
1244a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	const struct format_info *info = NULL;
1245a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned int i;
1246a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1247a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	for (i = 0; i < ARRAY_SIZE(format_info); ++i) {
1248a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		if (format_info[i].format == format) {
1249a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			info = &format_info[i];
1250a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			break;
1251a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		}
1252a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
1253a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1254a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	if (info == NULL)
1255a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return;
1256a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1257a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	switch (pattern) {
1258a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case PATTERN_TILES:
1259a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_tiles(info, planes, width, height, stride);
1260a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1261a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case PATTERN_SMPTE:
1262a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_smpte(info, planes, width, height, stride);
1263a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1264a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case PATTERN_PLAIN:
1265a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return fill_plain(info, planes, width, height, stride);
1266a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1267a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	default:
1268a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		printf("Error: unsupported test pattern %u.\n", pattern);
1269a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		break;
1270a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
1271a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart}
1272a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1273a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* -----------------------------------------------------------------------------
1274a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Buffers management
1275a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */
1276a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1277a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartstatic struct kms_bo *
1278a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchartallocate_buffer(struct kms_driver *kms,
1279a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		int width, int height, int *stride)
12803fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart{
1281a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	struct kms_bo *bo;
1282a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	unsigned bo_attribs[] = {
1283a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		KMS_WIDTH,   0,
1284a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		KMS_HEIGHT,  0,
1285a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		KMS_BO_TYPE, KMS_BO_TYPE_SCANOUT_X8R8G8B8,
1286a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		KMS_TERMINATE_PROP_LIST
1287a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	};
1288a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	int ret;
1289a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1290a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	bo_attribs[1] = width;
1291a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	bo_attribs[3] = height;
1292a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1293a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	ret = kms_bo_create(kms, bo_attribs, &bo);
1294a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	if (ret) {
1295a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		fprintf(stderr, "failed to alloc buffer: %s\n",
1296a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			strerror(-ret));
1297a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return NULL;
1298a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
1299a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1300a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	ret = kms_bo_get_prop(bo, KMS_PITCH, stride);
1301a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	if (ret) {
1302a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		fprintf(stderr, "failed to retreive buffer stride: %s\n",
1303a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart			strerror(-ret));
1304a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		kms_bo_destroy(&bo);
1305a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		return NULL;
1306a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	}
1307a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart
1308a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	return bo;
13093fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart}
13103fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
13113fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartstatic struct kms_bo *
13123fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartcreate_test_buffer(struct kms_driver *kms, unsigned int format,
13133fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		   int width, int height, int handles[4],
1314a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		   int pitches[4], int offsets[4], enum fill_pattern pattern)
13153fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart{
13163fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	struct kms_bo *bo;
13173fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	int ret, stride;
1318a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	void *planes[3];
13193fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	void *virtual;
13203fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
13213fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	bo = allocate_buffer(kms, width, height, &pitches[0]);
13223fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (!bo)
13233fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		return NULL;
13243fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
13253fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	ret = kms_bo_map(bo, &virtual);
13263fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (ret) {
13273fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		fprintf(stderr, "failed to map buffer: %s\n",
13283fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart			strerror(-ret));
13293fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_destroy(&bo);
13303fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		return NULL;
13313fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	}
13323fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
13333fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	/* just testing a limited # of formats to test single
13343fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	 * and multi-planar path.. would be nice to add more..
13353fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	 */
13363fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	switch (format) {
13373fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	case DRM_FORMAT_YUYV:
13383fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		pitches[0] = width * 2;
13393fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[0] = 0;
13403fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
13413fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1342a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[0] = virtual;
13433fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		break;
13443fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
13453fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	case DRM_FORMAT_NV12:
1346a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_NV21:
13473fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		pitches[0] = width;
13483fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[0] = 0;
13493fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
13503fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		pitches[1] = width;
13513fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[1] = width * height;
13523fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[1]);
13533fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1354a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[0] = virtual;
1355a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[1] = virtual + offsets[1];
13563fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		break;
13573fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
13583fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	case DRM_FORMAT_YVU420:
13593fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		pitches[0] = width;
13603fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[0] = 0;
13613fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
13623fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		pitches[1] = width / 2;
13633fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[1] = width * height;
13643fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[1]);
13653fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		pitches[2] = width / 2;
13663fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[2] = offsets[1] + (width * height) / 4;
13673fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[2]);
13683fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1369a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[0] = virtual;
1370a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[1] = virtual + offsets[1];
1371a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[2] = virtual + offsets[2];
13723fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		break;
13733fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1374a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_RGB565:
1375a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_ARGB1555:
13763fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	case DRM_FORMAT_XRGB1555:
13773fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		pitches[0] = width * 2;
13783fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[0] = 0;
13793fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
13803fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1381a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[0] = virtual;
13823fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		break;
13833fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1384a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_RGB888:
1385a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		pitches[0] = width * 3;
13863fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[0] = 0;
13873fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
13883fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1389a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[0] = virtual;
13903fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		break;
13913fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1392a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	case DRM_FORMAT_XRGB8888:
1393a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		pitches[0] = width * 4;
13943fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		offsets[0] = 0;
13953fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
13963fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1397a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart		planes[0] = virtual;
13983fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		break;
13993fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	}
14003fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1401a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart	fill_pattern(format, pattern, planes, width, height, pitches[0]);
14023fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	kms_bo_unmap(bo);
14033fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
14043fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	return bo;
14053fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart}
14063fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
14073fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart/* -------------------------------------------------------------------------- */
14083fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
14093fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartvoid
14103fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartpage_flip_handler(int fd, unsigned int frame,
14113fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		  unsigned int sec, unsigned int usec, void *data)
14123fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart{
14133fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	struct connector *c;
14143fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	unsigned int new_fb_id;
14153fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	struct timeval end;
14163fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	double t;
14173fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
14183fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	c = data;
14193fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (c->current_fb_id == c->fb_id[0])
14203fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		new_fb_id = c->fb_id[1];
14213fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	else
14223fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		new_fb_id = c->fb_id[0];
14233fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
14243fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	drmModePageFlip(fd, c->crtc, new_fb_id,
14253fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart			DRM_MODE_PAGE_FLIP_EVENT, c);
14263fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	c->current_fb_id = new_fb_id;
14273fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	c->swap_count++;
14283fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (c->swap_count == 60) {
14293fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		gettimeofday(&end, NULL);
14303fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		t = end.tv_sec + end.tv_usec * 1e-6 -
14313fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart			(c->start.tv_sec + c->start.tv_usec * 1e-6);
14323fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t);
14333fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		c->swap_count = 0;
14343fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		c->start = end;
14353fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	}
14363fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart}
14373fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1438d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic int
1439d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_plane(struct kms_driver *kms, struct connector *c, struct plane *p)
1440d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{
1441d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlaneRes *plane_resources;
1442d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlane *ovr;
1443d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
1444d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t plane_id = 0;
1445d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	struct kms_bo *plane_bo;
1446b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	uint32_t plane_flags = 0, format;
14479b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	int ret, crtc_x, crtc_y, crtc_w, crtc_h;
14489b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	unsigned int i;
1449d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
14503fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	format = format_fourcc(p->format_str);
14513fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (format == 0) {
14523fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		fprintf(stderr, "Unknown format: %s\n", p->format_str);
14533fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		return -1;
14543fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	}
14553fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart
1456d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* find an unused plane which can be connected to our crtc */
1457d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	plane_resources = drmModeGetPlaneResources(fd);
1458d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_resources) {
1459d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
1460d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
1461d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
1462d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
1463d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1464d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < plane_resources->count_planes && !plane_id; i++) {
1465d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
1466d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr) {
1467d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			fprintf(stderr, "drmModeGetPlane failed: %s\n",
1468d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				strerror(errno));
1469d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			return -1;
1470d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
1471d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1472d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if ((ovr->possible_crtcs & (1 << c->pipe)) && !ovr->crtc_id)
1473d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			plane_id = ovr->plane_id;
1474d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1475d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		drmModeFreePlane(ovr);
1476d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
1477d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1478b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	fprintf(stderr, "testing %dx%d@%s overlay plane\n",
1479b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			p->w, p->h, p->format_str);
1480b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
1481d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_id) {
1482d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to find plane!\n");
1483d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
1484d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
1485d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
14863fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	plane_bo = create_test_buffer(kms, format, p->w, p->h, handles,
1487a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				      pitches, offsets, PATTERN_TILES);
14883fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (plane_bo == NULL)
14893fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart		return -1;
1490d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1491d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* just use single plane format for now.. */
1492b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	if (drmModeAddFB2(fd, p->w, p->h, format,
1493d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			handles, pitches, offsets, &p->fb_id, plane_flags)) {
1494d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
1495d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
1496d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
1497d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1498d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* ok, boring.. but for now put in middle of screen: */
1499d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_x = c->mode->hdisplay / 3;
1500d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_y = c->mode->vdisplay / 3;
1501d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_w = crtc_x;
1502d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_h = crtc_y;
1503d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1504d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* note src coords (last 4 args) are in Q16 format */
1505d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (drmModeSetPlane(fd, plane_id, c->crtc, p->fb_id,
1506d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			    plane_flags, crtc_x, crtc_y, crtc_w, crtc_h,
1507d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			    0, 0, p->w << 16, p->h << 16)) {
1508d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to enable plane: %s\n",
1509d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
1510d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
1511d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
1512d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1513d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	return 0;
1514d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}
1515d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
15167a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic void
1517d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_mode(struct connector *c, int count, struct plane *p, int plane_count,
1518d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		int page_flip)
15197a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{
15208fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_driver *kms;
15218fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_bo *bo, *other_bo;
15221e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	unsigned int fb_id, other_fb_id;
15233fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	int i, j, ret, width, height, x;
15243fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
15251e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	drmEventContext evctx;
15267a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
15277a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	width = 0;
15287a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	height = 0;
15297a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	for (i = 0; i < count; i++) {
15307a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		connector_find_mode(&c[i]);
15317a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		if (c[i].mode == NULL)
15327a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			continue;
15337a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		width += c[i].mode->hdisplay;
15347a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		if (height < c[i].mode->vdisplay)
15357a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			height = c[i].mode->vdisplay;
15367a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	}
15377a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
15388fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	ret = kms_create(fd, &kms);
15398fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (ret) {
15408fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		fprintf(stderr, "failed to create kms driver: %s\n",
15418fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke			strerror(-ret));
15427a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return;
15437a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	}
15447a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
15453fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	bo = create_test_buffer(kms, DRM_FORMAT_XRGB8888, width, height, handles,
1546a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				pitches, offsets, PATTERN_SMPTE);
15473fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (bo == NULL)
15487a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return;
1549731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
15503fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	ret = drmModeAddFB(fd, width, height, 24, 32, pitches[0], handles[0], &fb_id);
1551731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (ret) {
1552680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz		fprintf(stderr, "failed to add fb (%ux%u): %s\n",
1553680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz			width, height, strerror(errno));
1554731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return;
1555731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1556731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1557669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	x = 0;
1558669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	for (i = 0; i < count; i++) {
1559669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c[i].mode == NULL)
1560669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			continue;
15618b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
15628b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		printf("setting mode %s on connector %d, crtc %d\n",
15638b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		       c[i].mode_str, c[i].id, c[i].crtc);
15648b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
15658b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		ret = drmModeSetCrtc(fd, c[i].crtc, fb_id, x, 0,
1566669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				     &c[i].id, 1, c[i].mode);
1567d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz
1568d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz		/* XXX: Actually check if this is needed */
1569d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz		drmModeDirtyFB(fd, fb_id, NULL, 0);
1570d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz
1571669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		x += c[i].mode->hdisplay;
1572669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
1573669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (ret) {
1574669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
1575669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			return;
1576669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		}
1577d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
1578d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		/* if we have a plane/overlay to show, set that up now: */
1579d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		for (j = 0; j < plane_count; j++)
1580d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			if (p[j].con_id == c[i].id)
1581d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				if (set_plane(kms, &c[i], &p[j]))
1582d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					return;
1583731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
15841e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
15851e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (!page_flip)
15861e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
15878fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
15883fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	other_bo = create_test_buffer(kms, DRM_FORMAT_XRGB8888, width, height, handles,
1589a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart				      pitches, offsets, PATTERN_PLAIN);
15903fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	if (other_bo == NULL)
15911e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
15921e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
15933fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart	ret = drmModeAddFB(fd, width, height, 32, 32, pitches[0], handles[0],
15941e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			   &other_fb_id);
15951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (ret) {
15961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
15971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
15981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
15991e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
16001e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	for (i = 0; i < count; i++) {
16011e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (c[i].mode == NULL)
16021e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			continue;
16031e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
16043c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		ret = drmModePageFlip(fd, c[i].crtc, other_fb_id,
16053c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz				      DRM_MODE_PAGE_FLIP_EVENT, &c[i]);
16063c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		if (ret) {
16073c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz			fprintf(stderr, "failed to page flip: %s\n", strerror(errno));
16083c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz			return;
16093c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		}
16101e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		gettimeofday(&c[i].start, NULL);
16111e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		c[i].swap_count = 0;
1612e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		c[i].fb_id[0] = fb_id;
1613e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		c[i].fb_id[1] = other_fb_id;
1614a697fb6acad7992c3d23bb6a663663694782eb7bBenjamin Franzke		c[i].current_fb_id = other_fb_id;
16151e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
16161e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
16171e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	memset(&evctx, 0, sizeof evctx);
16181e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	evctx.version = DRM_EVENT_CONTEXT_VERSION;
16191e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	evctx.vblank_handler = NULL;
16206f1eba0548cd6a96e91a4e8be7b91ba6a936eb98Jesse Barnes	evctx.page_flip_handler = page_flip_handler;
16211e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
16221e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	while (1) {
1623e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#if 0
16241e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		struct pollfd pfd[2];
16251e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
16261e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[0].fd = 0;
16271e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[0].events = POLLIN;
16281e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[1].fd = fd;
16291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[1].events = POLLIN;
16301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
16311e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (poll(pfd, 2, -1) < 0) {
16321e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			fprintf(stderr, "poll error\n");
16331e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
16341e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		}
16351e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
16361e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (pfd[0].revents)
16371e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
1638e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#else
1639e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
1640e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		fd_set fds;
1641e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		int ret;
1642e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes
1643e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_ZERO(&fds);
1644e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_SET(0, &fds);
1645e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_SET(fd, &fds);
1646e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		ret = select(fd + 1, &fds, NULL, NULL, &timeout);
1647e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes
1648e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		if (ret <= 0) {
1649e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			fprintf(stderr, "select timed out or error (ret %d)\n",
1650e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes				ret);
1651e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			continue;
1652e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		} else if (FD_ISSET(0, &fds)) {
1653e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			break;
1654e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		}
1655e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#endif
16561e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
16571e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		drmHandleEvent(fd, &evctx);
16581e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
16598fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
16608fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_destroy(&bo);
16618fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_destroy(&other_bo);
16628fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_destroy(&kms);
1663731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
1664731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1665731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern char *optarg;
1666731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern int optind, opterr, optopt;
1667d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic char optstr[] = "ecpmfs:P:v";
1668731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1669731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid usage(char *name)
1670731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
1671731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "usage: %s [-ecpmf]\n", name);
1672731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-e\tlist encoders\n");
1673731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-c\tlist connectors\n");
1674d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n");
1675731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-m\tlist modes\n");
1676731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-f\tlist framebuffers\n");
16771e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
1678731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n");
16798b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n");
1680d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	fprintf(stderr, "\t-P <connector_id>:<w>x<h>\tset a plane\n");
1681b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	fprintf(stderr, "\t-P <connector_id>:<w>x<h>@<format>\tset a plane\n");
1682731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\n\tDefault is to dump all info.\n");
1683731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	exit(0);
1684731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
1685731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1686731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define dump_resource(res) if (res) dump_##res()
1687731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
16889b44fbd393b8db571badae41881f490145404ae0Paulo Zanonistatic int page_flipping_supported(void)
168959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg{
16908fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	/*FIXME: generic ioctl needed? */
16918fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	return 1;
16928fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#if 0
169359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	int ret, value;
169459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	struct drm_i915_getparam gp;
169559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
169659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	gp.param = I915_PARAM_HAS_PAGEFLIPPING;
169759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	gp.value = &value;
169859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
169959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
170059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	if (ret) {
170159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		fprintf(stderr, "drm_i915_getparam: %m\n");
170259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		return 0;
170359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	}
170459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
1705e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	return *gp.value;
17068fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#endif
170759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg}
170859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
1709731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv)
1710731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
1711731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int c;
1712d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0;
17131e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	int test_vsync = 0;
1714e07b650662ea0529d99741691c47856ef1034c9cInki Dae	char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" };
17159b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	unsigned int i;
17169b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	int count = 0, plane_count = 0;
1717669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	struct connector con_args[2];
1718b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	struct plane plane_args[2] = {0};
1719669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
1720731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	opterr = 0;
1721731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	while ((c = getopt(argc, argv, optstr)) != -1) {
1722731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		switch (c) {
1723731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'e':
1724731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			encoders = 1;
1725731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1726731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'c':
1727731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			connectors = 1;
1728731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1729731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'p':
1730731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			crtcs = 1;
1731d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			planes = 1;
1732731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1733731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'm':
1734731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			modes = 1;
1735731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1736731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'f':
1737731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			framebuffers = 1;
1738731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
17391e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		case 'v':
17401e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			test_vsync = 1;
17411e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
1742731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 's':
17438b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg			con_args[count].crtc = -1;
1744669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			if (sscanf(optarg, "%d:%64s",
1745669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				   &con_args[count].id,
1746e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell				   con_args[count].mode_str) != 2 &&
17478b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg			    sscanf(optarg, "%d@%d:%64s",
17488b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg				   &con_args[count].id,
17498b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg				   &con_args[count].crtc,
1750e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell				   con_args[count].mode_str) != 3)
1751669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				usage(argv[0]);
1752669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			count++;
1753731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1754d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		case 'P':
1755b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			strcpy(plane_args[plane_count].format_str, "XR24");
1756b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			if (sscanf(optarg, "%d:%dx%d@%4s",
1757b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					&plane_args[plane_count].con_id,
1758b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					&plane_args[plane_count].w,
1759b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					&plane_args[plane_count].h,
1760b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					plane_args[plane_count].format_str) != 4 &&
1761b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark				sscanf(optarg, "%d:%dx%d",
1762d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					&plane_args[plane_count].con_id,
1763d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					&plane_args[plane_count].w,
1764d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					&plane_args[plane_count].h) != 3)
1765d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				usage(argv[0]);
1766d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			plane_count++;
1767d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			break;
1768731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		default:
1769731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			usage(argv[0]);
1770731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1771731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
1772731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1773731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1774731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (argc == 1)
1775d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		encoders = connectors = crtcs = planes = modes = framebuffers = 1;
1776731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1777731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < ARRAY_SIZE(modules); i++) {
1778731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("trying to load module %s...", modules[i]);
1779731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fd = drmOpen(modules[i], NULL);
1780731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (fd < 0) {
1781731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			printf("failed.\n");
1782731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		} else {
1783731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			printf("success.\n");
1784731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1785731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
1786731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1787731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
17889b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni	if (test_vsync && !page_flipping_supported()) {
178959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		fprintf(stderr, "page flipping not supported by drm.\n");
179059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		return -1;
179159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	}
179259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
1793731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (i == ARRAY_SIZE(modules)) {
1794731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "failed to load any modules, aborting.\n");
1795731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return -1;
1796731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1797731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1798731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	resources = drmModeGetResources(fd);
1799731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (!resources) {
1800731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "drmModeGetResources failed: %s\n",
1801731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			strerror(errno));
1802731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmClose(fd);
1803731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return 1;
1804731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1805731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1806731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(encoders);
1807731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(connectors);
1808731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(crtcs);
1809d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	dump_resource(planes);
1810731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(framebuffers);
1811731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1812669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	if (count > 0) {
1813d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		set_mode(con_args, count, plane_args, plane_count, test_vsync);
18142c113a1b159f57ab94b54316ece49c677cfe04ceKristian Høgsberg		getchar();
1815731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1816731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1817731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeFreeResources(resources);
1818731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1819731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return 0;
1820731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
1821