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