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