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#include "util/kms.h" 46 47int current; 48int connectors; 49int full_props; 50int edid; 51int modes; 52int full_modes; 53int encoders; 54int crtcs; 55int fbs; 56char *module_name; 57 58static int printMode(struct drm_mode_modeinfo *mode) 59{ 60 if (full_modes) { 61 printf("Mode: %s\n", mode->name); 62 printf("\tclock : %i\n", mode->clock); 63 printf("\thdisplay : %i\n", mode->hdisplay); 64 printf("\thsync_start : %i\n", mode->hsync_start); 65 printf("\thsync_end : %i\n", mode->hsync_end); 66 printf("\thtotal : %i\n", mode->htotal); 67 printf("\thskew : %i\n", mode->hskew); 68 printf("\tvdisplay : %i\n", mode->vdisplay); 69 printf("\tvsync_start : %i\n", mode->vsync_start); 70 printf("\tvsync_end : %i\n", mode->vsync_end); 71 printf("\tvtotal : %i\n", mode->vtotal); 72 printf("\tvscan : %i\n", mode->vscan); 73 printf("\tvrefresh : %i\n", mode->vrefresh); 74 printf("\tflags : %i\n", mode->flags); 75 } else { 76 printf("Mode: \"%s\" %ix%i %i\n", mode->name, 77 mode->hdisplay, mode->vdisplay, mode->vrefresh); 78 } 79 return 0; 80} 81 82static int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, uint64_t value) 83{ 84 const char *name = NULL; 85 int j; 86 87 printf("Property: %s\n", props->name); 88 printf("\tid : %i\n", props->prop_id); 89 printf("\tflags : %i\n", props->flags); 90 printf("\tcount_values : %d\n", props->count_values); 91 92 93 if (props->count_values) { 94 printf("\tvalues :"); 95 for (j = 0; j < props->count_values; j++) 96 printf(" %" PRIu64, props->values[j]); 97 printf("\n"); 98 } 99 100 101 printf("\tcount_enums : %d\n", props->count_enums); 102 103 if (props->flags & DRM_MODE_PROP_BLOB) { 104 drmModePropertyBlobPtr blob; 105 106 blob = drmModeGetPropertyBlob(fd, value); 107 if (blob) { 108 printf("blob is %d length, %08X\n", blob->length, *(uint32_t *)blob->data); 109 drmModeFreePropertyBlob(blob); 110 } else { 111 printf("error getting blob %" PRIu64 "\n", value); 112 } 113 114 } else { 115 for (j = 0; j < props->count_enums; j++) { 116 printf("\t\t%" PRIu64" = %s\n", (uint64_t)props->enums[j].value, props->enums[j].name); 117 if (props->enums[j].value == value) 118 name = props->enums[j].name; 119 } 120 121 if (props->count_enums && name) { 122 printf("\tcon_value : %s\n", name); 123 } else { 124 printf("\tcon_value : %" PRIu64 "\n", value); 125 } 126 } 127 128 return 0; 129} 130 131static int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uint32_t id) 132{ 133 int i = 0; 134 struct drm_mode_modeinfo *mode = NULL; 135 drmModePropertyPtr props; 136 const char *connector_type_name = NULL; 137 138 connector_type_name = util_lookup_connector_type_name(connector->connector_type); 139 140 if (connector_type_name) 141 printf("Connector: %s-%d\n", connector_type_name, 142 connector->connector_type_id); 143 else 144 printf("Connector: %d-%d\n", connector->connector_type, 145 connector->connector_type_id); 146 printf("\tid : %i\n", id); 147 printf("\tencoder id : %i\n", connector->encoder_id); 148 printf("\tconn : %s\n", util_lookup_connector_status_name(connector->connection)); 149 printf("\tsize : %ix%i (mm)\n", connector->mmWidth, connector->mmHeight); 150 printf("\tcount_modes : %i\n", connector->count_modes); 151 printf("\tcount_props : %i\n", connector->count_props); 152 if (connector->count_props) { 153 printf("\tprops :"); 154 for (i = 0; i < connector->count_props; i++) 155 printf(" %i", connector->props[i]); 156 printf("\n"); 157 } 158 159 printf("\tcount_encoders : %i\n", connector->count_encoders); 160 if (connector->count_encoders) { 161 printf("\tencoders :"); 162 for (i = 0; i < connector->count_encoders; i++) 163 printf(" %i", connector->encoders[i]); 164 printf("\n"); 165 } 166 167 if (modes) { 168 for (i = 0; i < connector->count_modes; i++) { 169 mode = (struct drm_mode_modeinfo *)&connector->modes[i]; 170 printMode(mode); 171 } 172 } 173 174 if (full_props) { 175 for (i = 0; i < connector->count_props; i++) { 176 props = drmModeGetProperty(fd, connector->props[i]); 177 if (props) { 178 printProperty(fd, res, props, connector->prop_values[i]); 179 drmModeFreeProperty(props); 180 } 181 } 182 } 183 184 return 0; 185} 186 187static int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t id) 188{ 189 const char *encoder_name; 190 191 encoder_name = util_lookup_encoder_type_name(encoder->encoder_type); 192 if (encoder_name) 193 printf("Encoder: %s\n", encoder_name); 194 else 195 printf("Encoder\n"); 196 printf("\tid :%i\n", id); 197 printf("\tcrtc_id :%d\n", encoder->crtc_id); 198 printf("\ttype :%d\n", encoder->encoder_type); 199 printf("\tpossible_crtcs :0x%x\n", encoder->possible_crtcs); 200 printf("\tpossible_clones :0x%x\n", encoder->possible_clones); 201 return 0; 202} 203 204static int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id) 205{ 206 printf("Crtc\n"); 207 printf("\tid : %i\n", id); 208 printf("\tx : %i\n", crtc->x); 209 printf("\ty : %i\n", crtc->y); 210 printf("\twidth : %i\n", crtc->width); 211 printf("\theight : %i\n", crtc->height); 212 printf("\tmode : %p\n", &crtc->mode); 213 printf("\tgamma size : %d\n", crtc->gamma_size); 214 215 return 0; 216} 217 218static int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb) 219{ 220 printf("Framebuffer\n"); 221 printf("\thandle : %i\n", fb->handle); 222 printf("\twidth : %i\n", fb->width); 223 printf("\theight : %i\n", fb->height); 224 printf("\tpitch : %i\n", fb->pitch); 225 printf("\tbpp : %i\n", fb->bpp); 226 printf("\tdepth : %i\n", fb->depth); 227 printf("\tbuffer_id : %i\n", fb->handle); 228 229 return 0; 230} 231 232static int printRes(int fd, drmModeResPtr res) 233{ 234 int i; 235 drmModeFBPtr fb; 236 drmModeCrtcPtr crtc; 237 drmModeEncoderPtr encoder; 238 drmModeConnectorPtr connector; 239 240 printf("Resources\n\n"); 241 242 printf("count_connectors : %i\n", res->count_connectors); 243 printf("count_encoders : %i\n", res->count_encoders); 244 printf("count_crtcs : %i\n", res->count_crtcs); 245 printf("count_fbs : %i\n", res->count_fbs); 246 247 printf("\n"); 248 249 if (connectors) { 250 for (i = 0; i < res->count_connectors; i++) { 251 connector = (current ? drmModeGetConnectorCurrent : drmModeGetConnector) (fd, res->connectors[i]); 252 253 if (!connector) 254 printf("Could not get connector %i\n", res->connectors[i]); 255 else { 256 printConnector(fd, res, connector, res->connectors[i]); 257 drmModeFreeConnector(connector); 258 } 259 } 260 printf("\n"); 261 } 262 263 264 if (encoders) { 265 for (i = 0; i < res->count_encoders; i++) { 266 encoder = drmModeGetEncoder(fd, res->encoders[i]); 267 268 if (!encoder) 269 printf("Could not get encoder %i\n", res->encoders[i]); 270 else { 271 printEncoder(fd, res, encoder, res->encoders[i]); 272 drmModeFreeEncoder(encoder); 273 } 274 } 275 printf("\n"); 276 } 277 278 if (crtcs) { 279 for (i = 0; i < res->count_crtcs; i++) { 280 crtc = drmModeGetCrtc(fd, res->crtcs[i]); 281 282 if (!crtc) 283 printf("Could not get crtc %i\n", res->crtcs[i]); 284 else { 285 printCrtc(fd, res, crtc, res->crtcs[i]); 286 drmModeFreeCrtc(crtc); 287 } 288 } 289 printf("\n"); 290 } 291 292 if (fbs) { 293 for (i = 0; i < res->count_fbs; i++) { 294 fb = drmModeGetFB(fd, res->fbs[i]); 295 296 if (!fb) 297 printf("Could not get fb %i\n", res->fbs[i]); 298 else { 299 printFrameBuffer(fd, res, fb); 300 drmModeFreeFB(fb); 301 } 302 } 303 } 304 305 return 0; 306} 307 308static void args(int argc, char **argv) 309{ 310 int defaults = 1; 311 int i; 312 313 fbs = 0; 314 edid = 0; 315 crtcs = 0; 316 modes = 0; 317 encoders = 0; 318 full_modes = 0; 319 full_props = 0; 320 connectors = 0; 321 current = 0; 322 323 module_name = argv[1]; 324 325 for (i = 2; i < argc; i++) { 326 if (strcmp(argv[i], "-fb") == 0) { 327 fbs = 1; 328 defaults = 0; 329 } else if (strcmp(argv[i], "-crtcs") == 0) { 330 crtcs = 1; 331 defaults = 0; 332 } else if (strcmp(argv[i], "-cons") == 0) { 333 connectors = 1; 334 modes = 1; 335 defaults = 0; 336 } else if (strcmp(argv[i], "-modes") == 0) { 337 connectors = 1; 338 modes = 1; 339 defaults = 0; 340 } else if (strcmp(argv[i], "-full") == 0) { 341 connectors = 1; 342 modes = 1; 343 full_modes = 1; 344 defaults = 0; 345 } else if (strcmp(argv[i], "-props") == 0) { 346 connectors = 1; 347 full_props = 1; 348 defaults = 0; 349 } else if (strcmp(argv[i], "-edids") == 0) { 350 connectors = 1; 351 edid = 1; 352 defaults = 0; 353 } else if (strcmp(argv[i], "-encoders") == 0) { 354 encoders = 1; 355 defaults = 0; 356 } else if (strcmp(argv[i], "-v") == 0) { 357 fbs = 1; 358 edid = 1; 359 crtcs = 1; 360 modes = 1; 361 encoders = 1; 362 full_modes = 1; 363 full_props = 1; 364 connectors = 1; 365 defaults = 0; 366 } else if (strcmp(argv[i], "-current") == 0) { 367 current = 1; 368 } 369 } 370 371 if (defaults) { 372 fbs = 1; 373 edid = 1; 374 crtcs = 1; 375 modes = 1; 376 encoders = 1; 377 full_modes = 0; 378 full_props = 0; 379 connectors = 1; 380 } 381} 382 383int main(int argc, char **argv) 384{ 385 int fd; 386 drmModeResPtr res; 387 388 if (argc == 1) { 389 printf("Please add modulename as first argument\n"); 390 return 1; 391 } 392 393 args(argc, argv); 394 395 printf("Starting test\n"); 396 397 fd = drmOpen(module_name, NULL); 398 399 if (fd < 0) { 400 printf("Failed to open the card fd (%d)\n",fd); 401 return 1; 402 } 403 404 res = drmModeGetResources(fd); 405 if (res == 0) { 406 printf("Failed to get resources from card\n"); 407 drmClose(fd); 408 return 1; 409 } 410 411 printRes(fd, res); 412 413 drmModeFreeResources(res); 414 415 printf("Ok\n"); 416 417 return 0; 418} 419