18f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni/*
28f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * Copyright © 2012 Intel Corporation
38f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni *
48f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * Permission is hereby granted, free of charge, to any person obtaining a
58f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * copy of this software and associated documentation files (the "Software"),
68f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * to deal in the Software without restriction, including without limitation
78f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * and/or sell copies of the Software, and to permit persons to whom the
98f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * Software is furnished to do so, subject to the following conditions:
108f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni *
118f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * The above copyright notice and this permission notice (including the next
128f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * paragraph) shall be included in all copies or substantial portions of the
138f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * Software.
148f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni *
158f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
178f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
188f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
208f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
218f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * IN THE SOFTWARE.
228f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni *
238f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni * Authors:
248f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni *    Paulo Zanoni <paulo.r.zanoni@intel.com>
258f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni *
268f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni */
278f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
288f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#include <assert.h>
298f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#include <errno.h>
308f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#include <inttypes.h>
318f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#include <stdlib.h>
328f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#include <stdio.h>
338f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#include <string.h>
348f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
358f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#include "xf86drm.h"
368f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#include "xf86drmMode.h"
378f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
388f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
39fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clarkstatic inline int64_t U642I64(uint64_t val)
40fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark{
41fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	return (int64_t)*((int64_t *)&val);
42fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark}
438f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
448f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoniint fd;
458f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo ZanonidrmModeResPtr res = NULL;
468f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
478f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoniconst char *connector_type_str(uint32_t type)
488f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
498f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	switch (type) {
508f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_Unknown:
518f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "Unknown";
528f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_VGA:
538f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "VGA";
548f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_DVII:
558f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "DVI-I";
568f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_DVID:
578f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "DVI-D";
588f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_DVIA:
598f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "DVI-A";
608f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_Composite:
618f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "Composite";
628f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_SVIDEO:
638f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "SVIDEO";
648f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_LVDS:
658f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "LVDS";
668f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_Component:
678f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "Component";
688f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_9PinDIN:
698f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "9PinDin";
708f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_DisplayPort:
718f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "DisplayPort";
728f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_HDMIA:
738f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "HDMI-A";
748f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_HDMIB:
758f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "HDMI-B";
768f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_TV:
778f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "TV";
788f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	case DRM_MODE_CONNECTOR_eDP:
798f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "eDP";
808f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	default:
818f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return "Invalid";
828f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
838f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
848f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
858f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni/* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */
868f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonistatic void
878f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonidump_blob(uint32_t blob_id)
888f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
898f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	uint32_t i;
908f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	unsigned char *blob_data;
918f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModePropertyBlobPtr blob;
928f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
938f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	blob = drmModeGetPropertyBlob(fd, blob_id);
94fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (!blob) {
95fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf("\n");
968f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return;
97fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	}
988f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
998f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	blob_data = blob->data;
1008f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1018f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	for (i = 0; i < blob->length; i++) {
1028f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		if (i % 16 == 0)
1038f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			printf("\n\t\t\t");
1048f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("%.2hhx", blob_data[i]);
1058f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
1068f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	printf("\n");
1078f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1088f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModeFreePropertyBlob(blob);
1098f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
1108f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1118f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonistatic void
1128f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonidump_prop(uint32_t prop_id, uint64_t value)
1138f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
1148f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	int i;
1158f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModePropertyPtr prop;
1168f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1178f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	prop = drmModeGetProperty(fd, prop_id);
1188f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1198f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	printf("\t%d", prop_id);
1208f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	if (!prop) {
1218f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("\n");
1228f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return;
1238f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
1248f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1258f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	printf(" %s:\n", prop->name);
1268f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1278f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	printf("\t\tflags:");
1288f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_PENDING)
1298f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf(" pending");
1308f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	if (prop->flags & DRM_MODE_PROP_IMMUTABLE)
1318f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf(" immutable");
132fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE))
133fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf(" signed range");
134fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE))
135fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf(" range");
136fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM))
1378f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf(" enum");
138fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK))
139fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf(" bitmask");
140fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB))
1418f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf(" blob");
142fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_OBJECT))
143fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf(" object");
1448f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	printf("\n");
1458f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
146fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark
147fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) {
148fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf("\t\tvalues:");
149fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		for (i = 0; i < prop->count_values; i++)
150fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark			printf(" %"PRId64, U642I64(prop->values[i]));
151fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf("\n");
152fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	}
153fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark
154fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) {
1558f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("\t\tvalues:");
1568f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		for (i = 0; i < prop->count_values; i++)
1578f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			printf(" %"PRIu64, prop->values[i]);
1588f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("\n");
1598f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
1608f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
161fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) {
1628f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("\t\tenums:");
1638f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		for (i = 0; i < prop->count_enums; i++)
1648f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			printf(" %s=%llu", prop->enums[i].name,
1658f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			       prop->enums[i].value);
1668f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("\n");
167fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	} else if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) {
168fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf("\t\tvalues:");
169fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		for (i = 0; i < prop->count_enums; i++)
170fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark			printf(" %s=0x%llx", prop->enums[i].name,
171fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark			       (1LL << prop->enums[i].value));
172fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark		printf("\n");
1738f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	} else {
1748f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		assert(prop->count_enums == 0);
1758f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
1768f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
177fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) {
1788f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("\t\tblobs:\n");
1798f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		for (i = 0; i < prop->count_blobs; i++)
1808f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			dump_blob(prop->blob_ids[i]);
1818f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("\n");
1828f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	} else {
1838f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		assert(prop->count_blobs == 0);
1848f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
1858f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1868f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	printf("\t\tvalue:");
187fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark	if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB))
1888f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		dump_blob(value);
1898f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	else
1908f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf(" %"PRIu64"\n", value);
1918f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1928f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModeFreeProperty(prop);
1938f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
1948f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
1958f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonistatic void listObjectProperties(uint32_t id, uint32_t type)
1968f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
1978f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	unsigned int i;
1988f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModeObjectPropertiesPtr props;
1998f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2008f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	props = drmModeObjectGetProperties(fd, id, type);
2018f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2028f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	if (!props) {
2038f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("\tNo properties: %s.\n", strerror(errno));
2048f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return;
2058f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
2068f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2078f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	for (i = 0; i < props->count_props; i++)
2088f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		dump_prop(props->props[i], props->prop_values[i]);
2098f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2108f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModeFreeObjectProperties(props);
2118f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
2128f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2138f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonistatic void listConnectorProperties(void)
2148f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
2158f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	int i;
2168f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModeConnectorPtr c;
2178f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2188f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	for (i = 0; i < res->count_connectors; i++) {
2198f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		c = drmModeGetConnector(fd, res->connectors[i]);
2208f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2218f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		if (!c) {
2228f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			fprintf(stderr, "Could not get connector %u: %s\n",
2238f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni				res->connectors[i], strerror(errno));
2248f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			continue;
2258f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		}
2268f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2278f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("Connector %u (%s-%u)\n", c->connector_id,
2288f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		       connector_type_str(c->connector_type),
2298f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		       c->connector_type_id);
2308f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2318f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		listObjectProperties(c->connector_id,
2328f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni				     DRM_MODE_OBJECT_CONNECTOR);
2338f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2348f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		drmModeFreeConnector(c);
2358f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
2368f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
2378f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2388f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonistatic void listCrtcProperties(void)
2398f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
2408f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	int i;
2418f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModeCrtcPtr c;
2428f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2438f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	for (i = 0; i < res->count_crtcs; i++) {
2448f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		c = drmModeGetCrtc(fd, res->crtcs[i]);
2458f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2468f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		if (!c) {
2478f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			fprintf(stderr, "Could not get crtc %u: %s\n",
2488f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni				res->crtcs[i], strerror(errno));
2498f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			continue;
2508f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		}
2518f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2528f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printf("CRTC %u\n", c->crtc_id);
2538f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2548f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		listObjectProperties(c->crtc_id, DRM_MODE_OBJECT_CRTC);
2558f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2568f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		drmModeFreeCrtc(c);
2578f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
2588f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
2598f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2608f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonistatic void listAllProperties(void)
2618f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
2628f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	listConnectorProperties();
2638f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	listCrtcProperties();
2648f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
2658f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2668f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonistatic int setProperty(char *argv[])
2678f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
2688f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	uint32_t obj_id, obj_type, prop_id;
2698f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	uint64_t value;
2708f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2718f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	obj_id = atoi(argv[1]);
2728f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2738f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	if (!strcmp(argv[2], "connector")) {
2748f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		obj_type = DRM_MODE_OBJECT_CONNECTOR;
2758f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	} else if (!strcmp(argv[2], "crtc")) {
2768f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		obj_type = DRM_MODE_OBJECT_CRTC;
2778f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	} else {
2788f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		fprintf(stderr, "Invalid object type.\n");
2798f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return 1;
2808f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
2818f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2828f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	prop_id = atoi(argv[3]);
2838f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	value = atoll(argv[4]);
2848f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2858f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	return drmModeObjectSetProperty(fd, obj_id, obj_type, prop_id, value);
2868f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
2878f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
2888f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonistatic void printUsage(void)
2898f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
2908f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	printf("Usage:\n"
2918f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"  proptest\n"
2928f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"  proptest [obj id] [obj type] [prop id] [value]\n"
2938f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"\n"
2948f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"The first form just prints all the existing properties. The second one is\n"
2958f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"used to set the value of a specified property. The object type can be one of\n"
2968f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"the following strings:\n"
2978f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"  connector crtc\n"
2988f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"\n"
2998f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"Example:\n"
3008f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"  proptest 7 connector 2 1\n"
3018f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni"will set property 2 of connector 7 to 1\n");
3028f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
3038f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
3048f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoniint main(int argc, char *argv[])
3058f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni{
3068f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "msm" };
3078f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	unsigned int i, ret = 0;
3088f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
3098f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	for (i = 0; i < ARRAY_SIZE(modules); i++){
3108f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		fd = drmOpen(modules[i], NULL);
3118f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		if (fd >= 0) {
3128f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			printf("Module %s loaded.\n", modules[i]);
3138f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			break;
3148f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		}
3158f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
3168f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
3178f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	if (i == ARRAY_SIZE(modules)) {
3188f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		fprintf(stderr, "Failed to load drm modules.\n");
3198f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		return 1;
3208f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
3218f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
3228f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	res = drmModeGetResources(fd);
3238f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	if (!res) {
3248f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		fprintf(stderr, "Failed to get resources: %s\n",
3258f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni			strerror(errno));
3268f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		ret = 1;
3278f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		goto done;
3288f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
3298f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
3308f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	if (argc < 2) {
3318f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		listAllProperties();
3328f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	} else if (argc == 5) {
3338f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		ret = setProperty(argv);
3348f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	} else {
3358f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		printUsage();
3368f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni		ret = 1;
3378f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	}
3388f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni
3398f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmModeFreeResources(res);
3408f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanonidone:
3418f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	drmClose(fd);
3428f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni	return ret;
3438f66c98818102b95c28320b9ed7b5e05fd4efa00Paulo Zanoni}
344