1d722e3fbSopenharmony_ci/* 2d722e3fbSopenharmony_ci * Copyright © 2012 Intel Corporation 3d722e3fbSopenharmony_ci * 4d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 7d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10d722e3fbSopenharmony_ci * 11d722e3fbSopenharmony_ci * The above copyright notice and this permission notice (including the next 12d722e3fbSopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13d722e3fbSopenharmony_ci * Software. 14d722e3fbSopenharmony_ci * 15d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18d722e3fbSopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19d722e3fbSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20d722e3fbSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21d722e3fbSopenharmony_ci * IN THE SOFTWARE. 22d722e3fbSopenharmony_ci * 23d722e3fbSopenharmony_ci * Authors: 24d722e3fbSopenharmony_ci * Paulo Zanoni <paulo.r.zanoni@intel.com> 25d722e3fbSopenharmony_ci * 26d722e3fbSopenharmony_ci */ 27d722e3fbSopenharmony_ci 28d722e3fbSopenharmony_ci#include <assert.h> 29d722e3fbSopenharmony_ci#include <errno.h> 30d722e3fbSopenharmony_ci#include <getopt.h> 31d722e3fbSopenharmony_ci#include <inttypes.h> 32d722e3fbSopenharmony_ci#include <stdlib.h> 33d722e3fbSopenharmony_ci#include <stdio.h> 34d722e3fbSopenharmony_ci#include <string.h> 35d722e3fbSopenharmony_ci 36d722e3fbSopenharmony_ci#include "xf86drm.h" 37d722e3fbSopenharmony_ci#include "xf86drmMode.h" 38d722e3fbSopenharmony_ci 39d722e3fbSopenharmony_ci#include "util/common.h" 40d722e3fbSopenharmony_ci#include "util/kms.h" 41d722e3fbSopenharmony_ci 42d722e3fbSopenharmony_cistatic inline int64_t U642I64(uint64_t val) 43d722e3fbSopenharmony_ci{ 44d722e3fbSopenharmony_ci return (int64_t)*((int64_t *)&val); 45d722e3fbSopenharmony_ci} 46d722e3fbSopenharmony_ci 47d722e3fbSopenharmony_ciint fd; 48d722e3fbSopenharmony_cidrmModeResPtr res = NULL; 49d722e3fbSopenharmony_ci 50d722e3fbSopenharmony_ci/* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */ 51d722e3fbSopenharmony_cistatic void 52d722e3fbSopenharmony_cidump_blob(uint32_t blob_id) 53d722e3fbSopenharmony_ci{ 54d722e3fbSopenharmony_ci uint32_t i; 55d722e3fbSopenharmony_ci unsigned char *blob_data; 56d722e3fbSopenharmony_ci drmModePropertyBlobPtr blob; 57d722e3fbSopenharmony_ci 58d722e3fbSopenharmony_ci blob = drmModeGetPropertyBlob(fd, blob_id); 59d722e3fbSopenharmony_ci if (!blob) { 60d722e3fbSopenharmony_ci printf("\n"); 61d722e3fbSopenharmony_ci return; 62d722e3fbSopenharmony_ci } 63d722e3fbSopenharmony_ci 64d722e3fbSopenharmony_ci blob_data = blob->data; 65d722e3fbSopenharmony_ci 66d722e3fbSopenharmony_ci for (i = 0; i < blob->length; i++) { 67d722e3fbSopenharmony_ci if (i % 16 == 0) 68d722e3fbSopenharmony_ci printf("\n\t\t\t"); 69d722e3fbSopenharmony_ci printf("%.2hhx", blob_data[i]); 70d722e3fbSopenharmony_ci } 71d722e3fbSopenharmony_ci printf("\n"); 72d722e3fbSopenharmony_ci 73d722e3fbSopenharmony_ci drmModeFreePropertyBlob(blob); 74d722e3fbSopenharmony_ci} 75d722e3fbSopenharmony_ci 76d722e3fbSopenharmony_cistatic void 77d722e3fbSopenharmony_cidump_prop(uint32_t prop_id, uint64_t value) 78d722e3fbSopenharmony_ci{ 79d722e3fbSopenharmony_ci int i; 80d722e3fbSopenharmony_ci drmModePropertyPtr prop; 81d722e3fbSopenharmony_ci 82d722e3fbSopenharmony_ci prop = drmModeGetProperty(fd, prop_id); 83d722e3fbSopenharmony_ci 84d722e3fbSopenharmony_ci printf("\t%d", prop_id); 85d722e3fbSopenharmony_ci if (!prop) { 86d722e3fbSopenharmony_ci printf("\n"); 87d722e3fbSopenharmony_ci return; 88d722e3fbSopenharmony_ci } 89d722e3fbSopenharmony_ci 90d722e3fbSopenharmony_ci printf(" %s:\n", prop->name); 91d722e3fbSopenharmony_ci 92d722e3fbSopenharmony_ci printf("\t\tflags:"); 93d722e3fbSopenharmony_ci if (prop->flags & DRM_MODE_PROP_PENDING) 94d722e3fbSopenharmony_ci printf(" pending"); 95d722e3fbSopenharmony_ci if (prop->flags & DRM_MODE_PROP_IMMUTABLE) 96d722e3fbSopenharmony_ci printf(" immutable"); 97d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) 98d722e3fbSopenharmony_ci printf(" signed range"); 99d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) 100d722e3fbSopenharmony_ci printf(" range"); 101d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) 102d722e3fbSopenharmony_ci printf(" enum"); 103d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) 104d722e3fbSopenharmony_ci printf(" bitmask"); 105d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) 106d722e3fbSopenharmony_ci printf(" blob"); 107d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_OBJECT)) 108d722e3fbSopenharmony_ci printf(" object"); 109d722e3fbSopenharmony_ci printf("\n"); 110d722e3fbSopenharmony_ci 111d722e3fbSopenharmony_ci 112d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) { 113d722e3fbSopenharmony_ci printf("\t\tvalues:"); 114d722e3fbSopenharmony_ci for (i = 0; i < prop->count_values; i++) 115d722e3fbSopenharmony_ci printf(" %"PRId64, U642I64(prop->values[i])); 116d722e3fbSopenharmony_ci printf("\n"); 117d722e3fbSopenharmony_ci } 118d722e3fbSopenharmony_ci 119d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) { 120d722e3fbSopenharmony_ci printf("\t\tvalues:"); 121d722e3fbSopenharmony_ci for (i = 0; i < prop->count_values; i++) 122d722e3fbSopenharmony_ci printf(" %"PRIu64, prop->values[i]); 123d722e3fbSopenharmony_ci printf("\n"); 124d722e3fbSopenharmony_ci } 125d722e3fbSopenharmony_ci 126d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) { 127d722e3fbSopenharmony_ci printf("\t\tenums:"); 128d722e3fbSopenharmony_ci for (i = 0; i < prop->count_enums; i++) 129d722e3fbSopenharmony_ci printf(" %s=%"PRIu64, prop->enums[i].name, 130d722e3fbSopenharmony_ci (uint64_t)prop->enums[i].value); 131d722e3fbSopenharmony_ci printf("\n"); 132d722e3fbSopenharmony_ci } else if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) { 133d722e3fbSopenharmony_ci printf("\t\tvalues:"); 134d722e3fbSopenharmony_ci for (i = 0; i < prop->count_enums; i++) 135d722e3fbSopenharmony_ci printf(" %s=0x%llx", prop->enums[i].name, 136d722e3fbSopenharmony_ci (1LL << prop->enums[i].value)); 137d722e3fbSopenharmony_ci printf("\n"); 138d722e3fbSopenharmony_ci } else { 139d722e3fbSopenharmony_ci assert(prop->count_enums == 0); 140d722e3fbSopenharmony_ci } 141d722e3fbSopenharmony_ci 142d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) { 143d722e3fbSopenharmony_ci printf("\t\tblobs:\n"); 144d722e3fbSopenharmony_ci for (i = 0; i < prop->count_blobs; i++) 145d722e3fbSopenharmony_ci dump_blob(prop->blob_ids[i]); 146d722e3fbSopenharmony_ci printf("\n"); 147d722e3fbSopenharmony_ci } else { 148d722e3fbSopenharmony_ci assert(prop->count_blobs == 0); 149d722e3fbSopenharmony_ci } 150d722e3fbSopenharmony_ci 151d722e3fbSopenharmony_ci printf("\t\tvalue:"); 152d722e3fbSopenharmony_ci if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) 153d722e3fbSopenharmony_ci dump_blob(value); 154d722e3fbSopenharmony_ci else if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) 155d722e3fbSopenharmony_ci printf(" %"PRId64"\n", value); 156d722e3fbSopenharmony_ci else 157d722e3fbSopenharmony_ci printf(" %"PRIu64"\n", value); 158d722e3fbSopenharmony_ci 159d722e3fbSopenharmony_ci drmModeFreeProperty(prop); 160d722e3fbSopenharmony_ci} 161d722e3fbSopenharmony_ci 162d722e3fbSopenharmony_cistatic void listObjectProperties(uint32_t id, uint32_t type) 163d722e3fbSopenharmony_ci{ 164d722e3fbSopenharmony_ci unsigned int i; 165d722e3fbSopenharmony_ci drmModeObjectPropertiesPtr props; 166d722e3fbSopenharmony_ci 167d722e3fbSopenharmony_ci props = drmModeObjectGetProperties(fd, id, type); 168d722e3fbSopenharmony_ci 169d722e3fbSopenharmony_ci if (!props) { 170d722e3fbSopenharmony_ci printf("\tNo properties: %s.\n", strerror(errno)); 171d722e3fbSopenharmony_ci return; 172d722e3fbSopenharmony_ci } 173d722e3fbSopenharmony_ci 174d722e3fbSopenharmony_ci for (i = 0; i < props->count_props; i++) 175d722e3fbSopenharmony_ci dump_prop(props->props[i], props->prop_values[i]); 176d722e3fbSopenharmony_ci 177d722e3fbSopenharmony_ci drmModeFreeObjectProperties(props); 178d722e3fbSopenharmony_ci} 179d722e3fbSopenharmony_ci 180d722e3fbSopenharmony_cistatic void listConnectorProperties(void) 181d722e3fbSopenharmony_ci{ 182d722e3fbSopenharmony_ci int i; 183d722e3fbSopenharmony_ci drmModeConnectorPtr c; 184d722e3fbSopenharmony_ci 185d722e3fbSopenharmony_ci for (i = 0; i < res->count_connectors; i++) { 186d722e3fbSopenharmony_ci c = drmModeGetConnector(fd, res->connectors[i]); 187d722e3fbSopenharmony_ci 188d722e3fbSopenharmony_ci if (!c) { 189d722e3fbSopenharmony_ci fprintf(stderr, "Could not get connector %u: %s\n", 190d722e3fbSopenharmony_ci res->connectors[i], strerror(errno)); 191d722e3fbSopenharmony_ci continue; 192d722e3fbSopenharmony_ci } 193d722e3fbSopenharmony_ci 194d722e3fbSopenharmony_ci printf("Connector %u (%s-%u)\n", c->connector_id, 195d722e3fbSopenharmony_ci util_lookup_connector_type_name(c->connector_type), 196d722e3fbSopenharmony_ci c->connector_type_id); 197d722e3fbSopenharmony_ci 198d722e3fbSopenharmony_ci listObjectProperties(c->connector_id, 199d722e3fbSopenharmony_ci DRM_MODE_OBJECT_CONNECTOR); 200d722e3fbSopenharmony_ci 201d722e3fbSopenharmony_ci drmModeFreeConnector(c); 202d722e3fbSopenharmony_ci } 203d722e3fbSopenharmony_ci} 204d722e3fbSopenharmony_ci 205d722e3fbSopenharmony_cistatic void listCrtcProperties(void) 206d722e3fbSopenharmony_ci{ 207d722e3fbSopenharmony_ci int i; 208d722e3fbSopenharmony_ci drmModeCrtcPtr c; 209d722e3fbSopenharmony_ci 210d722e3fbSopenharmony_ci for (i = 0; i < res->count_crtcs; i++) { 211d722e3fbSopenharmony_ci c = drmModeGetCrtc(fd, res->crtcs[i]); 212d722e3fbSopenharmony_ci 213d722e3fbSopenharmony_ci if (!c) { 214d722e3fbSopenharmony_ci fprintf(stderr, "Could not get crtc %u: %s\n", 215d722e3fbSopenharmony_ci res->crtcs[i], strerror(errno)); 216d722e3fbSopenharmony_ci continue; 217d722e3fbSopenharmony_ci } 218d722e3fbSopenharmony_ci 219d722e3fbSopenharmony_ci printf("CRTC %u\n", c->crtc_id); 220d722e3fbSopenharmony_ci 221d722e3fbSopenharmony_ci listObjectProperties(c->crtc_id, DRM_MODE_OBJECT_CRTC); 222d722e3fbSopenharmony_ci 223d722e3fbSopenharmony_ci drmModeFreeCrtc(c); 224d722e3fbSopenharmony_ci } 225d722e3fbSopenharmony_ci} 226d722e3fbSopenharmony_ci 227d722e3fbSopenharmony_cistatic void listAllProperties(void) 228d722e3fbSopenharmony_ci{ 229d722e3fbSopenharmony_ci listConnectorProperties(); 230d722e3fbSopenharmony_ci listCrtcProperties(); 231d722e3fbSopenharmony_ci} 232d722e3fbSopenharmony_ci 233d722e3fbSopenharmony_cistatic int setProperty(char *argv[]) 234d722e3fbSopenharmony_ci{ 235d722e3fbSopenharmony_ci uint32_t obj_id, obj_type, prop_id; 236d722e3fbSopenharmony_ci uint64_t value; 237d722e3fbSopenharmony_ci 238d722e3fbSopenharmony_ci obj_id = atoi(argv[0]); 239d722e3fbSopenharmony_ci 240d722e3fbSopenharmony_ci if (!strcmp(argv[1], "connector")) { 241d722e3fbSopenharmony_ci obj_type = DRM_MODE_OBJECT_CONNECTOR; 242d722e3fbSopenharmony_ci } else if (!strcmp(argv[1], "crtc")) { 243d722e3fbSopenharmony_ci obj_type = DRM_MODE_OBJECT_CRTC; 244d722e3fbSopenharmony_ci } else { 245d722e3fbSopenharmony_ci fprintf(stderr, "Invalid object type.\n"); 246d722e3fbSopenharmony_ci return 1; 247d722e3fbSopenharmony_ci } 248d722e3fbSopenharmony_ci 249d722e3fbSopenharmony_ci prop_id = atoi(argv[2]); 250d722e3fbSopenharmony_ci value = atoll(argv[3]); 251d722e3fbSopenharmony_ci 252d722e3fbSopenharmony_ci return drmModeObjectSetProperty(fd, obj_id, obj_type, prop_id, value); 253d722e3fbSopenharmony_ci} 254d722e3fbSopenharmony_ci 255d722e3fbSopenharmony_cistatic void usage(const char *program) 256d722e3fbSopenharmony_ci{ 257d722e3fbSopenharmony_ci printf("Usage:\n" 258d722e3fbSopenharmony_ci" %s [options]\n" 259d722e3fbSopenharmony_ci" %s [options] [obj id] [obj type] [prop id] [value]\n" 260d722e3fbSopenharmony_ci"\n" 261d722e3fbSopenharmony_ci"options:\n" 262d722e3fbSopenharmony_ci" -D DEVICE use the given device\n" 263d722e3fbSopenharmony_ci" -M MODULE use the given driver\n" 264d722e3fbSopenharmony_ci"\n" 265d722e3fbSopenharmony_ci"The first form just prints all the existing properties. The second one is\n" 266d722e3fbSopenharmony_ci"used to set the value of a specified property. The object type can be one of\n" 267d722e3fbSopenharmony_ci"the following strings:\n" 268d722e3fbSopenharmony_ci" connector crtc\n" 269d722e3fbSopenharmony_ci"\n" 270d722e3fbSopenharmony_ci"Example:\n" 271d722e3fbSopenharmony_ci" proptest 7 connector 2 1\n" 272d722e3fbSopenharmony_ci"will set property 2 of connector 7 to 1\n", program, program); 273d722e3fbSopenharmony_ci} 274d722e3fbSopenharmony_ci 275d722e3fbSopenharmony_ciint main(int argc, char *argv[]) 276d722e3fbSopenharmony_ci{ 277d722e3fbSopenharmony_ci static const char optstr[] = "D:M:"; 278d722e3fbSopenharmony_ci int c, args, ret = 0; 279d722e3fbSopenharmony_ci char *device = NULL; 280d722e3fbSopenharmony_ci char *module = NULL; 281d722e3fbSopenharmony_ci 282d722e3fbSopenharmony_ci while ((c = getopt(argc, argv, optstr)) != -1) { 283d722e3fbSopenharmony_ci switch (c) { 284d722e3fbSopenharmony_ci case 'D': 285d722e3fbSopenharmony_ci device = optarg; 286d722e3fbSopenharmony_ci break; 287d722e3fbSopenharmony_ci 288d722e3fbSopenharmony_ci case 'M': 289d722e3fbSopenharmony_ci module = optarg; 290d722e3fbSopenharmony_ci break; 291d722e3fbSopenharmony_ci 292d722e3fbSopenharmony_ci default: 293d722e3fbSopenharmony_ci usage(argv[0]); 294d722e3fbSopenharmony_ci break; 295d722e3fbSopenharmony_ci } 296d722e3fbSopenharmony_ci } 297d722e3fbSopenharmony_ci 298d722e3fbSopenharmony_ci args = argc - optind; 299d722e3fbSopenharmony_ci 300d722e3fbSopenharmony_ci fd = util_open(device, module); 301d722e3fbSopenharmony_ci if (fd < 0) 302d722e3fbSopenharmony_ci return 1; 303d722e3fbSopenharmony_ci 304d722e3fbSopenharmony_ci res = drmModeGetResources(fd); 305d722e3fbSopenharmony_ci if (!res) { 306d722e3fbSopenharmony_ci fprintf(stderr, "Failed to get resources: %s\n", 307d722e3fbSopenharmony_ci strerror(errno)); 308d722e3fbSopenharmony_ci ret = 1; 309d722e3fbSopenharmony_ci goto done; 310d722e3fbSopenharmony_ci } 311d722e3fbSopenharmony_ci 312d722e3fbSopenharmony_ci if (args < 1) { 313d722e3fbSopenharmony_ci listAllProperties(); 314d722e3fbSopenharmony_ci } else if (args == 4) { 315d722e3fbSopenharmony_ci ret = setProperty(&argv[optind]); 316d722e3fbSopenharmony_ci } else { 317d722e3fbSopenharmony_ci usage(argv[0]); 318d722e3fbSopenharmony_ci ret = 1; 319d722e3fbSopenharmony_ci } 320d722e3fbSopenharmony_ci 321d722e3fbSopenharmony_ci drmModeFreeResources(res); 322d722e3fbSopenharmony_cidone: 323d722e3fbSopenharmony_ci drmClose(fd); 324d722e3fbSopenharmony_ci return ret; 325d722e3fbSopenharmony_ci} 326