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 <inttypes.h> 31 #include <stdlib.h> 32 #include <stdio.h> 33 #include <string.h> 34 35 #include "xf86drm.h" 36 #include "xf86drmMode.h" 37 38 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 39 static inline int64_t U642I64(uint64_t val) 40 { 41 return (int64_t)*((int64_t *)&val); 42 } 43 44 int fd; 45 drmModeResPtr res = NULL; 46 47 const char *connector_type_str(uint32_t type) 48 { 49 switch (type) { 50 case DRM_MODE_CONNECTOR_Unknown: 51 return "Unknown"; 52 case DRM_MODE_CONNECTOR_VGA: 53 return "VGA"; 54 case DRM_MODE_CONNECTOR_DVII: 55 return "DVI-I"; 56 case DRM_MODE_CONNECTOR_DVID: 57 return "DVI-D"; 58 case DRM_MODE_CONNECTOR_DVIA: 59 return "DVI-A"; 60 case DRM_MODE_CONNECTOR_Composite: 61 return "Composite"; 62 case DRM_MODE_CONNECTOR_SVIDEO: 63 return "SVIDEO"; 64 case DRM_MODE_CONNECTOR_LVDS: 65 return "LVDS"; 66 case DRM_MODE_CONNECTOR_Component: 67 return "Component"; 68 case DRM_MODE_CONNECTOR_9PinDIN: 69 return "9PinDin"; 70 case DRM_MODE_CONNECTOR_DisplayPort: 71 return "DisplayPort"; 72 case DRM_MODE_CONNECTOR_HDMIA: 73 return "HDMI-A"; 74 case DRM_MODE_CONNECTOR_HDMIB: 75 return "HDMI-B"; 76 case DRM_MODE_CONNECTOR_TV: 77 return "TV"; 78 case DRM_MODE_CONNECTOR_eDP: 79 return "eDP"; 80 default: 81 return "Invalid"; 82 } 83 } 84 85 /* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */ 86 static void 87 dump_blob(uint32_t blob_id) 88 { 89 uint32_t i; 90 unsigned char *blob_data; 91 drmModePropertyBlobPtr blob; 92 93 blob = drmModeGetPropertyBlob(fd, blob_id); 94 if (!blob) { 95 printf("\n"); 96 return; 97 } 98 99 blob_data = blob->data; 100 101 for (i = 0; i < blob->length; i++) { 102 if (i % 16 == 0) 103 printf("\n\t\t\t"); 104 printf("%.2hhx", blob_data[i]); 105 } 106 printf("\n"); 107 108 drmModeFreePropertyBlob(blob); 109 } 110 111 static void 112 dump_prop(uint32_t prop_id, uint64_t value) 113 { 114 int i; 115 drmModePropertyPtr prop; 116 117 prop = drmModeGetProperty(fd, prop_id); 118 119 printf("\t%d", prop_id); 120 if (!prop) { 121 printf("\n"); 122 return; 123 } 124 125 printf(" %s:\n", prop->name); 126 127 printf("\t\tflags:"); 128 if (prop->flags & DRM_MODE_PROP_PENDING) 129 printf(" pending"); 130 if (prop->flags & DRM_MODE_PROP_IMMUTABLE) 131 printf(" immutable"); 132 if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) 133 printf(" signed range"); 134 if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) 135 printf(" range"); 136 if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) 137 printf(" enum"); 138 if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) 139 printf(" bitmask"); 140 if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) 141 printf(" blob"); 142 if (drm_property_type_is(prop, DRM_MODE_PROP_OBJECT)) 143 printf(" object"); 144 printf("\n"); 145 146 147 if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) { 148 printf("\t\tvalues:"); 149 for (i = 0; i < prop->count_values; i++) 150 printf(" %"PRId64, U642I64(prop->values[i])); 151 printf("\n"); 152 } 153 154 if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) { 155 printf("\t\tvalues:"); 156 for (i = 0; i < prop->count_values; i++) 157 printf(" %"PRIu64, prop->values[i]); 158 printf("\n"); 159 } 160 161 if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) { 162 printf("\t\tenums:"); 163 for (i = 0; i < prop->count_enums; i++) 164 printf(" %s=%llu", prop->enums[i].name, 165 prop->enums[i].value); 166 printf("\n"); 167 } else if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) { 168 printf("\t\tvalues:"); 169 for (i = 0; i < prop->count_enums; i++) 170 printf(" %s=0x%llx", prop->enums[i].name, 171 (1LL << prop->enums[i].value)); 172 printf("\n"); 173 } else { 174 assert(prop->count_enums == 0); 175 } 176 177 if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) { 178 printf("\t\tblobs:\n"); 179 for (i = 0; i < prop->count_blobs; i++) 180 dump_blob(prop->blob_ids[i]); 181 printf("\n"); 182 } else { 183 assert(prop->count_blobs == 0); 184 } 185 186 printf("\t\tvalue:"); 187 if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) 188 dump_blob(value); 189 else 190 printf(" %"PRIu64"\n", value); 191 192 drmModeFreeProperty(prop); 193 } 194 195 static void listObjectProperties(uint32_t id, uint32_t type) 196 { 197 unsigned int i; 198 drmModeObjectPropertiesPtr props; 199 200 props = drmModeObjectGetProperties(fd, id, type); 201 202 if (!props) { 203 printf("\tNo properties: %s.\n", strerror(errno)); 204 return; 205 } 206 207 for (i = 0; i < props->count_props; i++) 208 dump_prop(props->props[i], props->prop_values[i]); 209 210 drmModeFreeObjectProperties(props); 211 } 212 213 static void listConnectorProperties(void) 214 { 215 int i; 216 drmModeConnectorPtr c; 217 218 for (i = 0; i < res->count_connectors; i++) { 219 c = drmModeGetConnector(fd, res->connectors[i]); 220 221 if (!c) { 222 fprintf(stderr, "Could not get connector %u: %s\n", 223 res->connectors[i], strerror(errno)); 224 continue; 225 } 226 227 printf("Connector %u (%s-%u)\n", c->connector_id, 228 connector_type_str(c->connector_type), 229 c->connector_type_id); 230 231 listObjectProperties(c->connector_id, 232 DRM_MODE_OBJECT_CONNECTOR); 233 234 drmModeFreeConnector(c); 235 } 236 } 237 238 static void listCrtcProperties(void) 239 { 240 int i; 241 drmModeCrtcPtr c; 242 243 for (i = 0; i < res->count_crtcs; i++) { 244 c = drmModeGetCrtc(fd, res->crtcs[i]); 245 246 if (!c) { 247 fprintf(stderr, "Could not get crtc %u: %s\n", 248 res->crtcs[i], strerror(errno)); 249 continue; 250 } 251 252 printf("CRTC %u\n", c->crtc_id); 253 254 listObjectProperties(c->crtc_id, DRM_MODE_OBJECT_CRTC); 255 256 drmModeFreeCrtc(c); 257 } 258 } 259 260 static void listAllProperties(void) 261 { 262 listConnectorProperties(); 263 listCrtcProperties(); 264 } 265 266 static int setProperty(char *argv[]) 267 { 268 uint32_t obj_id, obj_type, prop_id; 269 uint64_t value; 270 271 obj_id = atoi(argv[1]); 272 273 if (!strcmp(argv[2], "connector")) { 274 obj_type = DRM_MODE_OBJECT_CONNECTOR; 275 } else if (!strcmp(argv[2], "crtc")) { 276 obj_type = DRM_MODE_OBJECT_CRTC; 277 } else { 278 fprintf(stderr, "Invalid object type.\n"); 279 return 1; 280 } 281 282 prop_id = atoi(argv[3]); 283 value = atoll(argv[4]); 284 285 return drmModeObjectSetProperty(fd, obj_id, obj_type, prop_id, value); 286 } 287 288 static void printUsage(void) 289 { 290 printf("Usage:\n" 291 " proptest\n" 292 " proptest [obj id] [obj type] [prop id] [value]\n" 293 "\n" 294 "The first form just prints all the existing properties. The second one is\n" 295 "used to set the value of a specified property. The object type can be one of\n" 296 "the following strings:\n" 297 " connector crtc\n" 298 "\n" 299 "Example:\n" 300 " proptest 7 connector 2 1\n" 301 "will set property 2 of connector 7 to 1\n"); 302 } 303 304 int main(int argc, char *argv[]) 305 { 306 char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "msm" }; 307 unsigned int i, ret = 0; 308 309 for (i = 0; i < ARRAY_SIZE(modules); i++){ 310 fd = drmOpen(modules[i], NULL); 311 if (fd >= 0) { 312 printf("Module %s loaded.\n", modules[i]); 313 break; 314 } 315 } 316 317 if (i == ARRAY_SIZE(modules)) { 318 fprintf(stderr, "Failed to load drm modules.\n"); 319 return 1; 320 } 321 322 res = drmModeGetResources(fd); 323 if (!res) { 324 fprintf(stderr, "Failed to get resources: %s\n", 325 strerror(errno)); 326 ret = 1; 327 goto done; 328 } 329 330 if (argc < 2) { 331 listAllProperties(); 332 } else if (argc == 5) { 333 ret = setProperty(argv); 334 } else { 335 printUsage(); 336 ret = 1; 337 } 338 339 drmModeFreeResources(res); 340 done: 341 drmClose(fd); 342 return ret; 343 } 344