diff options
author | Dave Airlie <airlied@redhat.com> | 2011-12-20 09:43:53 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-12-20 09:43:53 -0500 |
commit | 1fbe6f625f69e48c4001051dc1431afc704acfaa (patch) | |
tree | 826b741201a2e09a627ed350c6ff36935f5cff79 /drivers/gpu/drm/drm_crtc_helper.c | |
parent | 0cecdd818cd79d092e36e70dfe3a71f2878d6b96 (diff) | |
parent | 384703b8e6cd4c8ef08512e596024e028c91c339 (diff) |
Merge tag 'v3.2-rc6' of /home/airlied/devel/kernel/linux-2.6 into drm-core-next
Merge in the upstream tree to bring in the mainline fixes.
Conflicts:
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c
Diffstat (limited to 'drivers/gpu/drm/drm_crtc_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index ccbdc0b5854..42f86e71479 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -457,6 +457,30 @@ done: | |||
457 | EXPORT_SYMBOL(drm_crtc_helper_set_mode); | 457 | EXPORT_SYMBOL(drm_crtc_helper_set_mode); |
458 | 458 | ||
459 | 459 | ||
460 | static int | ||
461 | drm_crtc_helper_disable(struct drm_crtc *crtc) | ||
462 | { | ||
463 | struct drm_device *dev = crtc->dev; | ||
464 | struct drm_connector *connector; | ||
465 | struct drm_encoder *encoder; | ||
466 | |||
467 | /* Decouple all encoders and their attached connectors from this crtc */ | ||
468 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
469 | if (encoder->crtc != crtc) | ||
470 | continue; | ||
471 | |||
472 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
473 | if (connector->encoder != encoder) | ||
474 | continue; | ||
475 | |||
476 | connector->encoder = NULL; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | drm_helper_disable_unused_functions(dev); | ||
481 | return 0; | ||
482 | } | ||
483 | |||
460 | /** | 484 | /** |
461 | * drm_crtc_helper_set_config - set a new config from userspace | 485 | * drm_crtc_helper_set_config - set a new config from userspace |
462 | * @crtc: CRTC to setup | 486 | * @crtc: CRTC to setup |
@@ -485,6 +509,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
485 | struct drm_connector *save_connectors, *connector; | 509 | struct drm_connector *save_connectors, *connector; |
486 | int count = 0, ro, fail = 0; | 510 | int count = 0, ro, fail = 0; |
487 | struct drm_crtc_helper_funcs *crtc_funcs; | 511 | struct drm_crtc_helper_funcs *crtc_funcs; |
512 | struct drm_mode_set save_set; | ||
488 | int ret = 0; | 513 | int ret = 0; |
489 | int i; | 514 | int i; |
490 | 515 | ||
@@ -510,8 +535,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
510 | (int)set->num_connectors, set->x, set->y); | 535 | (int)set->num_connectors, set->x, set->y); |
511 | } else { | 536 | } else { |
512 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); | 537 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); |
513 | set->mode = NULL; | 538 | return drm_crtc_helper_disable(set->crtc); |
514 | set->num_connectors = 0; | ||
515 | } | 539 | } |
516 | 540 | ||
517 | dev = set->crtc->dev; | 541 | dev = set->crtc->dev; |
@@ -557,6 +581,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
557 | save_connectors[count++] = *connector; | 581 | save_connectors[count++] = *connector; |
558 | } | 582 | } |
559 | 583 | ||
584 | save_set.crtc = set->crtc; | ||
585 | save_set.mode = &set->crtc->mode; | ||
586 | save_set.x = set->crtc->x; | ||
587 | save_set.y = set->crtc->y; | ||
588 | save_set.fb = set->crtc->fb; | ||
589 | |||
560 | /* We should be able to check here if the fb has the same properties | 590 | /* We should be able to check here if the fb has the same properties |
561 | * and then just flip_or_move it */ | 591 | * and then just flip_or_move it */ |
562 | if (set->crtc->fb != set->fb) { | 592 | if (set->crtc->fb != set->fb) { |
@@ -722,6 +752,12 @@ fail: | |||
722 | *connector = save_connectors[count++]; | 752 | *connector = save_connectors[count++]; |
723 | } | 753 | } |
724 | 754 | ||
755 | /* Try to restore the config */ | ||
756 | if (mode_changed && | ||
757 | !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x, | ||
758 | save_set.y, save_set.fb)) | ||
759 | DRM_ERROR("failed to restore config after modeset failure\n"); | ||
760 | |||
725 | kfree(save_connectors); | 761 | kfree(save_connectors); |
726 | kfree(save_encoders); | 762 | kfree(save_encoders); |
727 | kfree(save_crtcs); | 763 | kfree(save_crtcs); |