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