aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc_helper.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-12-20 09:43:53 -0500
committerDave Airlie <airlied@redhat.com>2011-12-20 09:43:53 -0500
commit1fbe6f625f69e48c4001051dc1431afc704acfaa (patch)
tree826b741201a2e09a627ed350c6ff36935f5cff79 /drivers/gpu/drm/drm_crtc_helper.c
parent0cecdd818cd79d092e36e70dfe3a71f2878d6b96 (diff)
parent384703b8e6cd4c8ef08512e596024e028c91c339 (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.c40
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:
457EXPORT_SYMBOL(drm_crtc_helper_set_mode); 457EXPORT_SYMBOL(drm_crtc_helper_set_mode);
458 458
459 459
460static int
461drm_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);