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 <linux/kernel.h> 33 #include <linux/export.h> 34 #include <linux/module.h> 35 #include <linux/moduleparam.h> 36 #include <asm/param.h> 37 #include <asm/bug.h> 38 39 #include <drm/drmP.h> 40 #include <drm/drm_crtc.h> 41 #include <drm/drm_fourcc.h> 42 #include <drm/drm_crtc_helper.h> 43 #ifndef __NetBSD__ 44 #include <drm/drm_fb_helper.h> 45 #endif 46 #include <drm/drm_edid.h> 47 48 MODULE_AUTHOR("David Airlie, Jesse Barnes"); 49 MODULE_DESCRIPTION("DRM KMS helper"); 50 MODULE_LICENSE("GPL and additional rights"); 51 52 /** 53 * drm_helper_move_panel_connectors_to_head() - move panels to the front in the 54 * connector list 55 * @dev: drm device to operate on 56 * 57 * Some userspace presumes that the first connected connector is the main 58 * display, where it's supposed to display e.g. the login screen. For 59 * laptops, this should be the main panel. Use this function to sort all 60 * (eDP/LVDS) panels to the front of the connector list, instead of 61 * painstakingly trying to initialize them in the right order. 62 */ 63 void drm_helper_move_panel_connectors_to_head(struct drm_device *dev) 64 { 65 struct drm_connector *connector, *tmp; 66 struct list_head panel_list; 67 68 INIT_LIST_HEAD(&panel_list); 69 70 list_for_each_entry_safe(connector, tmp, 71 &dev->mode_config.connector_list, head) { 72 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS || 73 connector->connector_type == DRM_MODE_CONNECTOR_eDP) 74 list_move_tail(&connector->head, &panel_list); 75 } 76 77 list_splice(&panel_list, &dev->mode_config.connector_list); 78 } 79 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head); 80 81 /** 82 * drm_helper_encoder_in_use - check if a given encoder is in use 83 * @encoder: encoder to check 84 * 85 * Checks whether @encoder is with the current mode setting output configuration 86 * in use by any connector. This doesn't mean that it is actually enabled since 87 * the DPMS state is tracked separately. 88 * 89 * Returns: 90 * True if @encoder is used, false otherwise. 91 */ 92 bool drm_helper_encoder_in_use(struct drm_encoder *encoder) 93 { 94 struct drm_connector *connector; 95 struct drm_device *dev = encoder->dev; 96 97 /* 98 * We can expect this mutex to be locked if we are not panicking. 99 * Locking is currently fubar in the panic handler. 100 */ 101 if (!oops_in_progress) 102 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); 103 104 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 105 if (connector->encoder == encoder) 106 return true; 107 return false; 108 } 109 EXPORT_SYMBOL(drm_helper_encoder_in_use); 110 111 /** 112 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config 113 * @crtc: CRTC to check 114 * 115 * Checks whether @crtc is with the current mode setting output configuration 116 * in use by any connector. This doesn't mean that it is actually enabled since 117 * the DPMS state is tracked separately. 118 * 119 * Returns: 120 * True if @crtc is used, false otherwise. 121 */ 122 bool drm_helper_crtc_in_use(struct drm_crtc *crtc) 123 { 124 struct drm_encoder *encoder; 125 struct drm_device *dev = crtc->dev; 126 127 /* 128 * We can expect this mutex to be locked if we are not panicking. 129 * Locking is currently fubar in the panic handler. 130 */ 131 if (!oops_in_progress) 132 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); 133 134 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) 135 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder)) 136 return true; 137 return false; 138 } 139 EXPORT_SYMBOL(drm_helper_crtc_in_use); 140 141 static void 142 drm_encoder_disable(struct drm_encoder *encoder) 143 { 144 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; 145 146 if (encoder->bridge) 147 encoder->bridge->funcs->disable(encoder->bridge); 148 149 if (encoder_funcs->disable) 150 (*encoder_funcs->disable)(encoder); 151 else 152 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); 153 154 if (encoder->bridge) 155 encoder->bridge->funcs->post_disable(encoder->bridge); 156 } 157 158 static void __drm_helper_disable_unused_functions(struct drm_device *dev) 159 { 160 struct drm_encoder *encoder; 161 struct drm_connector *connector; 162 struct drm_crtc *crtc; 163 164 drm_warn_on_modeset_not_all_locked(dev); 165 166 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 167 if (!connector->encoder) 168 continue; 169 } 170 171 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 172 if (!drm_helper_encoder_in_use(encoder)) { 173 drm_encoder_disable(encoder); 174 /* disconnector encoder from any connector */ 175 encoder->crtc = NULL; 176 } 177 } 178 179 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 180 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 181 crtc->enabled = drm_helper_crtc_in_use(crtc); 182 if (!crtc->enabled) { 183 if (crtc_funcs->disable) 184 (*crtc_funcs->disable)(crtc); 185 else 186 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF); 187 crtc->primary->fb = NULL; 188 } 189 } 190 } 191 192 /** 193 * drm_helper_disable_unused_functions - disable unused objects 194 * @dev: DRM device 195 * 196 * This function walks through the entire mode setting configuration of @dev. It 197 * will remove any crtc links of unused encoders and encoder links of 198 * disconnected connectors. Then it will disable all unused encoders and crtcs 199 * either by calling their disable callback if available or by calling their 200 * dpms callback with DRM_MODE_DPMS_OFF. 201 */ 202 void drm_helper_disable_unused_functions(struct drm_device *dev) 203 { 204 drm_modeset_lock_all(dev); 205 __drm_helper_disable_unused_functions(dev); 206 drm_modeset_unlock_all(dev); 207 } 208 EXPORT_SYMBOL(drm_helper_disable_unused_functions); 209 210 /* 211 * Check the CRTC we're going to map each output to vs. its current 212 * CRTC. If they don't match, we have to disable the output and the CRTC 213 * since the driver will have to re-route things. 214 */ 215 static void 216 drm_crtc_prepare_encoders(struct drm_device *dev) 217 { 218 struct drm_encoder_helper_funcs *encoder_funcs; 219 struct drm_encoder *encoder; 220 221 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 222 encoder_funcs = encoder->helper_private; 223 /* Disable unused encoders */ 224 if (encoder->crtc == NULL) 225 drm_encoder_disable(encoder); 226 /* Disable encoders whose CRTC is about to change */ 227 if (encoder_funcs->get_crtc && 228 encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) 229 drm_encoder_disable(encoder); 230 } 231 } 232 233 /** 234 * drm_crtc_helper_set_mode - internal helper to set a mode 235 * @crtc: CRTC to program 236 * @mode: mode to use 237 * @x: horizontal offset into the surface 238 * @y: vertical offset into the surface 239 * @old_fb: old framebuffer, for cleanup 240 * 241 * Try to set @mode on @crtc. Give @crtc and its associated connectors a chance 242 * to fixup or reject the mode prior to trying to set it. This is an internal 243 * helper that drivers could e.g. use to update properties that require the 244 * entire output pipe to be disabled and re-enabled in a new configuration. For 245 * example for changing whether audio is enabled on a hdmi link or for changing 246 * panel fitter or dither attributes. It is also called by the 247 * drm_crtc_helper_set_config() helper function to drive the mode setting 248 * sequence. 249 * 250 * Returns: 251 * True if the mode was set successfully, false otherwise. 252 */ 253 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, 254 struct drm_display_mode *mode, 255 int x, int y, 256 struct drm_framebuffer *old_fb) 257 { 258 struct drm_device *dev = crtc->dev; 259 struct drm_display_mode *adjusted_mode, saved_mode; 260 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 261 struct drm_encoder_helper_funcs *encoder_funcs; 262 int saved_x, saved_y; 263 bool saved_enabled; 264 struct drm_encoder *encoder; 265 bool ret = true; 266 267 drm_warn_on_modeset_not_all_locked(dev); 268 269 saved_enabled = crtc->enabled; 270 crtc->enabled = drm_helper_crtc_in_use(crtc); 271 if (!crtc->enabled) 272 return true; 273 274 adjusted_mode = drm_mode_duplicate(dev, mode); 275 if (!adjusted_mode) { 276 crtc->enabled = saved_enabled; 277 return false; 278 } 279 280 saved_mode = crtc->mode; 281 saved_x = crtc->x; 282 saved_y = crtc->y; 283 284 /* Update crtc values up front so the driver can rely on them for mode 285 * setting. 286 */ 287 crtc->mode = *mode; 288 crtc->x = x; 289 crtc->y = y; 290 291 /* Pass our mode to the connectors and the CRTC to give them a chance to 292 * adjust it according to limitations or connector properties, and also 293 * a chance to reject the mode entirely. 294 */ 295 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 296 297 if (encoder->crtc != crtc) 298 continue; 299 300 if (encoder->bridge && encoder->bridge->funcs->mode_fixup) { 301 ret = encoder->bridge->funcs->mode_fixup( 302 encoder->bridge, mode, adjusted_mode); 303 if (!ret) { 304 DRM_DEBUG_KMS("Bridge fixup failed\n"); 305 goto done; 306 } 307 } 308 309 encoder_funcs = encoder->helper_private; 310 if (!(ret = encoder_funcs->mode_fixup(encoder, mode, 311 adjusted_mode))) { 312 DRM_DEBUG_KMS("Encoder fixup failed\n"); 313 goto done; 314 } 315 } 316 317 if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { 318 DRM_DEBUG_KMS("CRTC fixup failed\n"); 319 goto done; 320 } 321 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); 322 323 /* Prepare the encoders and CRTCs before setting the mode. */ 324 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 325 326 if (encoder->crtc != crtc) 327 continue; 328 329 if (encoder->bridge) 330 encoder->bridge->funcs->disable(encoder->bridge); 331 332 encoder_funcs = encoder->helper_private; 333 /* Disable the encoders as the first thing we do. */ 334 encoder_funcs->prepare(encoder); 335 336 if (encoder->bridge) 337 encoder->bridge->funcs->post_disable(encoder->bridge); 338 } 339 340 drm_crtc_prepare_encoders(dev); 341 342 crtc_funcs->prepare(crtc); 343 344 /* Set up the DPLL and any encoders state that needs to adjust or depend 345 * on the DPLL. 346 */ 347 ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); 348 if (!ret) 349 goto done; 350 351 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 352 353 if (encoder->crtc != crtc) 354 continue; 355 356 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", 357 encoder->base.id, drm_get_encoder_name(encoder), 358 mode->base.id, mode->name); 359 encoder_funcs = encoder->helper_private; 360 encoder_funcs->mode_set(encoder, mode, adjusted_mode); 361 362 if (encoder->bridge && encoder->bridge->funcs->mode_set) 363 encoder->bridge->funcs->mode_set(encoder->bridge, mode, 364 adjusted_mode); 365 } 366 367 /* Now enable the clocks, plane, pipe, and connectors that we set up. */ 368 crtc_funcs->commit(crtc); 369 370 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 371 372 if (encoder->crtc != crtc) 373 continue; 374 375 if (encoder->bridge) 376 encoder->bridge->funcs->pre_enable(encoder->bridge); 377 378 encoder_funcs = encoder->helper_private; 379 encoder_funcs->commit(encoder); 380 381 if (encoder->bridge) 382 encoder->bridge->funcs->enable(encoder->bridge); 383 } 384 385 /* Store real post-adjustment hardware mode. */ 386 crtc->hwmode = *adjusted_mode; 387 388 /* Calculate and store various constants which 389 * are later needed by vblank and swap-completion 390 * timestamping. They are derived from true hwmode. 391 */ 392 drm_calc_timestamping_constants(crtc, &crtc->hwmode); 393 394 /* FIXME: add subpixel order */ 395 done: 396 drm_mode_destroy(dev, adjusted_mode); 397 if (!ret) { 398 crtc->enabled = saved_enabled; 399 crtc->mode = saved_mode; 400 crtc->x = saved_x; 401 crtc->y = saved_y; 402 } 403 404 return ret; 405 } 406 EXPORT_SYMBOL(drm_crtc_helper_set_mode); 407 408 409 static int 410 drm_crtc_helper_disable(struct drm_crtc *crtc) 411 { 412 struct drm_device *dev = crtc->dev; 413 struct drm_connector *connector; 414 struct drm_encoder *encoder; 415 416 /* Decouple all encoders and their attached connectors from this crtc */ 417 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 418 if (encoder->crtc != crtc) 419 continue; 420 421 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 422 if (connector->encoder != encoder) 423 continue; 424 425 connector->encoder = NULL; 426 427 /* 428 * drm_helper_disable_unused_functions() ought to be 429 * doing this, but since we've decoupled the encoder 430 * from the connector above, the required connection 431 * between them is henceforth no longer available. 432 */ 433 connector->dpms = DRM_MODE_DPMS_OFF; 434 } 435 } 436 437 __drm_helper_disable_unused_functions(dev); 438 return 0; 439 } 440 441 /** 442 * drm_crtc_helper_set_config - set a new config from userspace 443 * @set: mode set configuration 444 * 445 * Setup a new configuration, provided by the upper layers (either an ioctl call 446 * from userspace or internally e.g. from the fbdev support code) in @set, and 447 * enable it. This is the main helper functions for drivers that implement 448 * kernel mode setting with the crtc helper functions and the assorted 449 * ->prepare(), ->modeset() and ->commit() helper callbacks. 450 * 451 * Returns: 452 * Returns 0 on success, negative errno numbers on failure. 453 */ 454 int drm_crtc_helper_set_config(struct drm_mode_set *set) 455 { 456 struct drm_device *dev; 457 struct drm_crtc *new_crtc; 458 struct drm_encoder *save_encoders, *new_encoder, *encoder; 459 bool mode_changed = false; /* if true do a full mode set */ 460 bool fb_changed = false; /* if true and !mode_changed just do a flip */ 461 struct drm_connector *save_connectors, *connector; 462 int count = 0, ro, fail = 0; 463 struct drm_crtc_helper_funcs *crtc_funcs; 464 struct drm_mode_set save_set; 465 int ret; 466 int i; 467 468 DRM_DEBUG_KMS("\n"); 469 470 BUG_ON(!set); 471 BUG_ON(!set->crtc); 472 BUG_ON(!set->crtc->helper_private); 473 474 /* Enforce sane interface api - has been abused by the fb helper. */ 475 BUG_ON(!set->mode && set->fb); 476 BUG_ON(set->fb && set->num_connectors == 0); 477 478 crtc_funcs = set->crtc->helper_private; 479 480 if (!set->mode) 481 set->fb = NULL; 482 483 if (set->fb) { 484 DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", 485 set->crtc->base.id, set->fb->base.id, 486 (int)set->num_connectors, set->x, set->y); 487 } else { 488 DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); 489 return drm_crtc_helper_disable(set->crtc); 490 } 491 492 dev = set->crtc->dev; 493 494 drm_warn_on_modeset_not_all_locked(dev); 495 496 /* 497 * Allocate space for the backup of all (non-pointer) encoder and 498 * connector data. 499 */ 500 save_encoders = kzalloc(dev->mode_config.num_encoder * 501 sizeof(struct drm_encoder), GFP_KERNEL); 502 if (!save_encoders) 503 return -ENOMEM; 504 505 save_connectors = kzalloc(dev->mode_config.num_connector * 506 sizeof(struct drm_connector), GFP_KERNEL); 507 if (!save_connectors) { 508 kfree(save_encoders); 509 return -ENOMEM; 510 } 511 512 /* 513 * Copy data. Note that driver private data is not affected. 514 * Should anything bad happen only the expected state is 515 * restored, not the drivers personal bookkeeping. 516 */ 517 count = 0; 518 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 519 save_encoders[count++] = *encoder; 520 } 521 522 count = 0; 523 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 524 save_connectors[count++] = *connector; 525 } 526 527 save_set.crtc = set->crtc; 528 save_set.mode = &set->crtc->mode; 529 save_set.x = set->crtc->x; 530 save_set.y = set->crtc->y; 531 save_set.fb = set->crtc->primary->fb; 532 533 /* We should be able to check here if the fb has the same properties 534 * and then just flip_or_move it */ 535 if (set->crtc->primary->fb != set->fb) { 536 /* If we have no fb then treat it as a full mode set */ 537 if (set->crtc->primary->fb == NULL) { 538 DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); 539 mode_changed = true; 540 } else if (set->fb == NULL) { 541 mode_changed = true; 542 } else if (set->fb->pixel_format != 543 set->crtc->primary->fb->pixel_format) { 544 mode_changed = true; 545 } else 546 fb_changed = true; 547 } 548 549 if (set->x != set->crtc->x || set->y != set->crtc->y) 550 fb_changed = true; 551 552 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { 553 DRM_DEBUG_KMS("modes are different, full mode set\n"); 554 drm_mode_debug_printmodeline(&set->crtc->mode); 555 drm_mode_debug_printmodeline(set->mode); 556 mode_changed = true; 557 } 558 559 /* a) traverse passed in connector list and get encoders for them */ 560 count = 0; 561 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 562 struct drm_connector_helper_funcs *connector_funcs = 563 connector->helper_private; 564 new_encoder = connector->encoder; 565 for (ro = 0; ro < set->num_connectors; ro++) { 566 if (set->connectors[ro] == connector) { 567 new_encoder = connector_funcs->best_encoder(connector); 568 /* if we can't get an encoder for a connector 569 we are setting now - then fail */ 570 if (new_encoder == NULL) 571 /* don't break so fail path works correct */ 572 fail = 1; 573 574 if (connector->dpms != DRM_MODE_DPMS_ON) { 575 DRM_DEBUG_KMS("connector dpms not on, full mode switch\n"); 576 mode_changed = true; 577 } 578 579 break; 580 } 581 } 582 583 if (new_encoder != connector->encoder) { 584 DRM_DEBUG_KMS("encoder changed, full mode switch\n"); 585 mode_changed = true; 586 /* If the encoder is reused for another connector, then 587 * the appropriate crtc will be set later. 588 */ 589 if (connector->encoder) 590 connector->encoder->crtc = NULL; 591 connector->encoder = new_encoder; 592 } 593 } 594 595 if (fail) { 596 ret = -EINVAL; 597 goto fail; 598 } 599 600 count = 0; 601 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 602 if (!connector->encoder) 603 continue; 604 605 if (connector->encoder->crtc == set->crtc) 606 new_crtc = NULL; 607 else 608 new_crtc = connector->encoder->crtc; 609 610 for (ro = 0; ro < set->num_connectors; ro++) { 611 if (set->connectors[ro] == connector) 612 new_crtc = set->crtc; 613 } 614 615 /* Make sure the new CRTC will work with the encoder */ 616 if (new_crtc && 617 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { 618 ret = -EINVAL; 619 goto fail; 620 } 621 if (new_crtc != connector->encoder->crtc) { 622 DRM_DEBUG_KMS("crtc changed, full mode switch\n"); 623 mode_changed = true; 624 connector->encoder->crtc = new_crtc; 625 } 626 if (new_crtc) { 627 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n", 628 connector->base.id, drm_get_connector_name(connector), 629 new_crtc->base.id); 630 } else { 631 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n", 632 connector->base.id, drm_get_connector_name(connector)); 633 } 634 } 635 636 /* mode_set_base is not a required function */ 637 if (fb_changed && !crtc_funcs->mode_set_base) 638 mode_changed = true; 639 640 if (mode_changed) { 641 if (drm_helper_crtc_in_use(set->crtc)) { 642 DRM_DEBUG_KMS("attempting to set mode from" 643 " userspace\n"); 644 drm_mode_debug_printmodeline(set->mode); 645 set->crtc->primary->fb = set->fb; 646 if (!drm_crtc_helper_set_mode(set->crtc, set->mode, 647 set->x, set->y, 648 save_set.fb)) { 649 DRM_ERROR("failed to set mode on [CRTC:%d]\n", 650 set->crtc->base.id); 651 set->crtc->primary->fb = save_set.fb; 652 ret = -EINVAL; 653 goto fail; 654 } 655 DRM_DEBUG_KMS("Setting connector DPMS state to on\n"); 656 for (i = 0; i < set->num_connectors; i++) { 657 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id, 658 drm_get_connector_name(set->connectors[i])); 659 set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON); 660 } 661 } 662 __drm_helper_disable_unused_functions(dev); 663 } else if (fb_changed) { 664 set->crtc->x = set->x; 665 set->crtc->y = set->y; 666 set->crtc->primary->fb = set->fb; 667 ret = crtc_funcs->mode_set_base(set->crtc, 668 set->x, set->y, save_set.fb); 669 if (ret != 0) { 670 set->crtc->x = save_set.x; 671 set->crtc->y = save_set.y; 672 set->crtc->primary->fb = save_set.fb; 673 goto fail; 674 } 675 } 676 677 kfree(save_connectors); 678 kfree(save_encoders); 679 return 0; 680 681 fail: 682 /* Restore all previous data. */ 683 count = 0; 684 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 685 *encoder = save_encoders[count++]; 686 } 687 688 count = 0; 689 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 690 *connector = save_connectors[count++]; 691 } 692 693 /* Try to restore the config */ 694 if (mode_changed && 695 !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x, 696 save_set.y, save_set.fb)) 697 DRM_ERROR("failed to restore config after modeset failure\n"); 698 699 kfree(save_connectors); 700 kfree(save_encoders); 701 return ret; 702 } 703 EXPORT_SYMBOL(drm_crtc_helper_set_config); 704 705 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder) 706 { 707 int dpms = DRM_MODE_DPMS_OFF; 708 struct drm_connector *connector; 709 struct drm_device *dev = encoder->dev; 710 711 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 712 if (connector->encoder == encoder) 713 if (connector->dpms < dpms) 714 dpms = connector->dpms; 715 return dpms; 716 } 717 718 /* Helper which handles bridge ordering around encoder dpms */ 719 static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode) 720 { 721 struct drm_bridge *bridge = encoder->bridge; 722 struct drm_encoder_helper_funcs *encoder_funcs; 723 724 if (bridge) { 725 if (mode == DRM_MODE_DPMS_ON) 726 bridge->funcs->pre_enable(bridge); 727 else 728 bridge->funcs->disable(bridge); 729 } 730 731 encoder_funcs = encoder->helper_private; 732 if (encoder_funcs->dpms) 733 encoder_funcs->dpms(encoder, mode); 734 735 if (bridge) { 736 if (mode == DRM_MODE_DPMS_ON) 737 bridge->funcs->enable(bridge); 738 else 739 bridge->funcs->post_disable(bridge); 740 } 741 } 742 743 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) 744 { 745 int dpms = DRM_MODE_DPMS_OFF; 746 struct drm_connector *connector; 747 struct drm_device *dev = crtc->dev; 748 749 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 750 if (connector->encoder && connector->encoder->crtc == crtc) 751 if (connector->dpms < dpms) 752 dpms = connector->dpms; 753 return dpms; 754 } 755 756 /** 757 * drm_helper_connector_dpms() - connector dpms helper implementation 758 * @connector: affected connector 759 * @mode: DPMS mode 760 * 761 * This is the main helper function provided by the crtc helper framework for 762 * implementing the DPMS connector attribute. It computes the new desired DPMS 763 * state for all encoders and crtcs in the output mesh and calls the ->dpms() 764 * callback provided by the driver appropriately. 765 */ 766 void drm_helper_connector_dpms(struct drm_connector *connector, int mode) 767 { 768 struct drm_encoder *encoder = connector->encoder; 769 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; 770 int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF; 771 772 if (mode == connector->dpms) 773 return; 774 775 old_dpms = connector->dpms; 776 connector->dpms = mode; 777 778 if (encoder) 779 encoder_dpms = drm_helper_choose_encoder_dpms(encoder); 780 781 /* from off to on, do crtc then encoder */ 782 if (mode < old_dpms) { 783 if (crtc) { 784 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 785 if (crtc_funcs->dpms) 786 (*crtc_funcs->dpms) (crtc, 787 drm_helper_choose_crtc_dpms(crtc)); 788 } 789 if (encoder) 790 drm_helper_encoder_dpms(encoder, encoder_dpms); 791 } 792 793 /* from on to off, do encoder then crtc */ 794 if (mode > old_dpms) { 795 if (encoder) 796 drm_helper_encoder_dpms(encoder, encoder_dpms); 797 if (crtc) { 798 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 799 if (crtc_funcs->dpms) 800 (*crtc_funcs->dpms) (crtc, 801 drm_helper_choose_crtc_dpms(crtc)); 802 } 803 } 804 805 return; 806 } 807 EXPORT_SYMBOL(drm_helper_connector_dpms); 808 809 /** 810 * drm_helper_mode_fill_fb_struct - fill out framebuffer metadata 811 * @fb: drm_framebuffer object to fill out 812 * @mode_cmd: metadata from the userspace fb creation request 813 * 814 * This helper can be used in a drivers fb_create callback to pre-fill the fb's 815 * metadata fields. 816 */ 817 void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, 818 struct drm_mode_fb_cmd2 *mode_cmd) 819 { 820 int i; 821 822 fb->width = mode_cmd->width; 823 fb->height = mode_cmd->height; 824 for (i = 0; i < 4; i++) { 825 fb->pitches[i] = mode_cmd->pitches[i]; 826 fb->offsets[i] = mode_cmd->offsets[i]; 827 } 828 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth, 829 &fb->bits_per_pixel); 830 fb->pixel_format = mode_cmd->pixel_format; 831 } 832 EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct); 833 834 /** 835 * drm_helper_resume_force_mode - force-restore mode setting configuration 836 * @dev: drm_device which should be restored 837 * 838 * Drivers which use the mode setting helpers can use this function to 839 * force-restore the mode setting configuration e.g. on resume or when something 840 * else might have trampled over the hw state (like some overzealous old BIOSen 841 * tended to do). 842 * 843 * This helper doesn't provide a error return value since restoring the old 844 * config should never fail due to resource allocation issues since the driver 845 * has successfully set the restored configuration already. Hence this should 846 * boil down to the equivalent of a few dpms on calls, which also don't provide 847 * an error code. 848 * 849 * Drivers where simply restoring an old configuration again might fail (e.g. 850 * due to slight differences in allocating shared resources when the 851 * configuration is restored in a different order than when userspace set it up) 852 * need to use their own restore logic. 853 */ 854 void drm_helper_resume_force_mode(struct drm_device *dev) 855 { 856 struct drm_crtc *crtc; 857 struct drm_encoder *encoder; 858 struct drm_crtc_helper_funcs *crtc_funcs; 859 int encoder_dpms; 860 bool ret; 861 862 drm_modeset_lock_all(dev); 863 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 864 865 if (!crtc->enabled) 866 continue; 867 868 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, 869 crtc->x, crtc->y, crtc->primary->fb); 870 871 /* Restoring the old config should never fail! */ 872 if (ret == false) 873 DRM_ERROR("failed to set mode on crtc %p\n", crtc); 874 875 /* Turn off outputs that were already powered off */ 876 if (drm_helper_choose_crtc_dpms(crtc)) { 877 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 878 879 if(encoder->crtc != crtc) 880 continue; 881 882 encoder_dpms = drm_helper_choose_encoder_dpms( 883 encoder); 884 885 drm_helper_encoder_dpms(encoder, encoder_dpms); 886 } 887 888 crtc_funcs = crtc->helper_private; 889 if (crtc_funcs->dpms) 890 (*crtc_funcs->dpms) (crtc, 891 drm_helper_choose_crtc_dpms(crtc)); 892 } 893 } 894 895 /* disable the unused connectors while restoring the modesetting */ 896 __drm_helper_disable_unused_functions(dev); 897 drm_modeset_unlock_all(dev); 898 } 899 EXPORT_SYMBOL(drm_helper_resume_force_mode); 900