modetest.c revision 8b8803695b24d4cb4d041437a4709be06e59471b
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>
46731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <unistd.h>
47731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <string.h>
48731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <errno.h>
49731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
50731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drm.h"
51731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drmMode.h"
52731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "intel_bufmgr.h"
53731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#ifdef HAVE_CAIRO
557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include <math.h>
567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include <cairo.h>
577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#endif
587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
59731cd5526e5c732d51307b26e784f454a724a699Jesse BarnesdrmModeRes *resources;
60731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint fd, modes;
61731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
62731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
63731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
64731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name {
65731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int type;
66731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	char *name;
67731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
68731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
69731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define type_name_fn(res) \
70731cd5526e5c732d51307b26e784f454a724a699Jesse Barneschar * res##_str(int type) {			\
71731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;						\
72731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
73731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (res##_names[i].type == type)	\
74731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			return res##_names[i].name;	\
75731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}						\
76731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return "(invalid)";				\
77731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
78731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
79731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name encoder_type_names[] = {
80731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_NONE, "none" },
81731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_DAC, "DAC" },
82731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
83731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
84731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_TVDAC, "TVDAC" },
85731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
86731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
87731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(encoder_type)
88731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
89731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_status_names[] = {
90731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTED, "connected" },
91731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_DISCONNECTED, "disconnected" },
92731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_UNKNOWNCONNECTION, "unknown" },
93731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
94731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
95731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_status)
96731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
97731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_type_names[] = {
98731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Unknown, "unknown" },
99731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_VGA, "VGA" },
100731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
101731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
102731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
103731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Composite, "composite" },
104731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
105731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
106731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Component, "component" },
107731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
108731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DisplayPort, "displayport" },
109731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
110731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
111731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
112731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
113731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_type)
114731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
115731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_encoders(void)
116731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
117731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeEncoder *encoder;
118731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
119731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
120731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("Encoders:\n");
121731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n");
122731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_encoders; i++) {
123731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		encoder = drmModeGetEncoder(fd, resources->encoders[i]);
124731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
125731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!encoder) {
126731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get encoder %i: %s\n",
127731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->encoders[i], strerror(errno));
128731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
129731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
130731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("%d\t%d\t%s\t0x%08x\t0x%08x\n",
131731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->encoder_id,
132731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->crtc_id,
133731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder_type_str(encoder->encoder_type),
134731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->possible_crtcs,
135731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->possible_clones);
136731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeEncoder(encoder);
137731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1380243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
1390243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg}
1400243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
1410243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsbergvoid dump_mode(struct drm_mode_modeinfo *mode)
1420243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg{
1430243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("  %s %.02f %d %d %d %d %d %d %d %d\n",
1440243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->name,
1450243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       (float)mode->vrefresh / 1000,
1460243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hdisplay,
1470243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hsync_start,
1480243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hsync_end,
1490243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->htotal,
1500243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vdisplay,
1510243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vsync_start,
1520243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vsync_end,
1530243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vtotal);
154731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
155731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
156731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_connectors(void)
157731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
158731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeConnector *connector;
159731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i, j;
160731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
161731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("Connectors:\n");
162731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n");
163731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_connectors; i++) {
164731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		connector = drmModeGetConnector(fd, resources->connectors[i]);
165731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
166731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector) {
167731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get connector %i: %s\n",
168731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->connectors[i], strerror(errno));
169731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
170731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
171731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
172731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n",
173731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->connector_id,
174731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->encoder_id,
175731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector_status_str(connector->connection),
176731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector_type_str(connector->connector_type),
177731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->mmWidth, connector->mmHeight,
178731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->count_modes);
179731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
180731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector->count_modes)
181731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
182731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
183731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("  modes:\n");
184731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("  name refresh (Hz) hdisp hss hse htot vdisp "
185731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       "vss vse vtot)\n");
1860243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		for (j = 0; j < connector->count_modes; j++)
1870243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg			dump_mode(&connector->modes[j]);
1880243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
189731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeConnector(connector);
190731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1910243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
192731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
193731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
194731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_crtcs(void)
195731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
196731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeCrtc *crtc;
197731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
198731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("CRTCs:\n");
2000243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("id\tfb\tpos\tsize\n");
201731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_crtcs; i++) {
202731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		crtc = drmModeGetCrtc(fd, resources->crtcs[i]);
203731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
204731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!crtc) {
205731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get crtc %i: %s\n",
206731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->crtcs[i], strerror(errno));
207731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
208731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
2090243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		printf("%d\t%d\t(%d,%d)\t(%dx%d)\n",
2100243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->crtc_id,
2110243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->buffer_id,
2120243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->x, crtc->y,
2130243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->width, crtc->height);
2140243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		dump_mode(&crtc->mode);
2150243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
216731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeCrtc(crtc);
217731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
2180243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
219731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
220731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
221731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_framebuffers(void)
222731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
223731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeFB *fb;
224731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
225731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2260243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("Frame buffers:\n");
2270243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("id\tsize\tpitch\n");
228731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_fbs; i++) {
229731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fb = drmModeGetFB(fd, resources->fbs[i]);
230731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
231731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!fb) {
232731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get fb %i: %s\n",
233731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->fbs[i], strerror(errno));
234731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
235731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
2360243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		printf("%d\t(%dx%d)\t%d\n",
2370243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       fb->fb_id,
2380243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       fb->width, fb->height);
2390243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
240731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeFB(fb);
241731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
2420243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
243731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
244731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
245731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/*
246731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Mode setting with the kernel interfaces is a bit of a chore.
247731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * First you have to find the connector in question and make sure the
248731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * requested mode is available.
249731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Then you need to find the encoder attached to that connector so you
250731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * can bind it with a free crtc.
251731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */
252669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstruct connector {
253669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	int id;
254669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	char mode_str[64];
255669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	struct drm_mode_modeinfo *mode;
256669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	drmModeEncoder *encoder;
2578b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	int crtc;
258669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg};
259669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
260669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstatic void
261669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergconnector_find_mode(struct connector *c)
262731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
263731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeConnector *connector;
264731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i, j, size, ret, width, height;
265731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
266731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* First, find the connector & mode */
267669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	c->mode = NULL;
268731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_connectors; i++) {
269731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		connector = drmModeGetConnector(fd, resources->connectors[i]);
270731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
271731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector) {
272731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get connector %i: %s\n",
273731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->connectors[i], strerror(errno));
274731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
275731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
276731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
277731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
278731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector->count_modes) {
279731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
280731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
281731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
282731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
283669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (connector->connector_id != c->id) {
284731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
285731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
286731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
287731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
288731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		for (j = 0; j < connector->count_modes; j++) {
289669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			c->mode = &connector->modes[j];
290669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			if (!strcmp(c->mode->name, c->mode_str))
291731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				break;
292731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
293731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
294731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		/* Found it, break out */
295669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c->mode)
296731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
297731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
298731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeConnector(connector);
299731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
300731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
301669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	if (!c->mode) {
302669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
303731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return;
304731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
305731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
306731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* Now get the encoder */
307731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_encoders; i++) {
308669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);
309731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
310669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (!c->encoder) {
311731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get encoder %i: %s\n",
312731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->encoders[i], strerror(errno));
313669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			drmModeFreeEncoder(c->encoder);
314731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
315731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
316731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
317669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c->encoder->encoder_id  == connector->encoder_id)
318731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
319731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
320669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		drmModeFreeEncoder(c->encoder);
321669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	}
3228b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
3238b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	if (c->crtc == -1)
3248b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		c->crtc = c->encoder->crtc_id;
325669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg}
326669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
3277a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#ifdef HAVE_CAIRO
3287a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
3297a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic int
3307a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergcreate_test_buffer(drm_intel_bufmgr *bufmgr,
3317a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		   int width, int height, int *stride_out, drm_intel_bo **bo_out)
332669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg{
333669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	drm_intel_bo *bo;
3347a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	unsigned int *fb_ptr;
3357a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	int size, ret, i, stride;
336669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	div_t d;
3377a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_surface_t *surface;
3387a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_t *cr;
3397a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	char buf[64];
3407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	int x, y;
341669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
3427a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
3437a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	stride = cairo_image_surface_get_stride(surface);
3447a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	size = stride * height;
3457a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	fb_ptr = (unsigned int *) cairo_image_surface_get_data(surface);
3467a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
3477a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	/* paint the buffer with colored tiles */
3487a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	for (i = 0; i < width * height; i++) {
3497a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		d = div(i, width);
3507a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
351731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
352731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3537a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cr = cairo_create(surface);
3547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
3557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	for (x = 0; x < width; x += 250)
3567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		for (y = 0; y < height; y += 250) {
3577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
3587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x, y - 20);
3597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_line_to(cr, x, y + 20);
3607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x - 20, y);
3617a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_line_to(cr, x + 20, y);
3627a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_new_sub_path(cr);
3637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_arc(cr, x, y, 10, 0, M_PI * 2);
3647a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_line_width(cr, 4);
3657a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 0, 0, 0);
3667a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke_preserve(cr);
3677a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 1, 1, 1);
3687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_line_width(cr, 2);
3697a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke(cr);
3707a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			snprintf(buf, sizeof buf, "%d, %d", x, y);
3717a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x + 20, y + 20);
3727a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_text_path(cr, buf);
3737a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 0, 0, 0);
3747a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke_preserve(cr);
3757a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 1, 1, 1);
3767a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_fill(cr);
3777a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		}
3787a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
3797a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_destroy(cr);
3807a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
3817a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096);
3827a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	if (!bo) {
3837a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		fprintf(stderr, "failed to alloc buffer: %s\n",
3847a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			strerror(errno));
3857a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return -1;
386731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
387731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
3887a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	drm_intel_bo_subdata(bo, 0, size, fb_ptr);
3897a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
3907a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_surface_destroy(surface);
3917a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
3927a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	*bo_out = bo;
3937a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	*stride_out = stride;
3947a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
3957a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	return 0;
3967a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg}
3977a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
3987a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#else
3997a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4007a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic int
4017a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergcreate_test_buffer(drm_intel_bufmgr *bufmgr,
4027a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		   int width, int height, int *stride_out, drm_intel_bo **bo_out)
4037a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{
4047a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	drm_intel_bo *bo;
4057a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	unsigned int *fb_ptr;
4067a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	int size, ret, i, stride;
4077a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	div_t d;
4087a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
409731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* Mode size at 32 bpp */
4107a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	stride = width * 4;
4117a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	size = stride * height;
412731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
413731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096);
414731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (!bo) {
415731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "failed to alloc buffer: %s\n",
416731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			strerror(errno));
4177a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return -1;
418731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
419731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
420731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	ret = drm_intel_gem_bo_map_gtt(bo);
421731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (ret) {
422731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "failed to GTT map buffer: %s\n",
423731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			strerror(errno));
4247a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return -1;
425731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
426731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
427731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fb_ptr = bo->virtual;
428731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
429d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg	/* paint the buffer with colored tiles */
430d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg	for (i = 0; i < width * height; i++) {
431d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg		d = div(i, width);
432d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg		fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
433d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg	}
4347a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	drm_intel_bo_unmap(bo);
4357a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4367a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	*bo_out = bo;
4377a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	*stride_out = stride;
4387a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4397a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	return 0;
4407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg}
4417a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4427a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#endif
4437a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4447a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic void
4457a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergset_mode(struct connector *c, int count)
4467a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{
4477a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	drmModeConnector *connector;
4487a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	drmModeEncoder *encoder = NULL;
4497a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	struct drm_mode_modeinfo *mode = NULL;
4507a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	drm_intel_bufmgr *bufmgr;
4517a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	drm_intel_bo *bo;
4527a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	unsigned int fb_id;
4537a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	int i, j, ret, width, height, x, stride;
4547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	width = 0;
4567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	height = 0;
4577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	for (i = 0; i < count; i++) {
4587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		connector_find_mode(&c[i]);
4597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		if (c[i].mode == NULL)
4607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			continue;
4617a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		width += c[i].mode->hdisplay;
4627a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		if (height < c[i].mode->vdisplay)
4637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			height = c[i].mode->vdisplay;
4647a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	}
4657a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4667a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20);
4677a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	if (!bufmgr) {
4687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno));
4697a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return;
4707a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	}
4717a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4727a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	if (create_test_buffer(bufmgr, width, height, &stride, &bo))
4737a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return;
474731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
4757a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	ret = drmModeAddFB(fd, width, height, 32, 32, stride, bo->handle,
476731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			   &fb_id);
477731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (ret) {
478731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
479731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return;
480731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
481731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
482669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	x = 0;
483669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	for (i = 0; i < count; i++) {
4848b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		int crtc_id;
485669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c[i].mode == NULL)
486669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			continue;
4878b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
4888b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		printf("setting mode %s on connector %d, crtc %d\n",
4898b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		       c[i].mode_str, c[i].id, c[i].crtc);
4908b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
4918b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		ret = drmModeSetCrtc(fd, c[i].crtc, fb_id, x, 0,
492669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				     &c[i].id, 1, c[i].mode);
493669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		x += c[i].mode->hdisplay;
494669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
495669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (ret) {
496669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
497669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			return;
498669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		}
499731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
500731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
501731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
502731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern char *optarg;
503731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern int optind, opterr, optopt;
504731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstatic char optstr[] = "ecpmfs:";
505731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
506731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid usage(char *name)
507731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
508731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "usage: %s [-ecpmf]\n", name);
509731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-e\tlist encoders\n");
510731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-c\tlist connectors\n");
511731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n");
512731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-m\tlist modes\n");
513731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-f\tlist framebuffers\n");
514731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n");
5158b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n");
516731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\n\tDefault is to dump all info.\n");
517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	exit(0);
518731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
519731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
520731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define dump_resource(res) if (res) dump_##res()
521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
522731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv)
523731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
524731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int c;
525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0;
526731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	char *modules[] = { "i915", "radeon" };
527731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	char *modeset = NULL, *mode, *connector;
528669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	int i, connector_id, count = 0;
529669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	struct connector con_args[2];
530669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
531731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	opterr = 0;
532731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	while ((c = getopt(argc, argv, optstr)) != -1) {
533731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		switch (c) {
534731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'e':
535731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			encoders = 1;
536731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
537731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'c':
538731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			connectors = 1;
539731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
540731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'p':
541731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			crtcs = 1;
542731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
543731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'm':
544731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			modes = 1;
545731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
546731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'f':
547731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			framebuffers = 1;
548731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
549731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 's':
550731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			modeset = strdup(optarg);
5518b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg			con_args[count].crtc = -1;
552669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			if (sscanf(optarg, "%d:%64s",
553669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				   &con_args[count].id,
5548b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg				   &con_args[count].mode_str) != 2 &&
5558b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg			    sscanf(optarg, "%d@%d:%64s",
5568b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg				   &con_args[count].id,
5578b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg				   &con_args[count].crtc,
5588b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg				   &con_args[count].mode_str) != 3)
559669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				usage(argv[0]);
560669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			count++;
561731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
562731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		default:
563731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			usage(argv[0]);
564731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
565731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
566731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
567731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
568731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (argc == 1)
569731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		encoders = connectors = crtcs = modes = framebuffers = 1;
570731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
571731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < ARRAY_SIZE(modules); i++) {
572731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("trying to load module %s...", modules[i]);
573731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fd = drmOpen(modules[i], NULL);
574731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (fd < 0) {
575731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			printf("failed.\n");
576731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		} else {
577731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			printf("success.\n");
578731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
579731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
580731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
581731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
582731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (i == ARRAY_SIZE(modules)) {
583731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "failed to load any modules, aborting.\n");
584731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return -1;
585731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
586731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
587731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	resources = drmModeGetResources(fd);
588731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (!resources) {
589731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "drmModeGetResources failed: %s\n",
590731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			strerror(errno));
591731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmClose(fd);
592731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return 1;
593731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
594731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
595731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(encoders);
596731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(connectors);
597731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(crtcs);
598731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(framebuffers);
599731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
600669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	if (count > 0) {
601669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		set_mode(con_args, count);
6022c113a1b159f57ab94b54316ece49c677cfe04ceKristian Høgsberg		getchar();
603731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
604731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
605731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeFreeResources(resources);
606731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
607731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return 0;
608731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
609