1 /* 2 * Copyright (c) 2006-2008 Intel Corporation 3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> 4 * 5 * DRM core CRTC related functions 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and its 8 * documentation for any purpose is hereby granted without fee, provided that 9 * the above copyright notice appear in all copies and that both that copyright 10 * notice and this permission notice appear in supporting documentation, and 11 * that the name of the copyright holders not be used in advertising or 12 * publicity pertaining to distribution of the software without specific, 13 * written prior permission. The copyright holders make no representations 14 * about the suitability of this software for any purpose. It is provided "as 15 * is" without express or implied warranty. 16 * 17 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 23 * OF THIS SOFTWARE. 24 * 25 * Authors: 26 * Keith Packard 27 * Eric Anholt <eric@anholt.net> 28 * Dave Airlie <airlied@linux.ie> 29 * Jesse Barnes <jesse.barnes@intel.com> 30 */ 31 32 #include "drmP.h" 33 #include "drm_crtc.h" 34 #include "drm_crtc_helper.h" 35 36 /* 37 * Detailed mode info for 800x600@60Hz 38 */ 39 static struct drm_display_mode std_modes[] = { 40 { DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 40000, 800, 840, 41 968, 1056, 0, 600, 601, 605, 628, 0, 42 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 43 }; 44 45 static void drm_mode_validate_flag(struct drm_connector *connector, 46 int flags) 47 { 48 struct drm_display_mode *mode, *t; 49 50 if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE)) 51 return; 52 53 list_for_each_entry_safe(mode, t, &connector->modes, head) { 54 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && 55 !(flags & DRM_MODE_FLAG_INTERLACE)) 56 mode->status = MODE_NO_INTERLACE; 57 if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) && 58 !(flags & DRM_MODE_FLAG_DBLSCAN)) 59 mode->status = MODE_NO_DBLESCAN; 60 } 61 62 return; 63 } 64 65 /** 66 * drm_helper_probe_connector_modes - get complete set of display modes 67 * @dev: DRM device 68 * @maxX: max width for modes 69 * @maxY: max height for modes 70 * 71 * LOCKING: 72 * Caller must hold mode config lock. 73 * 74 * Based on @dev's mode_config layout, scan all the connectors and try to detect 75 * modes on them. Modes will first be added to the connector's probed_modes 76 * list, then culled (based on validity and the @maxX, @maxY parameters) and 77 * put into the normal modes list. 78 * 79 * Intended to be used either at bootup time or when major configuration 80 * changes have occurred. 81 * 82 * FIXME: take into account monitor limits 83 * 84 * RETURNS: 85 * Number of modes found on @connector. 86 */ 87 int drm_helper_probe_single_connector_modes(struct drm_connector *connector, 88 uint32_t maxX, uint32_t maxY) 89 { 90 struct drm_device *dev = connector->dev; 91 struct drm_display_mode *mode, *t; 92 struct drm_connector_helper_funcs *connector_funcs = 93 connector->helper_private; 94 int count = 0; 95 int mode_flags = 0; 96 97 DRM_DEBUG("%s\n", drm_get_connector_name(connector)); 98 /* set all modes to the unverified state */ 99 list_for_each_entry_safe(mode, t, &connector->modes, head) 100 mode->status = MODE_UNVERIFIED; 101 102 connector->status = connector->funcs->detect(connector); 103 104 if (connector->status == connector_status_disconnected) { 105 DRM_DEBUG("%s is disconnected\n", 106 drm_get_connector_name(connector)); 107 /* TODO set EDID to NULL */ 108 return 0; 109 } 110 111 count = (*connector_funcs->get_modes)(connector); 112 if (!count) 113 return 0; 114 115 drm_mode_connector_list_update(connector); 116 117 if (maxX && maxY) 118 drm_mode_validate_size(dev, &connector->modes, maxX, 119 maxY, 0); 120 121 if (connector->interlace_allowed) 122 mode_flags |= DRM_MODE_FLAG_INTERLACE; 123 if (connector->doublescan_allowed) 124 mode_flags |= DRM_MODE_FLAG_DBLSCAN; 125 drm_mode_validate_flag(connector, mode_flags); 126 127 list_for_each_entry_safe(mode, t, &connector->modes, head) { 128 if (mode->status == MODE_OK) 129 mode->status = connector_funcs->mode_valid(connector, 130 mode); 131 } 132 133 134 drm_mode_prune_invalid(dev, &connector->modes, true); 135 136 if (list_empty(&connector->modes)) 137 return 0; 138 139 drm_mode_sort(&connector->modes); 140 141 DRM_DEBUG("Probed modes for %s\n", drm_get_connector_name(connector)); 142 list_for_each_entry_safe(mode, t, &connector->modes, head) { 143 mode->vrefresh = drm_mode_vrefresh(mode); 144 145 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 146 drm_mode_debug_printmodeline(mode); 147 } 148 149 return count; 150 } 151 EXPORT_SYMBOL(drm_helper_probe_single_connector_modes); 152 153 int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, 154 uint32_t maxY) 155 { 156 struct drm_connector *connector; 157 int count = 0; 158 159 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 160 count += drm_helper_probe_single_connector_modes(connector, 161 maxX, maxY); 162 } 163 164 return count; 165 } 166 EXPORT_SYMBOL(drm_helper_probe_connector_modes); 167 168 static void drm_helper_add_std_modes(struct drm_device *dev, 169 struct drm_connector *connector) 170 { 171 struct drm_display_mode *mode, *t; 172 int i; 173 174 for (i = 0; i < ARRAY_SIZE(std_modes); i++) { 175 struct drm_display_mode *stdmode; 176 177 /* 178 * When no valid EDID modes are available we end up 179 * here and bailed in the past, now we add some standard 180 * modes and move on. 181 */ 182 stdmode = drm_mode_duplicate(dev, &std_modes[i]); 183 drm_mode_probed_add(connector, stdmode); 184 drm_mode_list_concat(&connector->probed_modes, 185 &connector->modes); 186 187 DRM_DEBUG("Adding mode %s to %s\n", stdmode->name, 188 drm_get_connector_name(connector)); 189 } 190 drm_mode_sort(&connector->modes); 191 192 DRM_DEBUG("Added std modes on %s\n", drm_get_connector_name(connector)); 193 list_for_each_entry_safe(mode, t, &connector->modes, head) { 194 mode->vrefresh = drm_mode_vrefresh(mode); 195 196 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 197 drm_mode_debug_printmodeline(mode); 198 } 199 } 200 201 /** 202 * drm_helper_encoder_in_use - check if a given encoder is in use 203 * @encoder: encoder to check 204 * 205 * LOCKING: 206 * Caller must hold mode config lock. 207 * 208 * Walk @encoders's DRM device's mode_config and see if it's in use. 209 * 210 * RETURNS: 211 * True if @encoder is part of the mode_config, false otherwise. 212 */ 213 bool drm_helper_encoder_in_use(struct drm_encoder *encoder) 214 { 215 struct drm_connector *connector; 216 struct drm_device *dev = encoder->dev; 217 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 218 if (connector->encoder == encoder) 219 return true; 220 return false; 221 } 222 EXPORT_SYMBOL(drm_helper_encoder_in_use); 223 224 /** 225 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config 226 * @crtc: CRTC to check 227 * 228 * LOCKING: 229 * Caller must hold mode config lock. 230 * 231 * Walk @crtc's DRM device's mode_config and see if it's in use. 232 * 233 * RETURNS: 234 * True if @crtc is part of the mode_config, false otherwise. 235 */ 236 bool drm_helper_crtc_in_use(struct drm_crtc *crtc) 237 { 238 struct drm_encoder *encoder; 239 struct drm_device *dev = crtc->dev; 240 /* FIXME: Locking around list access? */ 241 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) 242 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder)) 243 return true; 244 return false; 245 } 246 EXPORT_SYMBOL(drm_helper_crtc_in_use); 247 248 /** 249 * drm_disable_unused_functions - disable unused objects 250 * @dev: DRM device 251 * 252 * LOCKING: 253 * Caller must hold mode config lock. 254 * 255 * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled 256 * by calling its dpms function, which should power it off. 257 */ 258 void drm_helper_disable_unused_functions(struct drm_device *dev) 259 { 260 struct drm_encoder *encoder; 261 struct drm_encoder_helper_funcs *encoder_funcs; 262 struct drm_crtc *crtc; 263 264 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 265 encoder_funcs = encoder->helper_private; 266 if (!drm_helper_encoder_in_use(encoder)) 267 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); 268 } 269 270 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 271 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 272 crtc->enabled = drm_helper_crtc_in_use(crtc); 273 if (!crtc->enabled) { 274 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); 275 crtc->fb = NULL; 276 } 277 } 278 } 279 EXPORT_SYMBOL(drm_helper_disable_unused_functions); 280 281 static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *connector, int width, int height) 282 { 283 struct drm_display_mode *mode; 284 285 list_for_each_entry(mode, &connector->modes, head) { 286 if (drm_mode_width(mode) > width || 287 drm_mode_height(mode) > height) 288 continue; 289 if (mode->type & DRM_MODE_TYPE_PREFERRED) 290 return mode; 291 } 292 return NULL; 293 } 294 295 static bool drm_connector_enabled(struct drm_connector *connector, bool strict) 296 { 297 bool enable; 298 299 if (strict) { 300 enable = connector->status == connector_status_connected; 301 } else { 302 enable = connector->status != connector_status_disconnected; 303 } 304 return enable; 305 } 306 307 static void drm_enable_connectors(struct drm_device *dev, bool *enabled) 308 { 309 bool any_enabled = false; 310 struct drm_connector *connector; 311 int i = 0; 312 313 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 314 enabled[i] = drm_connector_enabled(connector, true); 315 DRM_DEBUG("connector %d enabled? %s\n", connector->base.id, 316 enabled[i] ? "yes" : "no"); 317 any_enabled |= enabled[i]; 318 i++; 319 } 320 321 if (any_enabled) 322 return; 323 324 i = 0; 325 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 326 enabled[i] = drm_connector_enabled(connector, false); 327 i++; 328 } 329 } 330 331 static bool drm_target_preferred(struct drm_device *dev, 332 struct drm_display_mode **modes, 333 bool *enabled, int width, int height) 334 { 335 struct drm_connector *connector; 336 int i = 0; 337 338 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 339 340 if (enabled[i] == false) { 341 i++; 342 continue; 343 } 344 345 DRM_DEBUG("looking for preferred mode on connector %d\n", 346 connector->base.id); 347 348 modes[i] = drm_has_preferred_mode(connector, width, height); 349 /* No preferred modes, pick one off the list */ 350 if (!modes[i] && !list_empty(&connector->modes)) { 351 list_for_each_entry(modes[i], &connector->modes, head) 352 break; 353 } 354 DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name : 355 "none"); 356 i++; 357 } 358 return true; 359 } 360 361 static int drm_pick_crtcs(struct drm_device *dev, 362 struct drm_crtc **best_crtcs, 363 struct drm_display_mode **modes, 364 int n, int width, int height) 365 { 366 int c, o; 367 struct drm_connector *connector; 368 struct drm_connector_helper_funcs *connector_funcs; 369 struct drm_encoder *encoder; 370 struct drm_crtc *best_crtc; 371 int my_score, best_score, score; 372 struct drm_crtc **crtcs, *crtc; 373 374 if (n == dev->mode_config.num_connector) 375 return 0; 376 c = 0; 377 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 378 if (c == n) 379 break; 380 c++; 381 } 382 383 best_crtcs[n] = NULL; 384 best_crtc = NULL; 385 best_score = drm_pick_crtcs(dev, best_crtcs, modes, n+1, width, height); 386 if (modes[n] == NULL) 387 return best_score; 388 389 crtcs = kmalloc(dev->mode_config.num_connector * 390 sizeof(struct drm_crtc *), GFP_KERNEL); 391 if (!crtcs) 392 return best_score; 393 394 my_score = 1; 395 if (connector->status == connector_status_connected) 396 my_score++; 397 if (drm_has_preferred_mode(connector, width, height)) 398 my_score++; 399 400 connector_funcs = connector->helper_private; 401 encoder = connector_funcs->best_encoder(connector); 402 if (!encoder) 403 goto out; 404 405 connector->encoder = encoder; 406 407 /* select a crtc for this connector and then attempt to configure 408 remaining connectors */ 409 c = 0; 410 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 411 412 if ((connector->encoder->possible_crtcs & (1 << c)) == 0) { 413 c++; 414 continue; 415 } 416 417 for (o = 0; o < n; o++) 418 if (best_crtcs[o] == crtc) 419 break; 420 421 if (o < n) { 422 /* ignore cloning for now */ 423 c++; 424 continue; 425 } 426 427 crtcs[n] = crtc; 428 memcpy(crtcs, best_crtcs, n * sizeof(struct drm_crtc *)); 429 score = my_score + drm_pick_crtcs(dev, crtcs, modes, n + 1, 430 width, height); 431 if (score > best_score) { 432 best_crtc = crtc; 433 best_score = score; 434 memcpy(best_crtcs, crtcs, 435 dev->mode_config.num_connector * 436 sizeof(struct drm_crtc *)); 437 } 438 c++; 439 } 440 out: 441 kfree(crtcs); 442 return best_score; 443 } 444 445 static void drm_setup_crtcs(struct drm_device *dev) 446 { 447 struct drm_crtc **crtcs; 448 struct drm_display_mode **modes; 449 struct drm_encoder *encoder; 450 struct drm_connector *connector; 451 bool *enabled; 452 int width, height; 453 int i, ret; 454 455 DRM_DEBUG("\n"); 456 457 width = dev->mode_config.max_width; 458 height = dev->mode_config.max_height; 459 460 /* clean out all the encoder/crtc combos */ 461 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 462 encoder->crtc = NULL; 463 } 464 465 crtcs = kcalloc(dev->mode_config.num_connector, 466 sizeof(struct drm_crtc *), GFP_KERNEL); 467 modes = kcalloc(dev->mode_config.num_connector, 468 sizeof(struct drm_display_mode *), GFP_KERNEL); 469 enabled = kcalloc(dev->mode_config.num_connector, 470 sizeof(bool), GFP_KERNEL); 471 472 drm_enable_connectors(dev, enabled); 473 474 ret = drm_target_preferred(dev, modes, enabled, width, height); 475 if (!ret) 476 DRM_ERROR("Unable to find initial modes\n"); 477 478 DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height); 479 480 drm_pick_crtcs(dev, crtcs, modes, 0, width, height); 481 482 i = 0; 483 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 484 struct drm_display_mode *mode = modes[i]; 485 struct drm_crtc *crtc = crtcs[i]; 486 487 if (connector->encoder == NULL) { 488 i++; 489 continue; 490 } 491 492 if (mode && crtc) { 493 DRM_DEBUG("desired mode %s set on crtc %d\n", 494 mode->name, crtc->base.id); 495 crtc->desired_mode = mode; 496 connector->encoder->crtc = crtc; 497 } else 498 connector->encoder->crtc = NULL; 499 i++; 500 } 501 502 kfree(crtcs); 503 kfree(modes); 504 kfree(enabled); 505 } 506 507 /** 508 * drm_encoder_crtc_ok - can a given crtc drive a given encoder? 509 * @encoder: encoder to test 510 * @crtc: crtc to test 511 * 512 * Return false if @encoder can't be driven by @crtc, true otherwise. 513 */ 514 static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, 515 struct drm_crtc *crtc) 516 { 517 struct drm_device *dev; 518 struct drm_crtc *tmp; 519 int crtc_mask = 1; 520 521 WARN(!crtc, "checking null crtc?"); 522 523 dev = crtc->dev; 524 525 list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { 526 if (tmp == crtc) 527 break; 528 crtc_mask <<= 1; 529 } 530 531 if (encoder->possible_crtcs & crtc_mask) 532 return true; 533 return false; 534 } 535 536 /* 537 * Check the CRTC we're going to map each output to vs. its current 538 * CRTC. If they don't match, we have to disable the output and the CRTC 539 * since the driver will have to re-route things. 540 */ 541 static void 542 drm_crtc_prepare_encoders(struct drm_device *dev) 543 { 544 struct drm_encoder_helper_funcs *encoder_funcs; 545 struct drm_encoder *encoder; 546 547 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 548 encoder_funcs = encoder->helper_private; 549 /* Disable unused encoders */ 550 if (encoder->crtc == NULL) 551 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); 552 /* Disable encoders whose CRTC is about to change */ 553 if (encoder_funcs->get_crtc && 554 encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) 555 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); 556 } 557 } 558 559 /** 560 * drm_crtc_set_mode - set a mode 561 * @crtc: CRTC to program 562 * @mode: mode to use 563 * @x: width of mode 564 * @y: height of mode 565 * 566 * LOCKING: 567 * Caller must hold mode config lock. 568 * 569 * Try to set @mode on @crtc. Give @crtc and its associated connectors a chance 570 * to fixup or reject the mode prior to trying to set it. 571 * 572 * RETURNS: 573 * True if the mode was set successfully, or false otherwise. 574 */ 575 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, 576 struct drm_display_mode *mode, 577 int x, int y, 578 struct drm_framebuffer *old_fb) 579 { 580 struct drm_device *dev = crtc->dev; 581 struct drm_display_mode *adjusted_mode, saved_mode; 582 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 583 struct drm_encoder_helper_funcs *encoder_funcs; 584 int saved_x, saved_y; 585 struct drm_encoder *encoder; 586 bool ret = true; 587 588 adjusted_mode = drm_mode_duplicate(dev, mode); 589 590 crtc->enabled = drm_helper_crtc_in_use(crtc); 591 592 if (!crtc->enabled) 593 return true; 594 595 saved_mode = crtc->mode; 596 saved_x = crtc->x; 597 saved_y = crtc->y; 598 599 /* Update crtc values up front so the driver can rely on them for mode 600 * setting. 601 */ 602 crtc->mode = *mode; 603 crtc->x = x; 604 crtc->y = y; 605 606 /* Pass our mode to the connectors and the CRTC to give them a chance to 607 * adjust it according to limitations or connector properties, and also 608 * a chance to reject the mode entirely. 609 */ 610 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 611 612 if (encoder->crtc != crtc) 613 continue; 614 encoder_funcs = encoder->helper_private; 615 if (!(ret = encoder_funcs->mode_fixup(encoder, mode, 616 adjusted_mode))) { 617 goto done; 618 } 619 } 620 621 if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { 622 goto done; 623 } 624 625 /* Prepare the encoders and CRTCs before setting the mode. */ 626 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 627 628 if (encoder->crtc != crtc) 629 continue; 630 encoder_funcs = encoder->helper_private; 631 /* Disable the encoders as the first thing we do. */ 632 encoder_funcs->prepare(encoder); 633 } 634 635 drm_crtc_prepare_encoders(dev); 636 637 crtc_funcs->prepare(crtc); 638 639 /* Set up the DPLL and any encoders state that needs to adjust or depend 640 * on the DPLL. 641 */ 642 ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); 643 if (!ret) 644 goto done; 645 646 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 647 648 if (encoder->crtc != crtc) 649 continue; 650 651 DRM_INFO("%s: set mode %s %x\n", drm_get_encoder_name(encoder), 652 mode->name, mode->base.id); 653 encoder_funcs = encoder->helper_private; 654 encoder_funcs->mode_set(encoder, mode, adjusted_mode); 655 } 656 657 /* Now enable the clocks, plane, pipe, and connectors that we set up. */ 658 crtc_funcs->commit(crtc); 659 660 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 661 662 if (encoder->crtc != crtc) 663 continue; 664 665 encoder_funcs = encoder->helper_private; 666 encoder_funcs->commit(encoder); 667 668 } 669 670 /* XXX free adjustedmode */ 671 drm_mode_destroy(dev, adjusted_mode); 672 /* FIXME: add subpixel order */ 673 done: 674 if (!ret) { 675 crtc->mode = saved_mode; 676 crtc->x = saved_x; 677 crtc->y = saved_y; 678 } 679 680 return ret; 681 } 682 EXPORT_SYMBOL(drm_crtc_helper_set_mode); 683 684 685 /** 686 * drm_crtc_helper_set_config - set a new config from userspace 687 * @crtc: CRTC to setup 688 * @crtc_info: user provided configuration 689 * @new_mode: new mode to set 690 * @connector_set: set of connectors for the new config 691 * @fb: new framebuffer 692 * 693 * LOCKING: 694 * Caller must hold mode config lock. 695 * 696 * Setup a new configuration, provided by the user in @crtc_info, and enable 697 * it. 698 * 699 * RETURNS: 700 * Zero. (FIXME) 701 */ 702 int drm_crtc_helper_set_config(struct drm_mode_set *set) 703 { 704 struct drm_device *dev; 705 struct drm_crtc **save_crtcs, *new_crtc; 706 struct drm_encoder **save_encoders, *new_encoder; 707 struct drm_framebuffer *old_fb = NULL; 708 bool save_enabled; 709 bool mode_changed = false; 710 bool fb_changed = false; 711 struct drm_connector *connector; 712 int count = 0, ro, fail = 0; 713 struct drm_crtc_helper_funcs *crtc_funcs; 714 int ret = 0; 715 716 DRM_DEBUG("\n"); 717 718 if (!set) 719 return -EINVAL; 720 721 if (!set->crtc) 722 return -EINVAL; 723 724 if (!set->crtc->helper_private) 725 return -EINVAL; 726 727 crtc_funcs = set->crtc->helper_private; 728 729 DRM_DEBUG("crtc: %p %d fb: %p connectors: %p num_connectors: %d (x, y) (%i, %i)\n", 730 set->crtc, set->crtc->base.id, set->fb, set->connectors, 731 (int)set->num_connectors, set->x, set->y); 732 733 dev = set->crtc->dev; 734 735 /* save previous config */ 736 save_enabled = set->crtc->enabled; 737 738 /* 739 * We do mode_config.num_connectors here since we'll look at the 740 * CRTC and encoder associated with each connector later. 741 */ 742 save_crtcs = kzalloc(dev->mode_config.num_connector * 743 sizeof(struct drm_crtc *), GFP_KERNEL); 744 if (!save_crtcs) 745 return -ENOMEM; 746 747 save_encoders = kzalloc(dev->mode_config.num_connector * 748 sizeof(struct drm_encoders *), GFP_KERNEL); 749 if (!save_encoders) { 750 kfree(save_crtcs); 751 return -ENOMEM; 752 } 753 754 /* We should be able to check here if the fb has the same properties 755 * and then just flip_or_move it */ 756 if (set->crtc->fb != set->fb) { 757 /* If we have no fb then treat it as a full mode set */ 758 if (set->crtc->fb == NULL) { 759 DRM_DEBUG("crtc has no fb, full mode set\n"); 760 mode_changed = true; 761 } else if ((set->fb->bits_per_pixel != 762 set->crtc->fb->bits_per_pixel) || 763 set->fb->depth != set->crtc->fb->depth) 764 fb_changed = true; 765 else 766 fb_changed = true; 767 } 768 769 if (set->x != set->crtc->x || set->y != set->crtc->y) 770 fb_changed = true; 771 772 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { 773 DRM_DEBUG("modes are different, full mode set\n"); 774 drm_mode_debug_printmodeline(&set->crtc->mode); 775 drm_mode_debug_printmodeline(set->mode); 776 mode_changed = true; 777 } 778 779 /* a) traverse passed in connector list and get encoders for them */ 780 count = 0; 781 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 782 struct drm_connector_helper_funcs *connector_funcs = 783 connector->helper_private; 784 save_encoders[count++] = connector->encoder; 785 new_encoder = connector->encoder; 786 for (ro = 0; ro < set->num_connectors; ro++) { 787 if (set->connectors[ro] == connector) { 788 new_encoder = connector_funcs->best_encoder(connector); 789 /* if we can't get an encoder for a connector 790 we are setting now - then fail */ 791 if (new_encoder == NULL) 792 /* don't break so fail path works correct */ 793 fail = 1; 794 break; 795 } 796 } 797 798 if (new_encoder != connector->encoder) { 799 DRM_DEBUG("encoder changed, full mode switch\n"); 800 mode_changed = true; 801 connector->encoder = new_encoder; 802 } 803 } 804 805 if (fail) { 806 ret = -EINVAL; 807 goto fail_no_encoder; 808 } 809 810 count = 0; 811 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 812 if (!connector->encoder) 813 continue; 814 815 save_crtcs[count++] = connector->encoder->crtc; 816 817 if (connector->encoder->crtc == set->crtc) 818 new_crtc = NULL; 819 else 820 new_crtc = connector->encoder->crtc; 821 822 for (ro = 0; ro < set->num_connectors; ro++) { 823 if (set->connectors[ro] == connector) 824 new_crtc = set->crtc; 825 } 826 827 /* Make sure the new CRTC will work with the encoder */ 828 if (new_crtc && 829 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { 830 ret = -EINVAL; 831 goto fail_set_mode; 832 } 833 if (new_crtc != connector->encoder->crtc) { 834 DRM_DEBUG("crtc changed, full mode switch\n"); 835 mode_changed = true; 836 connector->encoder->crtc = new_crtc; 837 } 838 DRM_DEBUG("setting connector %d crtc to %p\n", 839 connector->base.id, new_crtc); 840 } 841 842 /* mode_set_base is not a required function */ 843 if (fb_changed && !crtc_funcs->mode_set_base) 844 mode_changed = true; 845 846 if (mode_changed) { 847 old_fb = set->crtc->fb; 848 set->crtc->fb = set->fb; 849 set->crtc->enabled = (set->mode != NULL); 850 if (set->mode != NULL) { 851 DRM_DEBUG("attempting to set mode from userspace\n"); 852 drm_mode_debug_printmodeline(set->mode); 853 if (!drm_crtc_helper_set_mode(set->crtc, set->mode, 854 set->x, set->y, 855 old_fb)) { 856 DRM_ERROR("failed to set mode on crtc %p\n", 857 set->crtc); 858 ret = -EINVAL; 859 goto fail_set_mode; 860 } 861 /* TODO are these needed? */ 862 set->crtc->desired_x = set->x; 863 set->crtc->desired_y = set->y; 864 set->crtc->desired_mode = set->mode; 865 } 866 drm_helper_disable_unused_functions(dev); 867 } else if (fb_changed) { 868 old_fb = set->crtc->fb; 869 if (set->crtc->fb != set->fb) 870 set->crtc->fb = set->fb; 871 ret = crtc_funcs->mode_set_base(set->crtc, 872 set->x, set->y, old_fb); 873 if (ret != 0) 874 goto fail_set_mode; 875 } 876 877 kfree(save_encoders); 878 kfree(save_crtcs); 879 return 0; 880 881 fail_set_mode: 882 set->crtc->enabled = save_enabled; 883 set->crtc->fb = old_fb; 884 count = 0; 885 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 886 if (!connector->encoder) 887 continue; 888 889 connector->encoder->crtc = save_crtcs[count++]; 890 } 891 fail_no_encoder: 892 kfree(save_crtcs); 893 count = 0; 894 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 895 connector->encoder = save_encoders[count++]; 896 } 897 kfree(save_encoders); 898 return ret; 899 } 900 EXPORT_SYMBOL(drm_crtc_helper_set_config); 901 902 bool drm_helper_plugged_event(struct drm_device *dev) 903 { 904 DRM_DEBUG("\n"); 905 906 drm_helper_probe_connector_modes(dev, dev->mode_config.max_width, 907 dev->mode_config.max_height); 908 909 drm_setup_crtcs(dev); 910 911 /* alert the driver fb layer */ 912 dev->mode_config.funcs->fb_changed(dev); 913 914 /* FIXME: send hotplug event */ 915 return true; 916 } 917 /** 918 * drm_initial_config - setup a sane initial connector configuration 919 * @dev: DRM device 920 * 921 * LOCKING: 922 * Called at init time, must take mode config lock. 923 * 924 * Scan the CRTCs and connectors and try to put together an initial setup. 925 * At the moment, this is a cloned configuration across all heads with 926 * a new framebuffer object as the backing store. 927 * 928 * RETURNS: 929 * Zero if everything went ok, nonzero otherwise. 930 */ 931 bool drm_helper_initial_config(struct drm_device *dev) 932 { 933 struct drm_connector *connector; 934 int count = 0; 935 936 count = drm_helper_probe_connector_modes(dev, 937 dev->mode_config.max_width, 938 dev->mode_config.max_height); 939 940 /* 941 * None of the available connectors had any modes, so add some 942 * and try to light them up anyway 943 */ 944 if (!count) { 945 DRM_ERROR("connectors have no modes, using standard modes\n"); 946 list_for_each_entry(connector, 947 &dev->mode_config.connector_list, 948 head) 949 drm_helper_add_std_modes(dev, connector); 950 } 951 952 drm_setup_crtcs(dev); 953 954 /* alert the driver fb layer */ 955 dev->mode_config.funcs->fb_changed(dev); 956 957 return 0; 958 } 959 EXPORT_SYMBOL(drm_helper_initial_config); 960 961 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder) 962 { 963 int dpms = DRM_MODE_DPMS_OFF; 964 struct drm_connector *connector; 965 struct drm_device *dev = encoder->dev; 966 967 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 968 if (connector->encoder == encoder) 969 if (connector->dpms < dpms) 970 dpms = connector->dpms; 971 return dpms; 972 } 973 974 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) 975 { 976 int dpms = DRM_MODE_DPMS_OFF; 977 struct drm_connector *connector; 978 struct drm_device *dev = crtc->dev; 979 980 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 981 if (connector->encoder && connector->encoder->crtc == crtc) 982 if (connector->dpms < dpms) 983 dpms = connector->dpms; 984 return dpms; 985 } 986 987 /** 988 * drm_helper_connector_dpms 989 * @connector affected connector 990 * @mode DPMS mode 991 * 992 * Calls the low-level connector DPMS function, then 993 * calls appropriate encoder and crtc DPMS functions as well 994 */ 995 void drm_helper_connector_dpms(struct drm_connector *connector, int mode) 996 { 997 struct drm_encoder *encoder = connector->encoder; 998 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; 999 int old_dpms; 1000 1001 if (mode == connector->dpms) 1002 return; 1003 1004 old_dpms = connector->dpms; 1005 connector->dpms = mode; 1006 1007 /* from off to on, do crtc then encoder */ 1008 if (mode < old_dpms) { 1009 if (crtc) { 1010 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 1011 if (crtc_funcs->dpms) 1012 (*crtc_funcs->dpms) (crtc, 1013 drm_helper_choose_crtc_dpms(crtc)); 1014 } 1015 if (encoder) { 1016 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; 1017 if (encoder_funcs->dpms) 1018 (*encoder_funcs->dpms) (encoder, 1019 drm_helper_choose_encoder_dpms(encoder)); 1020 } 1021 } 1022 1023 /* from on to off, do encoder then crtc */ 1024 if (mode > old_dpms) { 1025 if (encoder) { 1026 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; 1027 if (encoder_funcs->dpms) 1028 (*encoder_funcs->dpms) (encoder, 1029 drm_helper_choose_encoder_dpms(encoder)); 1030 } 1031 if (crtc) { 1032 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 1033 if (crtc_funcs->dpms) 1034 (*crtc_funcs->dpms) (crtc, 1035 drm_helper_choose_crtc_dpms(crtc)); 1036 } 1037 } 1038 1039 return; 1040 } 1041 EXPORT_SYMBOL(drm_helper_connector_dpms); 1042 1043 /** 1044 * drm_hotplug_stage_two 1045 * @dev DRM device 1046 * @connector hotpluged connector 1047 * 1048 * LOCKING. 1049 * Caller must hold mode config lock, function might grab struct lock. 1050 * 1051 * Stage two of a hotplug. 1052 * 1053 * RETURNS: 1054 * Zero on success, errno on failure. 1055 */ 1056 int drm_helper_hotplug_stage_two(struct drm_device *dev) 1057 { 1058 drm_helper_plugged_event(dev); 1059 1060 return 0; 1061 } 1062 EXPORT_SYMBOL(drm_helper_hotplug_stage_two); 1063 1064 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, 1065 struct drm_mode_fb_cmd *mode_cmd) 1066 { 1067 fb->width = mode_cmd->width; 1068 fb->height = mode_cmd->height; 1069 fb->pitch = mode_cmd->pitch; 1070 fb->bits_per_pixel = mode_cmd->bpp; 1071 fb->depth = mode_cmd->depth; 1072 1073 return 0; 1074 } 1075 EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct); 1076 1077 int drm_helper_resume_force_mode(struct drm_device *dev) 1078 { 1079 struct drm_crtc *crtc; 1080 int ret; 1081 1082 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 1083 1084 if (!crtc->enabled) 1085 continue; 1086 1087 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, 1088 crtc->x, crtc->y, crtc->fb); 1089 1090 if (ret == false) 1091 DRM_ERROR("failed to set mode on crtc %p\n", crtc); 1092 } 1093 return 0; 1094 } 1095 EXPORT_SYMBOL(drm_helper_resume_force_mode); 1096