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_crtc_in_use - check if a given CRTC is in a mode_config 203 * @crtc: CRTC to check 204 * 205 * LOCKING: 206 * Caller must hold mode config lock. 207 * 208 * Walk @crtc's DRM device's mode_config and see if it's in use. 209 * 210 * RETURNS: 211 * True if @crtc is part of the mode_config, false otherwise. 212 */ 213 bool drm_helper_crtc_in_use(struct drm_crtc *crtc) 214 { 215 struct drm_encoder *encoder; 216 struct drm_device *dev = crtc->dev; 217 /* FIXME: Locking around list access? */ 218 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) 219 if (encoder->crtc == crtc) 220 return true; 221 return false; 222 } 223 EXPORT_SYMBOL(drm_helper_crtc_in_use); 224 225 /** 226 * drm_disable_unused_functions - disable unused objects 227 * @dev: DRM device 228 * 229 * LOCKING: 230 * Caller must hold mode config lock. 231 * 232 * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled 233 * by calling its dpms function, which should power it off. 234 */ 235 void drm_helper_disable_unused_functions(struct drm_device *dev) 236 { 237 struct drm_encoder *encoder; 238 struct drm_encoder_helper_funcs *encoder_funcs; 239 struct drm_crtc *crtc; 240 241 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 242 encoder_funcs = encoder->helper_private; 243 if (!encoder->crtc) 244 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); 245 } 246 247 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 248 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 249 crtc->enabled = drm_helper_crtc_in_use(crtc); 250 if (!crtc->enabled) { 251 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); 252 crtc->fb = NULL; 253 } 254 } 255 } 256 EXPORT_SYMBOL(drm_helper_disable_unused_functions); 257 258 static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *connector, int width, int height) 259 { 260 struct drm_display_mode *mode; 261 262 list_for_each_entry(mode, &connector->modes, head) { 263 if (drm_mode_width(mode) > width || 264 drm_mode_height(mode) > height) 265 continue; 266 if (mode->type & DRM_MODE_TYPE_PREFERRED) 267 return mode; 268 } 269 return NULL; 270 } 271 272 static bool drm_connector_enabled(struct drm_connector *connector, bool strict) 273 { 274 bool enable; 275 276 if (strict) { 277 enable = connector->status == connector_status_connected; 278 } else { 279 enable = connector->status != connector_status_disconnected; 280 } 281 return enable; 282 } 283 284 static void drm_enable_connectors(struct drm_device *dev, bool *enabled) 285 { 286 bool any_enabled = false; 287 struct drm_connector *connector; 288 int i = 0; 289 290 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 291 enabled[i] = drm_connector_enabled(connector, true); 292 DRM_DEBUG("connector %d enabled? %s\n", connector->base.id, 293 enabled[i] ? "yes" : "no"); 294 any_enabled |= enabled[i]; 295 i++; 296 } 297 298 if (any_enabled) 299 return; 300 301 i = 0; 302 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 303 enabled[i] = drm_connector_enabled(connector, false); 304 i++; 305 } 306 } 307 308 static bool drm_target_preferred(struct drm_device *dev, 309 struct drm_display_mode **modes, 310 bool *enabled, int width, int height) 311 { 312 struct drm_connector *connector; 313 int i = 0; 314 315 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 316 317 if (enabled[i] == false) { 318 i++; 319 continue; 320 } 321 322 DRM_DEBUG("looking for preferred mode on connector %d\n", 323 connector->base.id); 324 325 modes[i] = drm_has_preferred_mode(connector, width, height); 326 /* No preferred modes, pick one off the list */ 327 if (!modes[i] && !list_empty(&connector->modes)) { 328 list_for_each_entry(modes[i], &connector->modes, head) 329 break; 330 } 331 DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name : 332 "none"); 333 i++; 334 } 335 return true; 336 } 337 338 static int drm_pick_crtcs(struct drm_device *dev, 339 struct drm_crtc **best_crtcs, 340 struct drm_display_mode **modes, 341 int n, int width, int height) 342 { 343 int c, o; 344 struct drm_connector *connector; 345 struct drm_connector_helper_funcs *connector_funcs; 346 struct drm_encoder *encoder; 347 struct drm_crtc *best_crtc; 348 int my_score, best_score, score; 349 struct drm_crtc **crtcs, *crtc; 350 351 if (n == dev->mode_config.num_connector) 352 return 0; 353 c = 0; 354 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 355 if (c == n) 356 break; 357 c++; 358 } 359 360 best_crtcs[n] = NULL; 361 best_crtc = NULL; 362 best_score = drm_pick_crtcs(dev, best_crtcs, modes, n+1, width, height); 363 if (modes[n] == NULL) 364 return best_score; 365 366 crtcs = kmalloc(dev->mode_config.num_connector * 367 sizeof(struct drm_crtc *), GFP_KERNEL); 368 if (!crtcs) 369 return best_score; 370 371 my_score = 1; 372 if (connector->status == connector_status_connected) 373 my_score++; 374 if (drm_has_preferred_mode(connector, width, height)) 375 my_score++; 376 377 connector_funcs = connector->helper_private; 378 encoder = connector_funcs->best_encoder(connector); 379 if (!encoder) 380 goto out; 381 382 connector->encoder = encoder; 383 384 /* select a crtc for this connector and then attempt to configure 385 remaining connectors */ 386 c = 0; 387 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 388 389 if ((connector->encoder->possible_crtcs & (1 << c)) == 0) { 390 c++; 391 continue; 392 } 393 394 for (o = 0; o < n; o++) 395 if (best_crtcs[o] == crtc) 396 break; 397 398 if (o < n) { 399 /* ignore cloning for now */ 400 c++; 401 continue; 402 } 403 404 crtcs[n] = crtc; 405 memcpy(crtcs, best_crtcs, n * sizeof(struct drm_crtc *)); 406 score = my_score + drm_pick_crtcs(dev, crtcs, modes, n + 1, 407 width, height); 408 if (score > best_score) { 409 best_crtc = crtc; 410 best_score = score; 411 memcpy(best_crtcs, crtcs, 412 dev->mode_config.num_connector * 413 sizeof(struct drm_crtc *)); 414 } 415 c++; 416 } 417 out: 418 kfree(crtcs); 419 return best_score; 420 } 421 422 static void drm_setup_crtcs(struct drm_device *dev) 423 { 424 struct drm_crtc **crtcs; 425 struct drm_display_mode **modes; 426 struct drm_encoder *encoder; 427 struct drm_connector *connector; 428 bool *enabled; 429 int width, height; 430 int i, ret; 431 432 DRM_DEBUG("\n"); 433 434 width = dev->mode_config.max_width; 435 height = dev->mode_config.max_height; 436 437 /* clean out all the encoder/crtc combos */ 438 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 439 encoder->crtc = NULL; 440 } 441 442 crtcs = kcalloc(dev->mode_config.num_connector, 443 sizeof(struct drm_crtc *), GFP_KERNEL); 444 modes = kcalloc(dev->mode_config.num_connector, 445 sizeof(struct drm_display_mode *), GFP_KERNEL); 446 enabled = kcalloc(dev->mode_config.num_connector, 447 sizeof(bool), GFP_KERNEL); 448 449 drm_enable_connectors(dev, enabled); 450 451 ret = drm_target_preferred(dev, modes, enabled, width, height); 452 if (!ret) 453 DRM_ERROR("Unable to find initial modes\n"); 454 455 DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height); 456 457 drm_pick_crtcs(dev, crtcs, modes, 0, width, height); 458 459 i = 0; 460 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 461 struct drm_display_mode *mode = modes[i]; 462 struct drm_crtc *crtc = crtcs[i]; 463 464 if (connector->encoder == NULL) { 465 i++; 466 continue; 467 } 468 469 if (mode && crtc) { 470 DRM_DEBUG("desired mode %s set on crtc %d\n", 471 mode->name, crtc->base.id); 472 crtc->desired_mode = mode; 473 connector->encoder->crtc = crtc; 474 } else 475 connector->encoder->crtc = NULL; 476 i++; 477 } 478 479 kfree(crtcs); 480 kfree(modes); 481 kfree(enabled); 482 } 483 484 /** 485 * drm_encoder_crtc_ok - can a given crtc drive a given encoder? 486 * @encoder: encoder to test 487 * @crtc: crtc to test 488 * 489 * Return false if @encoder can't be driven by @crtc, true otherwise. 490 */ 491 static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, 492 struct drm_crtc *crtc) 493 { 494 struct drm_device *dev; 495 struct drm_crtc *tmp; 496 int crtc_mask = 1; 497 498 WARN(!crtc, "checking null crtc?"); 499 500 dev = crtc->dev; 501 502 list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { 503 if (tmp == crtc) 504 break; 505 crtc_mask <<= 1; 506 } 507 508 if (encoder->possible_crtcs & crtc_mask) 509 return true; 510 return false; 511 } 512 513 /* 514 * Check the CRTC we're going to map each output to vs. its current 515 * CRTC. If they don't match, we have to disable the output and the CRTC 516 * since the driver will have to re-route things. 517 */ 518 static void 519 drm_crtc_prepare_encoders(struct drm_device *dev) 520 { 521 struct drm_encoder_helper_funcs *encoder_funcs; 522 struct drm_encoder *encoder; 523 524 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 525 encoder_funcs = encoder->helper_private; 526 /* Disable unused encoders */ 527 if (encoder->crtc == NULL) 528 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); 529 /* Disable encoders whose CRTC is about to change */ 530 if (encoder_funcs->get_crtc && 531 encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) 532 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); 533 } 534 } 535 536 /** 537 * drm_crtc_set_mode - set a mode 538 * @crtc: CRTC to program 539 * @mode: mode to use 540 * @x: width of mode 541 * @y: height of mode 542 * 543 * LOCKING: 544 * Caller must hold mode config lock. 545 * 546 * Try to set @mode on @crtc. Give @crtc and its associated connectors a chance 547 * to fixup or reject the mode prior to trying to set it. 548 * 549 * RETURNS: 550 * True if the mode was set successfully, or false otherwise. 551 */ 552 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, 553 struct drm_display_mode *mode, 554 int x, int y, 555 struct drm_framebuffer *old_fb) 556 { 557 struct drm_device *dev = crtc->dev; 558 struct drm_display_mode *adjusted_mode, saved_mode; 559 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 560 struct drm_encoder_helper_funcs *encoder_funcs; 561 int saved_x, saved_y; 562 struct drm_encoder *encoder; 563 bool ret = true; 564 bool depth_changed, bpp_changed; 565 566 adjusted_mode = drm_mode_duplicate(dev, mode); 567 568 crtc->enabled = drm_helper_crtc_in_use(crtc); 569 570 if (!crtc->enabled) 571 return true; 572 573 if (old_fb && crtc->fb) { 574 depth_changed = (old_fb->depth != crtc->fb->depth); 575 bpp_changed = (old_fb->bits_per_pixel != 576 crtc->fb->bits_per_pixel); 577 } else { 578 depth_changed = true; 579 bpp_changed = true; 580 } 581 582 saved_mode = crtc->mode; 583 saved_x = crtc->x; 584 saved_y = crtc->y; 585 586 /* Update crtc values up front so the driver can rely on them for mode 587 * setting. 588 */ 589 crtc->mode = *mode; 590 crtc->x = x; 591 crtc->y = y; 592 593 if (drm_mode_equal(&saved_mode, &crtc->mode)) { 594 if (saved_x != crtc->x || saved_y != crtc->y || 595 depth_changed || bpp_changed) { 596 ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, 597 old_fb); 598 goto done; 599 } 600 } 601 602 /* Pass our mode to the connectors and the CRTC to give them a chance to 603 * adjust it according to limitations or connector properties, and also 604 * a chance to reject the mode entirely. 605 */ 606 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 607 608 if (encoder->crtc != crtc) 609 continue; 610 encoder_funcs = encoder->helper_private; 611 if (!(ret = encoder_funcs->mode_fixup(encoder, mode, 612 adjusted_mode))) { 613 goto done; 614 } 615 } 616 617 if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { 618 goto done; 619 } 620 621 /* Prepare the encoders and CRTCs before setting the mode. */ 622 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 623 624 if (encoder->crtc != crtc) 625 continue; 626 encoder_funcs = encoder->helper_private; 627 /* Disable the encoders as the first thing we do. */ 628 encoder_funcs->prepare(encoder); 629 } 630 631 drm_crtc_prepare_encoders(dev); 632 633 crtc_funcs->prepare(crtc); 634 635 /* Set up the DPLL and any encoders state that needs to adjust or depend 636 * on the DPLL. 637 */ 638 ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); 639 if (!ret) 640 goto done; 641 642 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 643 644 if (encoder->crtc != crtc) 645 continue; 646 647 DRM_INFO("%s: set mode %s %x\n", drm_get_encoder_name(encoder), 648 mode->name, mode->base.id); 649 encoder_funcs = encoder->helper_private; 650 encoder_funcs->mode_set(encoder, mode, adjusted_mode); 651 } 652 653 /* Now enable the clocks, plane, pipe, and connectors that we set up. */ 654 crtc_funcs->commit(crtc); 655 656 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 657 658 if (encoder->crtc != crtc) 659 continue; 660 661 encoder_funcs = encoder->helper_private; 662 encoder_funcs->commit(encoder); 663 664 } 665 666 /* XXX free adjustedmode */ 667 drm_mode_destroy(dev, adjusted_mode); 668 /* FIXME: add subpixel order */ 669 done: 670 if (!ret) { 671 crtc->mode = saved_mode; 672 crtc->x = saved_x; 673 crtc->y = saved_y; 674 } 675 676 return ret; 677 } 678 EXPORT_SYMBOL(drm_crtc_helper_set_mode); 679 680 681 /** 682 * drm_crtc_helper_set_config - set a new config from userspace 683 * @crtc: CRTC to setup 684 * @crtc_info: user provided configuration 685 * @new_mode: new mode to set 686 * @connector_set: set of connectors for the new config 687 * @fb: new framebuffer 688 * 689 * LOCKING: 690 * Caller must hold mode config lock. 691 * 692 * Setup a new configuration, provided by the user in @crtc_info, and enable 693 * it. 694 * 695 * RETURNS: 696 * Zero. (FIXME) 697 */ 698 int drm_crtc_helper_set_config(struct drm_mode_set *set) 699 { 700 struct drm_device *dev; 701 struct drm_crtc **save_crtcs, *new_crtc; 702 struct drm_encoder **save_encoders, *new_encoder; 703 struct drm_framebuffer *old_fb = NULL; 704 bool save_enabled; 705 bool mode_changed = false; 706 bool fb_changed = false; 707 struct drm_connector *connector; 708 int count = 0, ro, fail = 0; 709 struct drm_crtc_helper_funcs *crtc_funcs; 710 int ret = 0; 711 712 DRM_DEBUG("\n"); 713 714 if (!set) 715 return -EINVAL; 716 717 if (!set->crtc) 718 return -EINVAL; 719 720 if (!set->crtc->helper_private) 721 return -EINVAL; 722 723 crtc_funcs = set->crtc->helper_private; 724 725 DRM_DEBUG("crtc: %p %d fb: %p connectors: %p num_connectors: %d (x, y) (%i, %i)\n", 726 set->crtc, set->crtc->base.id, set->fb, set->connectors, 727 (int)set->num_connectors, set->x, set->y); 728 729 dev = set->crtc->dev; 730 731 /* save previous config */ 732 save_enabled = set->crtc->enabled; 733 734 /* 735 * We do mode_config.num_connectors here since we'll look at the 736 * CRTC and encoder associated with each connector later. 737 */ 738 save_crtcs = kzalloc(dev->mode_config.num_connector * 739 sizeof(struct drm_crtc *), GFP_KERNEL); 740 if (!save_crtcs) 741 return -ENOMEM; 742 743 save_encoders = kzalloc(dev->mode_config.num_connector * 744 sizeof(struct drm_encoders *), GFP_KERNEL); 745 if (!save_encoders) { 746 kfree(save_crtcs); 747 return -ENOMEM; 748 } 749 750 /* We should be able to check here if the fb has the same properties 751 * and then just flip_or_move it */ 752 if (set->crtc->fb != set->fb) { 753 /* If we have no fb then treat it as a full mode set */ 754 if (set->crtc->fb == NULL) { 755 DRM_DEBUG("crtc has no fb, full mode set\n"); 756 mode_changed = true; 757 } else if ((set->fb->bits_per_pixel != 758 set->crtc->fb->bits_per_pixel) || 759 set->fb->depth != set->crtc->fb->depth) 760 fb_changed = true; 761 else 762 fb_changed = true; 763 } 764 765 if (set->x != set->crtc->x || set->y != set->crtc->y) 766 fb_changed = true; 767 768 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { 769 DRM_DEBUG("modes are different, full mode set\n"); 770 drm_mode_debug_printmodeline(&set->crtc->mode); 771 drm_mode_debug_printmodeline(set->mode); 772 mode_changed = true; 773 } 774 775 /* a) traverse passed in connector list and get encoders for them */ 776 count = 0; 777 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 778 struct drm_connector_helper_funcs *connector_funcs = 779 connector->helper_private; 780 save_encoders[count++] = connector->encoder; 781 new_encoder = connector->encoder; 782 for (ro = 0; ro < set->num_connectors; ro++) { 783 if (set->connectors[ro] == connector) { 784 new_encoder = connector_funcs->best_encoder(connector); 785 /* if we can't get an encoder for a connector 786 we are setting now - then fail */ 787 if (new_encoder == NULL) 788 /* don't break so fail path works correct */ 789 fail = 1; 790 break; 791 } 792 } 793 794 if (new_encoder != connector->encoder) { 795 DRM_DEBUG("encoder changed, full mode switch\n"); 796 mode_changed = true; 797 connector->encoder = new_encoder; 798 } 799 } 800 801 if (fail) { 802 ret = -EINVAL; 803 goto fail_no_encoder; 804 } 805 806 count = 0; 807 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 808 if (!connector->encoder) 809 continue; 810 811 save_crtcs[count++] = connector->encoder->crtc; 812 813 if (connector->encoder->crtc == set->crtc) 814 new_crtc = NULL; 815 else 816 new_crtc = connector->encoder->crtc; 817 818 for (ro = 0; ro < set->num_connectors; ro++) { 819 if (set->connectors[ro] == connector) 820 new_crtc = set->crtc; 821 } 822 823 /* Make sure the new CRTC will work with the encoder */ 824 if (new_crtc && 825 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { 826 ret = -EINVAL; 827 goto fail_set_mode; 828 } 829 if (new_crtc != connector->encoder->crtc) { 830 DRM_DEBUG("crtc changed, full mode switch\n"); 831 mode_changed = true; 832 connector->encoder->crtc = new_crtc; 833 } 834 DRM_DEBUG("setting connector %d crtc to %p\n", 835 connector->base.id, new_crtc); 836 } 837 838 /* mode_set_base is not a required function */ 839 if (fb_changed && !crtc_funcs->mode_set_base) 840 mode_changed = true; 841 842 if (mode_changed) { 843 old_fb = set->crtc->fb; 844 set->crtc->fb = set->fb; 845 set->crtc->enabled = (set->mode != NULL); 846 if (set->mode != NULL) { 847 DRM_DEBUG("attempting to set mode from userspace\n"); 848 drm_mode_debug_printmodeline(set->mode); 849 if (!drm_crtc_helper_set_mode(set->crtc, set->mode, 850 set->x, set->y, 851 old_fb)) { 852 DRM_ERROR("failed to set mode on crtc %p\n", 853 set->crtc); 854 ret = -EINVAL; 855 goto fail_set_mode; 856 } 857 /* TODO are these needed? */ 858 set->crtc->desired_x = set->x; 859 set->crtc->desired_y = set->y; 860 set->crtc->desired_mode = set->mode; 861 } 862 drm_helper_disable_unused_functions(dev); 863 } else if (fb_changed) { 864 old_fb = set->crtc->fb; 865 if (set->crtc->fb != set->fb) 866 set->crtc->fb = set->fb; 867 ret = crtc_funcs->mode_set_base(set->crtc, 868 set->x, set->y, old_fb); 869 if (ret != 0) 870 goto fail_set_mode; 871 } 872 873 kfree(save_encoders); 874 kfree(save_crtcs); 875 return 0; 876 877 fail_set_mode: 878 set->crtc->enabled = save_enabled; 879 set->crtc->fb = old_fb; 880 count = 0; 881 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 882 if (!connector->encoder) 883 continue; 884 885 connector->encoder->crtc = save_crtcs[count++]; 886 } 887 fail_no_encoder: 888 kfree(save_crtcs); 889 count = 0; 890 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 891 connector->encoder = save_encoders[count++]; 892 } 893 kfree(save_encoders); 894 return ret; 895 } 896 EXPORT_SYMBOL(drm_crtc_helper_set_config); 897 898 bool drm_helper_plugged_event(struct drm_device *dev) 899 { 900 DRM_DEBUG("\n"); 901 902 drm_helper_probe_connector_modes(dev, dev->mode_config.max_width, 903 dev->mode_config.max_height); 904 905 drm_setup_crtcs(dev); 906 907 /* alert the driver fb layer */ 908 dev->mode_config.funcs->fb_changed(dev); 909 910 /* FIXME: send hotplug event */ 911 return true; 912 } 913 /** 914 * drm_initial_config - setup a sane initial connector configuration 915 * @dev: DRM device 916 * 917 * LOCKING: 918 * Called at init time, must take mode config lock. 919 * 920 * Scan the CRTCs and connectors and try to put together an initial setup. 921 * At the moment, this is a cloned configuration across all heads with 922 * a new framebuffer object as the backing store. 923 * 924 * RETURNS: 925 * Zero if everything went ok, nonzero otherwise. 926 */ 927 bool drm_helper_initial_config(struct drm_device *dev) 928 { 929 struct drm_connector *connector; 930 int count = 0; 931 932 count = drm_helper_probe_connector_modes(dev, 933 dev->mode_config.max_width, 934 dev->mode_config.max_height); 935 936 /* 937 * None of the available connectors had any modes, so add some 938 * and try to light them up anyway 939 */ 940 if (!count) { 941 DRM_ERROR("connectors have no modes, using standard modes\n"); 942 list_for_each_entry(connector, 943 &dev->mode_config.connector_list, 944 head) 945 drm_helper_add_std_modes(dev, connector); 946 } 947 948 drm_setup_crtcs(dev); 949 950 /* alert the driver fb layer */ 951 dev->mode_config.funcs->fb_changed(dev); 952 953 return 0; 954 } 955 EXPORT_SYMBOL(drm_helper_initial_config); 956 957 /** 958 * drm_hotplug_stage_two 959 * @dev DRM device 960 * @connector hotpluged connector 961 * 962 * LOCKING. 963 * Caller must hold mode config lock, function might grab struct lock. 964 * 965 * Stage two of a hotplug. 966 * 967 * RETURNS: 968 * Zero on success, errno on failure. 969 */ 970 int drm_helper_hotplug_stage_two(struct drm_device *dev) 971 { 972 drm_helper_plugged_event(dev); 973 974 return 0; 975 } 976 EXPORT_SYMBOL(drm_helper_hotplug_stage_two); 977 978 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, 979 struct drm_mode_fb_cmd *mode_cmd) 980 { 981 fb->width = mode_cmd->width; 982 fb->height = mode_cmd->height; 983 fb->pitch = mode_cmd->pitch; 984 fb->bits_per_pixel = mode_cmd->bpp; 985 fb->depth = mode_cmd->depth; 986 987 return 0; 988 } 989 EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct); 990 991 int drm_helper_resume_force_mode(struct drm_device *dev) 992 { 993 struct drm_crtc *crtc; 994 int ret; 995 996 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 997 998 if (!crtc->enabled) 999 continue; 1000 1001 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, 1002 crtc->x, crtc->y, crtc->fb); 1003 1004 if (ret == false) 1005 DRM_ERROR("failed to set mode on crtc %p\n", crtc); 1006 } 1007 return 0; 1008 } 1009 EXPORT_SYMBOL(drm_helper_resume_force_mode); 1010