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