modeprint.c revision e6188e58
1/*
2 * \file modedemo.c
3 * Test program to dump DRM kernel mode setting related information.
4 * Queries the kernel for all available information and dumps it to stdout.
5 *
6 * \author Jakob Bornecrantz <wallbraker@gmail.com>
7 */
8
9/*
10 * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
11 * Copyright (c) 2007-2008 Jakob Bornecrantz <wallbraker@gmail.com>
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a
14 * copy of this software and associated documentation files (the "Software"),
15 * to deal in the Software without restriction, including without limitation
16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29 * IN THE SOFTWARE.
30 *
31 */
32
33#include <assert.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <stdint.h>
37#include <unistd.h>
38#include <string.h>
39#include <inttypes.h>
40
41#include "xf86drm.h"
42#include "xf86drmMode.h"
43
44#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
45
46int current;
47int connectors;
48int full_props;
49int edid;
50int modes;
51int full_modes;
52int encoders;
53int crtcs;
54int fbs;
55char *module_name;
56
57static const char* getConnectionText(drmModeConnection conn)
58{
59	switch (conn) {
60	case DRM_MODE_CONNECTED:
61		return "connected";
62	case DRM_MODE_DISCONNECTED:
63		return "disconnected";
64	default:
65		return "unknown";
66	}
67
68}
69
70static int printMode(struct drm_mode_modeinfo *mode)
71{
72	if (full_modes) {
73		printf("Mode: %s\n", mode->name);
74		printf("\tclock       : %i\n", mode->clock);
75		printf("\thdisplay    : %i\n", mode->hdisplay);
76		printf("\thsync_start : %i\n", mode->hsync_start);
77		printf("\thsync_end   : %i\n", mode->hsync_end);
78		printf("\thtotal      : %i\n", mode->htotal);
79		printf("\thskew       : %i\n", mode->hskew);
80		printf("\tvdisplay    : %i\n", mode->vdisplay);
81		printf("\tvsync_start : %i\n", mode->vsync_start);
82		printf("\tvsync_end   : %i\n", mode->vsync_end);
83		printf("\tvtotal      : %i\n", mode->vtotal);
84		printf("\tvscan       : %i\n", mode->vscan);
85		printf("\tvrefresh    : %i\n", mode->vrefresh);
86		printf("\tflags       : %i\n", mode->flags);
87	} else {
88		printf("Mode: \"%s\" %ix%i %i\n", mode->name,
89				mode->hdisplay, mode->vdisplay, mode->vrefresh);
90	}
91	return 0;
92}
93
94static int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, uint64_t value)
95{
96	const char *name = NULL;
97	int j;
98
99	printf("Property: %s\n", props->name);
100	printf("\tid           : %i\n", props->prop_id);
101	printf("\tflags        : %i\n", props->flags);
102	printf("\tcount_values : %d\n", props->count_values);
103
104
105	if (props->count_values) {
106		printf("\tvalues       :");
107		for (j = 0; j < props->count_values; j++)
108			printf(" %" PRIu64, props->values[j]);
109		printf("\n");
110	}
111
112
113	printf("\tcount_enums  : %d\n", props->count_enums);
114
115	if (props->flags & DRM_MODE_PROP_BLOB) {
116		drmModePropertyBlobPtr blob;
117
118		blob = drmModeGetPropertyBlob(fd, value);
119		if (blob) {
120			printf("blob is %d length, %08X\n", blob->length, *(uint32_t *)blob->data);
121			drmModeFreePropertyBlob(blob);
122		} else {
123			printf("error getting blob %" PRIu64 "\n", value);
124		}
125
126	} else {
127		if (!strncmp(props->name, "DPMS", 4))
128			;
129
130		for (j = 0; j < props->count_enums; j++) {
131			printf("\t\t%lld = %s\n", props->enums[j].value, props->enums[j].name);
132			if (props->enums[j].value == value)
133				name = props->enums[j].name;
134		}
135
136		if (props->count_enums && name) {
137			printf("\tcon_value    : %s\n", name);
138		} else {
139			printf("\tcon_value    : %" PRIu64 "\n", value);
140		}
141	}
142
143	return 0;
144}
145
146static const char * const output_names[] = { "None",
147					     "VGA",
148					     "DVI-I",
149					     "DVI-D",
150					     "DVI-A",
151					     "Composite",
152					     "SVIDEO",
153					     "LVDS",
154					     "Component",
155					     "DIN",
156					     "DP",
157					     "HDMI-A",
158					     "HDMI-B",
159					     "TV",
160					     "eDP",
161					     "Virtual",
162					     "DSI",
163};
164
165static int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uint32_t id)
166{
167	int i = 0;
168	struct drm_mode_modeinfo *mode = NULL;
169	drmModePropertyPtr props;
170
171	if (connector->connector_type < ARRAY_SIZE(output_names))
172		printf("Connector: %s-%d\n", output_names[connector->connector_type],
173			connector->connector_type_id);
174	else
175		printf("Connector: %d-%d\n", connector->connector_type,
176			connector->connector_type_id);
177	printf("\tid             : %i\n", id);
178	printf("\tencoder id     : %i\n", connector->encoder_id);
179	printf("\tconn           : %s\n", getConnectionText(connector->connection));
180	printf("\tsize           : %ix%i (mm)\n", connector->mmWidth, connector->mmHeight);
181	printf("\tcount_modes    : %i\n", connector->count_modes);
182	printf("\tcount_props    : %i\n", connector->count_props);
183	if (connector->count_props) {
184		printf("\tprops          :");
185		for (i = 0; i < connector->count_props; i++)
186			printf(" %i", connector->props[i]);
187		printf("\n");
188	}
189
190	printf("\tcount_encoders : %i\n", connector->count_encoders);
191	if (connector->count_encoders) {
192		printf("\tencoders       :");
193		for (i = 0; i < connector->count_encoders; i++)
194			printf(" %i", connector->encoders[i]);
195		printf("\n");
196	}
197
198	if (modes) {
199		for (i = 0; i < connector->count_modes; i++) {
200			mode = (struct drm_mode_modeinfo *)&connector->modes[i];
201			printMode(mode);
202		}
203	}
204
205	if (full_props) {
206		for (i = 0; i < connector->count_props; i++) {
207			props = drmModeGetProperty(fd, connector->props[i]);
208			if (props) {
209				printProperty(fd, res, props, connector->prop_values[i]);
210				drmModeFreeProperty(props);
211			}
212		}
213	}
214
215	return 0;
216}
217
218static int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t id)
219{
220	printf("Encoder\n");
221	printf("\tid     :%i\n", id);
222	printf("\tcrtc_id   :%d\n", encoder->crtc_id);
223	printf("\ttype   :%d\n", encoder->encoder_type);
224	printf("\tpossible_crtcs  :0x%x\n", encoder->possible_crtcs);
225	printf("\tpossible_clones :0x%x\n", encoder->possible_clones);
226	return 0;
227}
228
229static int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id)
230{
231	printf("Crtc\n");
232	printf("\tid             : %i\n", id);
233	printf("\tx              : %i\n", crtc->x);
234	printf("\ty              : %i\n", crtc->y);
235	printf("\twidth          : %i\n", crtc->width);
236	printf("\theight         : %i\n", crtc->height);
237	printf("\tmode           : %p\n", &crtc->mode);
238	printf("\tgamma size     : %d\n", crtc->gamma_size);
239
240	return 0;
241}
242
243static int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb)
244{
245	printf("Framebuffer\n");
246	printf("\thandle    : %i\n", fb->handle);
247	printf("\twidth     : %i\n", fb->width);
248	printf("\theight    : %i\n", fb->height);
249	printf("\tpitch     : %i\n", fb->pitch);;
250	printf("\tbpp       : %i\n", fb->bpp);
251	printf("\tdepth     : %i\n", fb->depth);
252	printf("\tbuffer_id : %i\n", fb->handle);
253
254	return 0;
255}
256
257static int printRes(int fd, drmModeResPtr res)
258{
259	int i;
260	drmModeFBPtr fb;
261	drmModeCrtcPtr crtc;
262	drmModeEncoderPtr encoder;
263	drmModeConnectorPtr connector;
264
265	printf("Resources\n\n");
266
267	printf("count_connectors : %i\n", res->count_connectors);
268	printf("count_encoders   : %i\n", res->count_encoders);
269	printf("count_crtcs      : %i\n", res->count_crtcs);
270	printf("count_fbs        : %i\n", res->count_fbs);
271
272	printf("\n");
273
274	if (connectors) {
275		for (i = 0; i < res->count_connectors; i++) {
276			connector = (current ? drmModeGetConnectorCurrent : drmModeGetConnector) (fd, res->connectors[i]);
277
278			if (!connector)
279				printf("Could not get connector %i\n", res->connectors[i]);
280			else {
281				printConnector(fd, res, connector, res->connectors[i]);
282				drmModeFreeConnector(connector);
283			}
284		}
285		printf("\n");
286	}
287
288
289	if (encoders) {
290		for (i = 0; i < res->count_encoders; i++) {
291			encoder = drmModeGetEncoder(fd, res->encoders[i]);
292
293			if (!encoder)
294				printf("Could not get encoder %i\n", res->encoders[i]);
295			else {
296				printEncoder(fd, res, encoder, res->encoders[i]);
297				drmModeFreeEncoder(encoder);
298			}
299		}
300		printf("\n");
301	}
302
303	if (crtcs) {
304		for (i = 0; i < res->count_crtcs; i++) {
305			crtc = drmModeGetCrtc(fd, res->crtcs[i]);
306
307			if (!crtc)
308				printf("Could not get crtc %i\n", res->crtcs[i]);
309			else {
310				printCrtc(fd, res, crtc, res->crtcs[i]);
311				drmModeFreeCrtc(crtc);
312			}
313		}
314		printf("\n");
315	}
316
317	if (fbs) {
318		for (i = 0; i < res->count_fbs; i++) {
319			fb = drmModeGetFB(fd, res->fbs[i]);
320
321			if (!fb)
322				printf("Could not get fb %i\n", res->fbs[i]);
323			else {
324				printFrameBuffer(fd, res, fb);
325				drmModeFreeFB(fb);
326			}
327		}
328	}
329
330	return 0;
331}
332
333static void args(int argc, char **argv)
334{
335	int defaults = 1;
336	int i;
337
338	fbs = 0;
339	edid = 0;
340	crtcs = 0;
341	modes = 0;
342	encoders = 0;
343	full_modes = 0;
344	full_props = 0;
345	connectors = 0;
346	current = 0;
347
348	module_name = argv[1];
349
350	for (i = 2; i < argc; i++) {
351		if (strcmp(argv[i], "-fb") == 0) {
352			fbs = 1;
353			defaults = 0;
354		} else if (strcmp(argv[i], "-crtcs") == 0) {
355			crtcs = 1;
356			defaults = 0;
357		} else if (strcmp(argv[i], "-cons") == 0) {
358			connectors = 1;
359			modes = 1;
360			defaults = 0;
361		} else if (strcmp(argv[i], "-modes") == 0) {
362			connectors = 1;
363			modes = 1;
364			defaults = 0;
365		} else if (strcmp(argv[i], "-full") == 0) {
366			connectors = 1;
367			modes = 1;
368			full_modes = 1;
369			defaults = 0;
370		} else if (strcmp(argv[i], "-props") == 0) {
371			connectors = 1;
372			full_props = 1;
373			defaults = 0;
374		} else if (strcmp(argv[i], "-edids") == 0) {
375			connectors = 1;
376			edid = 1;
377			defaults = 0;
378		} else if (strcmp(argv[i], "-encoders") == 0) {
379			encoders = 1;
380			defaults = 0;
381		} else if (strcmp(argv[i], "-v") == 0) {
382			fbs = 1;
383			edid = 1;
384			crtcs = 1;
385			modes = 1;
386			encoders = 1;
387			full_modes = 1;
388			full_props = 1;
389			connectors = 1;
390			defaults = 0;
391		} else if (strcmp(argv[i], "-current") == 0) {
392			current = 1;
393		}
394	}
395
396	if (defaults) {
397		fbs = 1;
398		edid = 1;
399		crtcs = 1;
400		modes = 1;
401		encoders = 1;
402		full_modes = 0;
403		full_props = 0;
404		connectors = 1;
405	}
406}
407
408int main(int argc, char **argv)
409{
410	int fd;
411	drmModeResPtr res;
412
413	if (argc == 1) {
414		printf("Please add modulename as first argument\n");
415		return 1;
416	}
417
418	args(argc, argv);
419
420	printf("Starting test\n");
421
422	fd = drmOpen(module_name, NULL);
423
424	if (fd < 0) {
425		printf("Failed to open the card fd (%d)\n",fd);
426		return 1;
427	}
428
429	res = drmModeGetResources(fd);
430	if (res == 0) {
431		printf("Failed to get resources from card\n");
432		drmClose(fd);
433		return 1;
434	}
435
436	printRes(fd, res);
437
438	drmModeFreeResources(res);
439
440	printf("Ok\n");
441
442	return 0;
443}
444