proptest.c revision 3f012e29
1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2012 Intel Corporation
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21b8e80941Smrg * IN THE SOFTWARE.
22b8e80941Smrg *
23b8e80941Smrg * Authors:
24b8e80941Smrg *    Paulo Zanoni <paulo.r.zanoni@intel.com>
25b8e80941Smrg *
26b8e80941Smrg */
27b8e80941Smrg
28b8e80941Smrg#include <assert.h>
29b8e80941Smrg#include <errno.h>
30b8e80941Smrg#include <getopt.h>
31b8e80941Smrg#include <inttypes.h>
32b8e80941Smrg#include <stdlib.h>
33b8e80941Smrg#include <stdio.h>
34b8e80941Smrg#include <string.h>
35b8e80941Smrg
36b8e80941Smrg#include "xf86drm.h"
37b8e80941Smrg#include "xf86drmMode.h"
38b8e80941Smrg
39b8e80941Smrg#include "util/common.h"
40b8e80941Smrg#include "util/kms.h"
41b8e80941Smrg
42b8e80941Smrgstatic inline int64_t U642I64(uint64_t val)
43b8e80941Smrg{
44b8e80941Smrg	return (int64_t)*((int64_t *)&val);
45b8e80941Smrg}
46b8e80941Smrg
47b8e80941Smrgint fd;
48b8e80941SmrgdrmModeResPtr res = NULL;
49b8e80941Smrg
50b8e80941Smrg/* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */
51b8e80941Smrgstatic void
52b8e80941Smrgdump_blob(uint32_t blob_id)
53b8e80941Smrg{
54b8e80941Smrg	uint32_t i;
55b8e80941Smrg	unsigned char *blob_data;
56b8e80941Smrg	drmModePropertyBlobPtr blob;
57b8e80941Smrg
58b8e80941Smrg	blob = drmModeGetPropertyBlob(fd, blob_id);
59b8e80941Smrg	if (!blob) {
60b8e80941Smrg		printf("\n");
61b8e80941Smrg		return;
62b8e80941Smrg	}
63b8e80941Smrg
64b8e80941Smrg	blob_data = blob->data;
65b8e80941Smrg
66b8e80941Smrg	for (i = 0; i < blob->length; i++) {
67b8e80941Smrg		if (i % 16 == 0)
68b8e80941Smrg			printf("\n\t\t\t");
69b8e80941Smrg		printf("%.2hhx", blob_data[i]);
70b8e80941Smrg	}
71b8e80941Smrg	printf("\n");
72b8e80941Smrg
73b8e80941Smrg	drmModeFreePropertyBlob(blob);
74b8e80941Smrg}
75b8e80941Smrg
76b8e80941Smrgstatic void
77b8e80941Smrgdump_prop(uint32_t prop_id, uint64_t value)
78b8e80941Smrg{
79b8e80941Smrg	int i;
80b8e80941Smrg	drmModePropertyPtr prop;
81b8e80941Smrg
82b8e80941Smrg	prop = drmModeGetProperty(fd, prop_id);
83b8e80941Smrg
84b8e80941Smrg	printf("\t%d", prop_id);
85b8e80941Smrg	if (!prop) {
86b8e80941Smrg		printf("\n");
87b8e80941Smrg		return;
88b8e80941Smrg	}
89b8e80941Smrg
90b8e80941Smrg	printf(" %s:\n", prop->name);
91b8e80941Smrg
92b8e80941Smrg	printf("\t\tflags:");
93b8e80941Smrg	if (prop->flags & DRM_MODE_PROP_PENDING)
94b8e80941Smrg		printf(" pending");
95b8e80941Smrg	if (prop->flags & DRM_MODE_PROP_IMMUTABLE)
96b8e80941Smrg		printf(" immutable");
97b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE))
98b8e80941Smrg		printf(" signed range");
99b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE))
100b8e80941Smrg		printf(" range");
101b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM))
102b8e80941Smrg		printf(" enum");
103b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK))
104b8e80941Smrg		printf(" bitmask");
105b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB))
106b8e80941Smrg		printf(" blob");
107b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_OBJECT))
108b8e80941Smrg		printf(" object");
109b8e80941Smrg	printf("\n");
110b8e80941Smrg
111b8e80941Smrg
112b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) {
113b8e80941Smrg		printf("\t\tvalues:");
114b8e80941Smrg		for (i = 0; i < prop->count_values; i++)
115b8e80941Smrg			printf(" %"PRId64, U642I64(prop->values[i]));
116b8e80941Smrg		printf("\n");
117b8e80941Smrg	}
118b8e80941Smrg
119b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) {
120b8e80941Smrg		printf("\t\tvalues:");
121b8e80941Smrg		for (i = 0; i < prop->count_values; i++)
122b8e80941Smrg			printf(" %"PRIu64, prop->values[i]);
123b8e80941Smrg		printf("\n");
124b8e80941Smrg	}
125b8e80941Smrg
126b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) {
127b8e80941Smrg		printf("\t\tenums:");
128b8e80941Smrg		for (i = 0; i < prop->count_enums; i++)
129b8e80941Smrg			printf(" %s=%llu", prop->enums[i].name,
130b8e80941Smrg			       prop->enums[i].value);
131b8e80941Smrg		printf("\n");
132b8e80941Smrg	} else if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) {
133b8e80941Smrg		printf("\t\tvalues:");
134b8e80941Smrg		for (i = 0; i < prop->count_enums; i++)
135b8e80941Smrg			printf(" %s=0x%llx", prop->enums[i].name,
136b8e80941Smrg			       (1LL << prop->enums[i].value));
137b8e80941Smrg		printf("\n");
138b8e80941Smrg	} else {
139b8e80941Smrg		assert(prop->count_enums == 0);
140b8e80941Smrg	}
141b8e80941Smrg
142b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) {
143b8e80941Smrg		printf("\t\tblobs:\n");
144b8e80941Smrg		for (i = 0; i < prop->count_blobs; i++)
145b8e80941Smrg			dump_blob(prop->blob_ids[i]);
146b8e80941Smrg		printf("\n");
147b8e80941Smrg	} else {
148b8e80941Smrg		assert(prop->count_blobs == 0);
149b8e80941Smrg	}
150b8e80941Smrg
151b8e80941Smrg	printf("\t\tvalue:");
152b8e80941Smrg	if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB))
153b8e80941Smrg		dump_blob(value);
154b8e80941Smrg	else if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE))
155b8e80941Smrg		printf(" %"PRId64"\n", value);
156b8e80941Smrg	else
157b8e80941Smrg		printf(" %"PRIu64"\n", value);
158b8e80941Smrg
159b8e80941Smrg	drmModeFreeProperty(prop);
160b8e80941Smrg}
161b8e80941Smrg
162b8e80941Smrgstatic void listObjectProperties(uint32_t id, uint32_t type)
163b8e80941Smrg{
164b8e80941Smrg	unsigned int i;
165b8e80941Smrg	drmModeObjectPropertiesPtr props;
166b8e80941Smrg
167b8e80941Smrg	props = drmModeObjectGetProperties(fd, id, type);
168b8e80941Smrg
169b8e80941Smrg	if (!props) {
170b8e80941Smrg		printf("\tNo properties: %s.\n", strerror(errno));
171b8e80941Smrg		return;
172b8e80941Smrg	}
173b8e80941Smrg
174b8e80941Smrg	for (i = 0; i < props->count_props; i++)
175b8e80941Smrg		dump_prop(props->props[i], props->prop_values[i]);
176b8e80941Smrg
177b8e80941Smrg	drmModeFreeObjectProperties(props);
178b8e80941Smrg}
179b8e80941Smrg
180b8e80941Smrgstatic void listConnectorProperties(void)
181b8e80941Smrg{
182b8e80941Smrg	int i;
183b8e80941Smrg	drmModeConnectorPtr c;
184b8e80941Smrg
185b8e80941Smrg	for (i = 0; i < res->count_connectors; i++) {
186b8e80941Smrg		c = drmModeGetConnector(fd, res->connectors[i]);
187b8e80941Smrg
188b8e80941Smrg		if (!c) {
189b8e80941Smrg			fprintf(stderr, "Could not get connector %u: %s\n",
190b8e80941Smrg				res->connectors[i], strerror(errno));
191b8e80941Smrg			continue;
192b8e80941Smrg		}
193b8e80941Smrg
194b8e80941Smrg		printf("Connector %u (%s-%u)\n", c->connector_id,
195b8e80941Smrg		       util_lookup_connector_type_name(c->connector_type),
196b8e80941Smrg		       c->connector_type_id);
197b8e80941Smrg
198b8e80941Smrg		listObjectProperties(c->connector_id,
199b8e80941Smrg				     DRM_MODE_OBJECT_CONNECTOR);
200b8e80941Smrg
201b8e80941Smrg		drmModeFreeConnector(c);
202b8e80941Smrg	}
203b8e80941Smrg}
204b8e80941Smrg
205b8e80941Smrgstatic void listCrtcProperties(void)
206b8e80941Smrg{
207b8e80941Smrg	int i;
208b8e80941Smrg	drmModeCrtcPtr c;
209b8e80941Smrg
210b8e80941Smrg	for (i = 0; i < res->count_crtcs; i++) {
211b8e80941Smrg		c = drmModeGetCrtc(fd, res->crtcs[i]);
212b8e80941Smrg
213b8e80941Smrg		if (!c) {
214b8e80941Smrg			fprintf(stderr, "Could not get crtc %u: %s\n",
215b8e80941Smrg				res->crtcs[i], strerror(errno));
216b8e80941Smrg			continue;
217b8e80941Smrg		}
218b8e80941Smrg
219b8e80941Smrg		printf("CRTC %u\n", c->crtc_id);
220b8e80941Smrg
221b8e80941Smrg		listObjectProperties(c->crtc_id, DRM_MODE_OBJECT_CRTC);
222b8e80941Smrg
223b8e80941Smrg		drmModeFreeCrtc(c);
224b8e80941Smrg	}
225b8e80941Smrg}
226b8e80941Smrg
227b8e80941Smrgstatic void listAllProperties(void)
228b8e80941Smrg{
229b8e80941Smrg	listConnectorProperties();
230b8e80941Smrg	listCrtcProperties();
231b8e80941Smrg}
232b8e80941Smrg
233b8e80941Smrgstatic int setProperty(char *argv[])
234b8e80941Smrg{
235b8e80941Smrg	uint32_t obj_id, obj_type, prop_id;
236b8e80941Smrg	uint64_t value;
237b8e80941Smrg
238b8e80941Smrg	obj_id = atoi(argv[0]);
239b8e80941Smrg
240b8e80941Smrg	if (!strcmp(argv[1], "connector")) {
241b8e80941Smrg		obj_type = DRM_MODE_OBJECT_CONNECTOR;
242b8e80941Smrg	} else if (!strcmp(argv[1], "crtc")) {
243b8e80941Smrg		obj_type = DRM_MODE_OBJECT_CRTC;
244b8e80941Smrg	} else {
245b8e80941Smrg		fprintf(stderr, "Invalid object type.\n");
246b8e80941Smrg		return 1;
247b8e80941Smrg	}
248b8e80941Smrg
249b8e80941Smrg	prop_id = atoi(argv[2]);
250b8e80941Smrg	value = atoll(argv[3]);
251b8e80941Smrg
252b8e80941Smrg	return drmModeObjectSetProperty(fd, obj_id, obj_type, prop_id, value);
253b8e80941Smrg}
254b8e80941Smrg
255b8e80941Smrgstatic void usage(const char *program)
256b8e80941Smrg{
257b8e80941Smrg	printf("Usage:\n"
258b8e80941Smrg"  %s [options]\n"
259b8e80941Smrg"  %s [options] [obj id] [obj type] [prop id] [value]\n"
260b8e80941Smrg"\n"
261b8e80941Smrg"options:\n"
262b8e80941Smrg"  -D DEVICE  use the given device\n"
263b8e80941Smrg"  -M MODULE  use the given driver\n"
264b8e80941Smrg"\n"
265b8e80941Smrg"The first form just prints all the existing properties. The second one is\n"
266b8e80941Smrg"used to set the value of a specified property. The object type can be one of\n"
267b8e80941Smrg"the following strings:\n"
268b8e80941Smrg"  connector crtc\n"
269b8e80941Smrg"\n"
270b8e80941Smrg"Example:\n"
271b8e80941Smrg"  proptest 7 connector 2 1\n"
272b8e80941Smrg"will set property 2 of connector 7 to 1\n", program, program);
273b8e80941Smrg}
274b8e80941Smrg
275b8e80941Smrgint main(int argc, char *argv[])
276b8e80941Smrg{
277b8e80941Smrg	static const char optstr[] = "D:M:";
278b8e80941Smrg	int c, args, ret = 0;
279b8e80941Smrg	char *device = NULL;
280b8e80941Smrg	char *module = NULL;
281b8e80941Smrg
282b8e80941Smrg	while ((c = getopt(argc, argv, optstr)) != -1) {
283b8e80941Smrg		switch (c) {
284b8e80941Smrg		case 'D':
285b8e80941Smrg			device = optarg;
286b8e80941Smrg			break;
287b8e80941Smrg
288b8e80941Smrg		case 'M':
289b8e80941Smrg			module = optarg;
290b8e80941Smrg			break;
291b8e80941Smrg
292b8e80941Smrg		default:
293b8e80941Smrg			usage(argv[0]);
294b8e80941Smrg			break;
295b8e80941Smrg		}
296b8e80941Smrg	}
297b8e80941Smrg
298b8e80941Smrg	args = argc - optind;
299b8e80941Smrg
300b8e80941Smrg	fd = util_open(device, module);
301b8e80941Smrg	if (fd < 0)
302b8e80941Smrg		return 1;
303b8e80941Smrg
304b8e80941Smrg	res = drmModeGetResources(fd);
305b8e80941Smrg	if (!res) {
306b8e80941Smrg		fprintf(stderr, "Failed to get resources: %s\n",
307b8e80941Smrg			strerror(errno));
308b8e80941Smrg		ret = 1;
309		goto done;
310	}
311
312	if (args < 1) {
313		listAllProperties();
314	} else if (args == 4) {
315		ret = setProperty(&argv[optind]);
316	} else {
317		usage(argv[0]);
318		ret = 1;
319	}
320
321	drmModeFreeResources(res);
322done:
323	drmClose(fd);
324	return ret;
325}
326