proptest.c revision 08d7334d
108d7334dSsnj/* 208d7334dSsnj * Copyright © 2012 Intel Corporation 308d7334dSsnj * 408d7334dSsnj * Permission is hereby granted, free of charge, to any person obtaining a 508d7334dSsnj * copy of this software and associated documentation files (the "Software"), 608d7334dSsnj * to deal in the Software without restriction, including without limitation 708d7334dSsnj * the rights to use, copy, modify, merge, publish, distribute, sublicense, 808d7334dSsnj * and/or sell copies of the Software, and to permit persons to whom the 908d7334dSsnj * Software is furnished to do so, subject to the following conditions: 1008d7334dSsnj * 1108d7334dSsnj * The above copyright notice and this permission notice (including the next 1208d7334dSsnj * paragraph) shall be included in all copies or substantial portions of the 1308d7334dSsnj * Software. 1408d7334dSsnj * 1508d7334dSsnj * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1608d7334dSsnj * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1708d7334dSsnj * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1808d7334dSsnj * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1908d7334dSsnj * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2008d7334dSsnj * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2108d7334dSsnj * IN THE SOFTWARE. 2208d7334dSsnj * 2308d7334dSsnj * Authors: 2408d7334dSsnj * Paulo Zanoni <paulo.r.zanoni@intel.com> 2508d7334dSsnj * 2608d7334dSsnj */ 2708d7334dSsnj 2808d7334dSsnj#include <assert.h> 2908d7334dSsnj#include <errno.h> 3008d7334dSsnj#include <inttypes.h> 3108d7334dSsnj#include <stdlib.h> 3208d7334dSsnj#include <stdio.h> 3308d7334dSsnj#include <string.h> 3408d7334dSsnj 3508d7334dSsnj#include "xf86drm.h" 3608d7334dSsnj#include "xf86drmMode.h" 3708d7334dSsnj 3808d7334dSsnj#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 3908d7334dSsnjstatic inline int64_t U642I64(uint64_t val) 4008d7334dSsnj{ 4108d7334dSsnj return (int64_t)*((int64_t *)&val); 4208d7334dSsnj} 4308d7334dSsnj 4408d7334dSsnjint fd; 4508d7334dSsnjdrmModeResPtr res = NULL; 4608d7334dSsnj 4708d7334dSsnjconst char *connector_type_str(uint32_t type) 4808d7334dSsnj{ 4908d7334dSsnj switch (type) { 5008d7334dSsnj case DRM_MODE_CONNECTOR_Unknown: 5108d7334dSsnj return "Unknown"; 5208d7334dSsnj case DRM_MODE_CONNECTOR_VGA: 5308d7334dSsnj return "VGA"; 5408d7334dSsnj case DRM_MODE_CONNECTOR_DVII: 5508d7334dSsnj return "DVI-I"; 5608d7334dSsnj case DRM_MODE_CONNECTOR_DVID: 5708d7334dSsnj return "DVI-D"; 5808d7334dSsnj case DRM_MODE_CONNECTOR_DVIA: 5908d7334dSsnj return "DVI-A"; 6008d7334dSsnj case DRM_MODE_CONNECTOR_Composite: 6108d7334dSsnj return "Composite"; 6208d7334dSsnj case DRM_MODE_CONNECTOR_SVIDEO: 6308d7334dSsnj return "SVIDEO"; 6408d7334dSsnj case DRM_MODE_CONNECTOR_LVDS: 6508d7334dSsnj return "LVDS"; 6608d7334dSsnj case DRM_MODE_CONNECTOR_Component: 6708d7334dSsnj return "Component"; 6808d7334dSsnj case DRM_MODE_CONNECTOR_9PinDIN: 6908d7334dSsnj return "9PinDin"; 7008d7334dSsnj case DRM_MODE_CONNECTOR_DisplayPort: 7108d7334dSsnj return "DisplayPort"; 7208d7334dSsnj case DRM_MODE_CONNECTOR_HDMIA: 7308d7334dSsnj return "HDMI-A"; 7408d7334dSsnj case DRM_MODE_CONNECTOR_HDMIB: 7508d7334dSsnj return "HDMI-B"; 7608d7334dSsnj case DRM_MODE_CONNECTOR_TV: 7708d7334dSsnj return "TV"; 7808d7334dSsnj case DRM_MODE_CONNECTOR_eDP: 7908d7334dSsnj return "eDP"; 8008d7334dSsnj default: 8108d7334dSsnj return "Invalid"; 8208d7334dSsnj } 8308d7334dSsnj} 8408d7334dSsnj 8508d7334dSsnj/* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */ 8608d7334dSsnjstatic void 8708d7334dSsnjdump_blob(uint32_t blob_id) 8808d7334dSsnj{ 8908d7334dSsnj uint32_t i; 9008d7334dSsnj unsigned char *blob_data; 9108d7334dSsnj drmModePropertyBlobPtr blob; 9208d7334dSsnj 9308d7334dSsnj blob = drmModeGetPropertyBlob(fd, blob_id); 9408d7334dSsnj if (!blob) { 9508d7334dSsnj printf("\n"); 9608d7334dSsnj return; 9708d7334dSsnj } 9808d7334dSsnj 9908d7334dSsnj blob_data = blob->data; 10008d7334dSsnj 10108d7334dSsnj for (i = 0; i < blob->length; i++) { 10208d7334dSsnj if (i % 16 == 0) 10308d7334dSsnj printf("\n\t\t\t"); 10408d7334dSsnj printf("%.2hhx", blob_data[i]); 10508d7334dSsnj } 10608d7334dSsnj printf("\n"); 10708d7334dSsnj 10808d7334dSsnj drmModeFreePropertyBlob(blob); 10908d7334dSsnj} 11008d7334dSsnj 11108d7334dSsnjstatic void 11208d7334dSsnjdump_prop(uint32_t prop_id, uint64_t value) 11308d7334dSsnj{ 11408d7334dSsnj int i; 11508d7334dSsnj drmModePropertyPtr prop; 11608d7334dSsnj 11708d7334dSsnj prop = drmModeGetProperty(fd, prop_id); 11808d7334dSsnj 11908d7334dSsnj printf("\t%d", prop_id); 12008d7334dSsnj if (!prop) { 12108d7334dSsnj printf("\n"); 12208d7334dSsnj return; 12308d7334dSsnj } 12408d7334dSsnj 12508d7334dSsnj printf(" %s:\n", prop->name); 12608d7334dSsnj 12708d7334dSsnj printf("\t\tflags:"); 12808d7334dSsnj if (prop->flags & DRM_MODE_PROP_PENDING) 12908d7334dSsnj printf(" pending"); 13008d7334dSsnj if (prop->flags & DRM_MODE_PROP_IMMUTABLE) 13108d7334dSsnj printf(" immutable"); 13208d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) 13308d7334dSsnj printf(" signed range"); 13408d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) 13508d7334dSsnj printf(" range"); 13608d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) 13708d7334dSsnj printf(" enum"); 13808d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) 13908d7334dSsnj printf(" bitmask"); 14008d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) 14108d7334dSsnj printf(" blob"); 14208d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_OBJECT)) 14308d7334dSsnj printf(" object"); 14408d7334dSsnj printf("\n"); 14508d7334dSsnj 14608d7334dSsnj 14708d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) { 14808d7334dSsnj printf("\t\tvalues:"); 14908d7334dSsnj for (i = 0; i < prop->count_values; i++) 15008d7334dSsnj printf(" %"PRId64, U642I64(prop->values[i])); 15108d7334dSsnj printf("\n"); 15208d7334dSsnj } 15308d7334dSsnj 15408d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) { 15508d7334dSsnj printf("\t\tvalues:"); 15608d7334dSsnj for (i = 0; i < prop->count_values; i++) 15708d7334dSsnj printf(" %"PRIu64, prop->values[i]); 15808d7334dSsnj printf("\n"); 15908d7334dSsnj } 16008d7334dSsnj 16108d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) { 16208d7334dSsnj printf("\t\tenums:"); 16308d7334dSsnj for (i = 0; i < prop->count_enums; i++) 16408d7334dSsnj printf(" %s=%llu", prop->enums[i].name, 16508d7334dSsnj prop->enums[i].value); 16608d7334dSsnj printf("\n"); 16708d7334dSsnj } else if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) { 16808d7334dSsnj printf("\t\tvalues:"); 16908d7334dSsnj for (i = 0; i < prop->count_enums; i++) 17008d7334dSsnj printf(" %s=0x%llx", prop->enums[i].name, 17108d7334dSsnj (1LL << prop->enums[i].value)); 17208d7334dSsnj printf("\n"); 17308d7334dSsnj } else { 17408d7334dSsnj assert(prop->count_enums == 0); 17508d7334dSsnj } 17608d7334dSsnj 17708d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) { 17808d7334dSsnj printf("\t\tblobs:\n"); 17908d7334dSsnj for (i = 0; i < prop->count_blobs; i++) 18008d7334dSsnj dump_blob(prop->blob_ids[i]); 18108d7334dSsnj printf("\n"); 18208d7334dSsnj } else { 18308d7334dSsnj assert(prop->count_blobs == 0); 18408d7334dSsnj } 18508d7334dSsnj 18608d7334dSsnj printf("\t\tvalue:"); 18708d7334dSsnj if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) 18808d7334dSsnj dump_blob(value); 18908d7334dSsnj else 19008d7334dSsnj printf(" %"PRIu64"\n", value); 19108d7334dSsnj 19208d7334dSsnj drmModeFreeProperty(prop); 19308d7334dSsnj} 19408d7334dSsnj 19508d7334dSsnjstatic void listObjectProperties(uint32_t id, uint32_t type) 19608d7334dSsnj{ 19708d7334dSsnj unsigned int i; 19808d7334dSsnj drmModeObjectPropertiesPtr props; 19908d7334dSsnj 20008d7334dSsnj props = drmModeObjectGetProperties(fd, id, type); 20108d7334dSsnj 20208d7334dSsnj if (!props) { 20308d7334dSsnj printf("\tNo properties: %s.\n", strerror(errno)); 20408d7334dSsnj return; 20508d7334dSsnj } 20608d7334dSsnj 20708d7334dSsnj for (i = 0; i < props->count_props; i++) 20808d7334dSsnj dump_prop(props->props[i], props->prop_values[i]); 20908d7334dSsnj 21008d7334dSsnj drmModeFreeObjectProperties(props); 21108d7334dSsnj} 21208d7334dSsnj 21308d7334dSsnjstatic void listConnectorProperties(void) 21408d7334dSsnj{ 21508d7334dSsnj int i; 21608d7334dSsnj drmModeConnectorPtr c; 21708d7334dSsnj 21808d7334dSsnj for (i = 0; i < res->count_connectors; i++) { 21908d7334dSsnj c = drmModeGetConnector(fd, res->connectors[i]); 22008d7334dSsnj 22108d7334dSsnj if (!c) { 22208d7334dSsnj fprintf(stderr, "Could not get connector %u: %s\n", 22308d7334dSsnj res->connectors[i], strerror(errno)); 22408d7334dSsnj continue; 22508d7334dSsnj } 22608d7334dSsnj 22708d7334dSsnj printf("Connector %u (%s-%u)\n", c->connector_id, 22808d7334dSsnj connector_type_str(c->connector_type), 22908d7334dSsnj c->connector_type_id); 23008d7334dSsnj 23108d7334dSsnj listObjectProperties(c->connector_id, 23208d7334dSsnj DRM_MODE_OBJECT_CONNECTOR); 23308d7334dSsnj 23408d7334dSsnj drmModeFreeConnector(c); 23508d7334dSsnj } 23608d7334dSsnj} 23708d7334dSsnj 23808d7334dSsnjstatic void listCrtcProperties(void) 23908d7334dSsnj{ 24008d7334dSsnj int i; 24108d7334dSsnj drmModeCrtcPtr c; 24208d7334dSsnj 24308d7334dSsnj for (i = 0; i < res->count_crtcs; i++) { 24408d7334dSsnj c = drmModeGetCrtc(fd, res->crtcs[i]); 24508d7334dSsnj 24608d7334dSsnj if (!c) { 24708d7334dSsnj fprintf(stderr, "Could not get crtc %u: %s\n", 24808d7334dSsnj res->crtcs[i], strerror(errno)); 24908d7334dSsnj continue; 25008d7334dSsnj } 25108d7334dSsnj 25208d7334dSsnj printf("CRTC %u\n", c->crtc_id); 25308d7334dSsnj 25408d7334dSsnj listObjectProperties(c->crtc_id, DRM_MODE_OBJECT_CRTC); 25508d7334dSsnj 25608d7334dSsnj drmModeFreeCrtc(c); 25708d7334dSsnj } 25808d7334dSsnj} 25908d7334dSsnj 26008d7334dSsnjstatic void listAllProperties(void) 26108d7334dSsnj{ 26208d7334dSsnj listConnectorProperties(); 26308d7334dSsnj listCrtcProperties(); 26408d7334dSsnj} 26508d7334dSsnj 26608d7334dSsnjstatic int setProperty(char *argv[]) 26708d7334dSsnj{ 26808d7334dSsnj uint32_t obj_id, obj_type, prop_id; 26908d7334dSsnj uint64_t value; 27008d7334dSsnj 27108d7334dSsnj obj_id = atoi(argv[1]); 27208d7334dSsnj 27308d7334dSsnj if (!strcmp(argv[2], "connector")) { 27408d7334dSsnj obj_type = DRM_MODE_OBJECT_CONNECTOR; 27508d7334dSsnj } else if (!strcmp(argv[2], "crtc")) { 27608d7334dSsnj obj_type = DRM_MODE_OBJECT_CRTC; 27708d7334dSsnj } else { 27808d7334dSsnj fprintf(stderr, "Invalid object type.\n"); 27908d7334dSsnj return 1; 28008d7334dSsnj } 28108d7334dSsnj 28208d7334dSsnj prop_id = atoi(argv[3]); 28308d7334dSsnj value = atoll(argv[4]); 28408d7334dSsnj 28508d7334dSsnj return drmModeObjectSetProperty(fd, obj_id, obj_type, prop_id, value); 28608d7334dSsnj} 28708d7334dSsnj 28808d7334dSsnjstatic void printUsage(void) 28908d7334dSsnj{ 29008d7334dSsnj printf("Usage:\n" 29108d7334dSsnj" proptest\n" 29208d7334dSsnj" proptest [obj id] [obj type] [prop id] [value]\n" 29308d7334dSsnj"\n" 29408d7334dSsnj"The first form just prints all the existing properties. The second one is\n" 29508d7334dSsnj"used to set the value of a specified property. The object type can be one of\n" 29608d7334dSsnj"the following strings:\n" 29708d7334dSsnj" connector crtc\n" 29808d7334dSsnj"\n" 29908d7334dSsnj"Example:\n" 30008d7334dSsnj" proptest 7 connector 2 1\n" 30108d7334dSsnj"will set property 2 of connector 7 to 1\n"); 30208d7334dSsnj} 30308d7334dSsnj 30408d7334dSsnjint main(int argc, char *argv[]) 30508d7334dSsnj{ 30608d7334dSsnj char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "msm" }; 30708d7334dSsnj unsigned int i, ret = 0; 30808d7334dSsnj 30908d7334dSsnj for (i = 0; i < ARRAY_SIZE(modules); i++){ 31008d7334dSsnj fd = drmOpen(modules[i], NULL); 31108d7334dSsnj if (fd >= 0) { 31208d7334dSsnj printf("Module %s loaded.\n", modules[i]); 31308d7334dSsnj break; 31408d7334dSsnj } 31508d7334dSsnj } 31608d7334dSsnj 31708d7334dSsnj if (i == ARRAY_SIZE(modules)) { 31808d7334dSsnj fprintf(stderr, "Failed to load drm modules.\n"); 31908d7334dSsnj return 1; 32008d7334dSsnj } 32108d7334dSsnj 32208d7334dSsnj res = drmModeGetResources(fd); 32308d7334dSsnj if (!res) { 32408d7334dSsnj fprintf(stderr, "Failed to get resources: %s\n", 32508d7334dSsnj strerror(errno)); 32608d7334dSsnj ret = 1; 32708d7334dSsnj goto done; 32808d7334dSsnj } 32908d7334dSsnj 33008d7334dSsnj if (argc < 2) { 33108d7334dSsnj listAllProperties(); 33208d7334dSsnj } else if (argc == 5) { 33308d7334dSsnj ret = setProperty(argv); 33408d7334dSsnj } else { 33508d7334dSsnj printUsage(); 33608d7334dSsnj ret = 1; 33708d7334dSsnj } 33808d7334dSsnj 33908d7334dSsnj drmModeFreeResources(res); 34008d7334dSsnjdone: 34108d7334dSsnj drmClose(fd); 34208d7334dSsnj return ret; 34308d7334dSsnj} 344