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@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 42static inline int64_t U642I64(uint64_t val) 43{ 44 return (int64_t)*((int64_t *)&val); 45} 46 47int fd; 48drmModeResPtr res = NULL; 49 50/* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */ 51static void 52dump_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 76static void 77dump_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 155 printf(" %"PRIu64"\n", value); 156 157 drmModeFreeProperty(prop); 158} 159 160static void listObjectProperties(uint32_t id, uint32_t type) 161{ 162 unsigned int i; 163 drmModeObjectPropertiesPtr props; 164 165 props = drmModeObjectGetProperties(fd, id, type); 166 167 if (!props) { 168 printf("\tNo properties: %s.\n", strerror(errno)); 169 return; 170 } 171 172 for (i = 0; i < props->count_props; i++) 173 dump_prop(props->props[i], props->prop_values[i]); 174 175 drmModeFreeObjectProperties(props); 176} 177 178static void listConnectorProperties(void) 179{ 180 int i; 181 drmModeConnectorPtr c; 182 183 for (i = 0; i < res->count_connectors; i++) { 184 c = drmModeGetConnector(fd, res->connectors[i]); 185 186 if (!c) { 187 fprintf(stderr, "Could not get connector %u: %s\n", 188 res->connectors[i], strerror(errno)); 189 continue; 190 } 191 192 printf("Connector %u (%s-%u)\n", c->connector_id, 193 util_lookup_connector_type_name(c->connector_type), 194 c->connector_type_id); 195 196 listObjectProperties(c->connector_id, 197 DRM_MODE_OBJECT_CONNECTOR); 198 199 drmModeFreeConnector(c); 200 } 201} 202 203static void listCrtcProperties(void) 204{ 205 int i; 206 drmModeCrtcPtr c; 207 208 for (i = 0; i < res->count_crtcs; i++) { 209 c = drmModeGetCrtc(fd, res->crtcs[i]); 210 211 if (!c) { 212 fprintf(stderr, "Could not get crtc %u: %s\n", 213 res->crtcs[i], strerror(errno)); 214 continue; 215 } 216 217 printf("CRTC %u\n", c->crtc_id); 218 219 listObjectProperties(c->crtc_id, DRM_MODE_OBJECT_CRTC); 220 221 drmModeFreeCrtc(c); 222 } 223} 224 225static void listAllProperties(void) 226{ 227 listConnectorProperties(); 228 listCrtcProperties(); 229} 230 231static int setProperty(char *argv[]) 232{ 233 uint32_t obj_id, obj_type, prop_id; 234 uint64_t value; 235 236 obj_id = atoi(argv[0]); 237 238 if (!strcmp(argv[1], "connector")) { 239 obj_type = DRM_MODE_OBJECT_CONNECTOR; 240 } else if (!strcmp(argv[1], "crtc")) { 241 obj_type = DRM_MODE_OBJECT_CRTC; 242 } else { 243 fprintf(stderr, "Invalid object type.\n"); 244 return 1; 245 } 246 247 prop_id = atoi(argv[2]); 248 value = atoll(argv[3]); 249 250 return drmModeObjectSetProperty(fd, obj_id, obj_type, prop_id, value); 251} 252 253static void usage(const char *program) 254{ 255 printf("Usage:\n" 256" %s [options]\n" 257" %s [options] [obj id] [obj type] [prop id] [value]\n" 258"\n" 259"options:\n" 260" -D DEVICE use the given device\n" 261" -M MODULE use the given driver\n" 262"\n" 263"The first form just prints all the existing properties. The second one is\n" 264"used to set the value of a specified property. The object type can be one of\n" 265"the following strings:\n" 266" connector crtc\n" 267"\n" 268"Example:\n" 269" proptest 7 connector 2 1\n" 270"will set property 2 of connector 7 to 1\n", program, program); 271} 272 273int main(int argc, char *argv[]) 274{ 275 static const char optstr[] = "D:M:"; 276 int c, args, ret = 0; 277 char *device = NULL; 278 char *module = NULL; 279 280 while ((c = getopt(argc, argv, optstr)) != -1) { 281 switch (c) { 282 case 'D': 283 device = optarg; 284 break; 285 286 case 'M': 287 module = optarg; 288 break; 289 290 default: 291 usage(argv[0]); 292 break; 293 } 294 } 295 296 args = argc - optind; 297 298 fd = util_open(module, device); 299 if (fd < 0) 300 return 1; 301 302 res = drmModeGetResources(fd); 303 if (!res) { 304 fprintf(stderr, "Failed to get resources: %s\n", 305 strerror(errno)); 306 ret = 1; 307 goto done; 308 } 309 310 if (args < 1) { 311 listAllProperties(); 312 } else if (args == 4) { 313 ret = setProperty(&argv[optind]); 314 } else { 315 usage(argv[0]); 316 ret = 1; 317 } 318 319 drmModeFreeResources(res); 320done: 321 drmClose(fd); 322 return ret; 323} 324