1/* 2 * \file modedemo.c 3 * Test program to dump DRM kernel mode setting related information. 4 * Queries the kernel for all available information and dumps it to stdout. 5 * 6 * \author Jakob Bornecrantz <wallbraker@gmail.com> 7 */ 8 9/* 10 * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. 11 * Copyright (c) 2007-2008 Jakob Bornecrantz <wallbraker@gmail.com> 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a 14 * copy of this software and associated documentation files (the "Software"), 15 * to deal in the Software without restriction, including without limitation 16 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 17 * and/or sell copies of the Software, and to permit persons to whom the 18 * Software is furnished to do so, subject to the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included in 21 * all copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 29 * IN THE SOFTWARE. 30 * 31 */ 32 33#include <assert.h> 34#include <stdio.h> 35#include <stdlib.h> 36#include <stdint.h> 37#include <unistd.h> 38#include <string.h> 39#include <inttypes.h> 40 41#include "xf86drm.h" 42#include "xf86drmMode.h" 43 44#include "util/common.h" 45 46int current; 47int connectors; 48int full_props; 49int edid; 50int modes; 51int full_modes; 52int encoders; 53int crtcs; 54int fbs; 55char *module_name; 56 57static const char* getConnectionText(drmModeConnection conn) 58{ 59 switch (conn) { 60 case DRM_MODE_CONNECTED: 61 return "connected"; 62 case DRM_MODE_DISCONNECTED: 63 return "disconnected"; 64 case DRM_MODE_UNKNOWNCONNECTION: 65 default: 66 return "unknown"; 67 } 68 69} 70 71static int printMode(struct drm_mode_modeinfo *mode) 72{ 73 if (full_modes) { 74 printf("Mode: %s\n", mode->name); 75 printf("\tclock : %i\n", mode->clock); 76 printf("\thdisplay : %i\n", mode->hdisplay); 77 printf("\thsync_start : %i\n", mode->hsync_start); 78 printf("\thsync_end : %i\n", mode->hsync_end); 79 printf("\thtotal : %i\n", mode->htotal); 80 printf("\thskew : %i\n", mode->hskew); 81 printf("\tvdisplay : %i\n", mode->vdisplay); 82 printf("\tvsync_start : %i\n", mode->vsync_start); 83 printf("\tvsync_end : %i\n", mode->vsync_end); 84 printf("\tvtotal : %i\n", mode->vtotal); 85 printf("\tvscan : %i\n", mode->vscan); 86 printf("\tvrefresh : %i\n", mode->vrefresh); 87 printf("\tflags : %i\n", mode->flags); 88 } else { 89 printf("Mode: \"%s\" %ix%i %i\n", mode->name, 90 mode->hdisplay, mode->vdisplay, mode->vrefresh); 91 } 92 return 0; 93} 94 95static int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, uint64_t value) 96{ 97 const char *name = NULL; 98 int j; 99 100 printf("Property: %s\n", props->name); 101 printf("\tid : %i\n", props->prop_id); 102 printf("\tflags : %i\n", props->flags); 103 printf("\tcount_values : %d\n", props->count_values); 104 105 106 if (props->count_values) { 107 printf("\tvalues :"); 108 for (j = 0; j < props->count_values; j++) 109 printf(" %" PRIu64, props->values[j]); 110 printf("\n"); 111 } 112 113 114 printf("\tcount_enums : %d\n", props->count_enums); 115 116 if (props->flags & DRM_MODE_PROP_BLOB) { 117 drmModePropertyBlobPtr blob; 118 119 blob = drmModeGetPropertyBlob(fd, value); 120 if (blob) { 121 printf("blob is %d length, %08X\n", blob->length, *(uint32_t *)blob->data); 122 drmModeFreePropertyBlob(blob); 123 } else { 124 printf("error getting blob %" PRIu64 "\n", value); 125 } 126 127 } else { 128 for (j = 0; j < props->count_enums; j++) { 129 printf("\t\t%lld = %s\n", props->enums[j].value, props->enums[j].name); 130 if (props->enums[j].value == value) 131 name = props->enums[j].name; 132 } 133 134 if (props->count_enums && name) { 135 printf("\tcon_value : %s\n", name); 136 } else { 137 printf("\tcon_value : %" PRIu64 "\n", value); 138 } 139 } 140 141 return 0; 142} 143 144static const char * const output_names[] = { "None", 145 "VGA", 146 "DVI-I", 147 "DVI-D", 148 "DVI-A", 149 "Composite", 150 "SVIDEO", 151 "LVDS", 152 "Component", 153 "DIN", 154 "DP", 155 "HDMI-A", 156 "HDMI-B", 157 "TV", 158 "eDP", 159 "Virtual", 160 "DSI", 161}; 162 163static int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uint32_t id) 164{ 165 int i = 0; 166 struct drm_mode_modeinfo *mode = NULL; 167 drmModePropertyPtr props; 168 169 if (connector->connector_type < ARRAY_SIZE(output_names)) 170 printf("Connector: %s-%d\n", output_names[connector->connector_type], 171 connector->connector_type_id); 172 else 173 printf("Connector: %d-%d\n", connector->connector_type, 174 connector->connector_type_id); 175 printf("\tid : %i\n", id); 176 printf("\tencoder id : %i\n", connector->encoder_id); 177 printf("\tconn : %s\n", getConnectionText(connector->connection)); 178 printf("\tsize : %ix%i (mm)\n", connector->mmWidth, connector->mmHeight); 179 printf("\tcount_modes : %i\n", connector->count_modes); 180 printf("\tcount_props : %i\n", connector->count_props); 181 if (connector->count_props) { 182 printf("\tprops :"); 183 for (i = 0; i < connector->count_props; i++) 184 printf(" %i", connector->props[i]); 185 printf("\n"); 186 } 187 188 printf("\tcount_encoders : %i\n", connector->count_encoders); 189 if (connector->count_encoders) { 190 printf("\tencoders :"); 191 for (i = 0; i < connector->count_encoders; i++) 192 printf(" %i", connector->encoders[i]); 193 printf("\n"); 194 } 195 196 if (modes) { 197 for (i = 0; i < connector->count_modes; i++) { 198 mode = (struct drm_mode_modeinfo *)&connector->modes[i]; 199 printMode(mode); 200 } 201 } 202 203 if (full_props) { 204 for (i = 0; i < connector->count_props; i++) { 205 props = drmModeGetProperty(fd, connector->props[i]); 206 if (props) { 207 printProperty(fd, res, props, connector->prop_values[i]); 208 drmModeFreeProperty(props); 209 } 210 } 211 } 212 213 return 0; 214} 215 216static int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t id) 217{ 218 printf("Encoder\n"); 219 printf("\tid :%i\n", id); 220 printf("\tcrtc_id :%d\n", encoder->crtc_id); 221 printf("\ttype :%d\n", encoder->encoder_type); 222 printf("\tpossible_crtcs :0x%x\n", encoder->possible_crtcs); 223 printf("\tpossible_clones :0x%x\n", encoder->possible_clones); 224 return 0; 225} 226 227static int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id) 228{ 229 printf("Crtc\n"); 230 printf("\tid : %i\n", id); 231 printf("\tx : %i\n", crtc->x); 232 printf("\ty : %i\n", crtc->y); 233 printf("\twidth : %i\n", crtc->width); 234 printf("\theight : %i\n", crtc->height); 235 printf("\tmode : %p\n", &crtc->mode); 236 printf("\tgamma size : %d\n", crtc->gamma_size); 237 238 return 0; 239} 240 241static int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb) 242{ 243 printf("Framebuffer\n"); 244 printf("\thandle : %i\n", fb->handle); 245 printf("\twidth : %i\n", fb->width); 246 printf("\theight : %i\n", fb->height); 247 printf("\tpitch : %i\n", fb->pitch);; 248 printf("\tbpp : %i\n", fb->bpp); 249 printf("\tdepth : %i\n", fb->depth); 250 printf("\tbuffer_id : %i\n", fb->handle); 251 252 return 0; 253} 254 255static int printRes(int fd, drmModeResPtr res) 256{ 257 int i; 258 drmModeFBPtr fb; 259 drmModeCrtcPtr crtc; 260 drmModeEncoderPtr encoder; 261 drmModeConnectorPtr connector; 262 263 printf("Resources\n\n"); 264 265 printf("count_connectors : %i\n", res->count_connectors); 266 printf("count_encoders : %i\n", res->count_encoders); 267 printf("count_crtcs : %i\n", res->count_crtcs); 268 printf("count_fbs : %i\n", res->count_fbs); 269 270 printf("\n"); 271 272 if (connectors) { 273 for (i = 0; i < res->count_connectors; i++) { 274 connector = (current ? drmModeGetConnectorCurrent : drmModeGetConnector) (fd, res->connectors[i]); 275 276 if (!connector) 277 printf("Could not get connector %i\n", res->connectors[i]); 278 else { 279 printConnector(fd, res, connector, res->connectors[i]); 280 drmModeFreeConnector(connector); 281 } 282 } 283 printf("\n"); 284 } 285 286 287 if (encoders) { 288 for (i = 0; i < res->count_encoders; i++) { 289 encoder = drmModeGetEncoder(fd, res->encoders[i]); 290 291 if (!encoder) 292 printf("Could not get encoder %i\n", res->encoders[i]); 293 else { 294 printEncoder(fd, res, encoder, res->encoders[i]); 295 drmModeFreeEncoder(encoder); 296 } 297 } 298 printf("\n"); 299 } 300 301 if (crtcs) { 302 for (i = 0; i < res->count_crtcs; i++) { 303 crtc = drmModeGetCrtc(fd, res->crtcs[i]); 304 305 if (!crtc) 306 printf("Could not get crtc %i\n", res->crtcs[i]); 307 else { 308 printCrtc(fd, res, crtc, res->crtcs[i]); 309 drmModeFreeCrtc(crtc); 310 } 311 } 312 printf("\n"); 313 } 314 315 if (fbs) { 316 for (i = 0; i < res->count_fbs; i++) { 317 fb = drmModeGetFB(fd, res->fbs[i]); 318 319 if (!fb) 320 printf("Could not get fb %i\n", res->fbs[i]); 321 else { 322 printFrameBuffer(fd, res, fb); 323 drmModeFreeFB(fb); 324 } 325 } 326 } 327 328 return 0; 329} 330 331static void args(int argc, char **argv) 332{ 333 int defaults = 1; 334 int i; 335 336 fbs = 0; 337 edid = 0; 338 crtcs = 0; 339 modes = 0; 340 encoders = 0; 341 full_modes = 0; 342 full_props = 0; 343 connectors = 0; 344 current = 0; 345 346 module_name = argv[1]; 347 348 for (i = 2; i < argc; i++) { 349 if (strcmp(argv[i], "-fb") == 0) { 350 fbs = 1; 351 defaults = 0; 352 } else if (strcmp(argv[i], "-crtcs") == 0) { 353 crtcs = 1; 354 defaults = 0; 355 } else if (strcmp(argv[i], "-cons") == 0) { 356 connectors = 1; 357 modes = 1; 358 defaults = 0; 359 } else if (strcmp(argv[i], "-modes") == 0) { 360 connectors = 1; 361 modes = 1; 362 defaults = 0; 363 } else if (strcmp(argv[i], "-full") == 0) { 364 connectors = 1; 365 modes = 1; 366 full_modes = 1; 367 defaults = 0; 368 } else if (strcmp(argv[i], "-props") == 0) { 369 connectors = 1; 370 full_props = 1; 371 defaults = 0; 372 } else if (strcmp(argv[i], "-edids") == 0) { 373 connectors = 1; 374 edid = 1; 375 defaults = 0; 376 } else if (strcmp(argv[i], "-encoders") == 0) { 377 encoders = 1; 378 defaults = 0; 379 } else if (strcmp(argv[i], "-v") == 0) { 380 fbs = 1; 381 edid = 1; 382 crtcs = 1; 383 modes = 1; 384 encoders = 1; 385 full_modes = 1; 386 full_props = 1; 387 connectors = 1; 388 defaults = 0; 389 } else if (strcmp(argv[i], "-current") == 0) { 390 current = 1; 391 } 392 } 393 394 if (defaults) { 395 fbs = 1; 396 edid = 1; 397 crtcs = 1; 398 modes = 1; 399 encoders = 1; 400 full_modes = 0; 401 full_props = 0; 402 connectors = 1; 403 } 404} 405 406int main(int argc, char **argv) 407{ 408 int fd; 409 drmModeResPtr res; 410 411 if (argc == 1) { 412 printf("Please add modulename as first argument\n"); 413 return 1; 414 } 415 416 args(argc, argv); 417 418 printf("Starting test\n"); 419 420 fd = drmOpen(module_name, NULL); 421 422 if (fd < 0) { 423 printf("Failed to open the card fd (%d)\n",fd); 424 return 1; 425 } 426 427 res = drmModeGetResources(fd); 428 if (res == 0) { 429 printf("Failed to get resources from card\n"); 430 drmClose(fd); 431 return 1; 432 } 433 434 printRes(fd, res); 435 436 drmModeFreeResources(res); 437 438 printf("Ok\n"); 439 440 return 0; 441} 442