aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_crtc_helper.c')
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index e490e69db21e..964c5eb1fada 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -480,6 +480,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
480 int saved_x, saved_y; 480 int saved_x, saved_y;
481 struct drm_encoder *encoder; 481 struct drm_encoder *encoder;
482 bool ret = true; 482 bool ret = true;
483 bool depth_changed, bpp_changed;
483 484
484 adjusted_mode = drm_mode_duplicate(dev, mode); 485 adjusted_mode = drm_mode_duplicate(dev, mode);
485 486
@@ -488,6 +489,15 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
488 if (!crtc->enabled) 489 if (!crtc->enabled)
489 return true; 490 return true;
490 491
492 if (old_fb && crtc->fb) {
493 depth_changed = (old_fb->depth != crtc->fb->depth);
494 bpp_changed = (old_fb->bits_per_pixel !=
495 crtc->fb->bits_per_pixel);
496 } else {
497 depth_changed = true;
498 bpp_changed = true;
499 }
500
491 saved_mode = crtc->mode; 501 saved_mode = crtc->mode;
492 saved_x = crtc->x; 502 saved_x = crtc->x;
493 saved_y = crtc->y; 503 saved_y = crtc->y;
@@ -500,7 +510,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
500 crtc->y = y; 510 crtc->y = y;
501 511
502 if (drm_mode_equal(&saved_mode, &crtc->mode)) { 512 if (drm_mode_equal(&saved_mode, &crtc->mode)) {
503 if (saved_x != crtc->x || saved_y != crtc->y) { 513 if (saved_x != crtc->x || saved_y != crtc->y ||
514 depth_changed || bpp_changed) {
504 crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, 515 crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
505 old_fb); 516 old_fb);
506 goto done; 517 goto done;
@@ -606,8 +617,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
606 struct drm_encoder **save_encoders, *new_encoder; 617 struct drm_encoder **save_encoders, *new_encoder;
607 struct drm_framebuffer *old_fb; 618 struct drm_framebuffer *old_fb;
608 bool save_enabled; 619 bool save_enabled;
609 bool changed = false; 620 bool mode_changed = false;
610 bool flip_or_move = false; 621 bool fb_changed = false;
611 struct drm_connector *connector; 622 struct drm_connector *connector;
612 int count = 0, ro, fail = 0; 623 int count = 0, ro, fail = 0;
613 struct drm_crtc_helper_funcs *crtc_funcs; 624 struct drm_crtc_helper_funcs *crtc_funcs;
@@ -635,7 +646,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
635 /* save previous config */ 646 /* save previous config */
636 save_enabled = set->crtc->enabled; 647 save_enabled = set->crtc->enabled;
637 648
638 /* this is meant to be num_connector not num_crtc */ 649 /*
650 * We do mode_config.num_connectors here since we'll look at the
651 * CRTC and encoder associated with each connector later.
652 */
639 save_crtcs = kzalloc(dev->mode_config.num_connector * 653 save_crtcs = kzalloc(dev->mode_config.num_connector *
640 sizeof(struct drm_crtc *), GFP_KERNEL); 654 sizeof(struct drm_crtc *), GFP_KERNEL);
641 if (!save_crtcs) 655 if (!save_crtcs)
@@ -651,21 +665,25 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
651 /* We should be able to check here if the fb has the same properties 665 /* We should be able to check here if the fb has the same properties
652 * and then just flip_or_move it */ 666 * and then just flip_or_move it */
653 if (set->crtc->fb != set->fb) { 667 if (set->crtc->fb != set->fb) {
654 /* if we have no fb then its a change not a flip */ 668 /* If we have no fb then treat it as a full mode set */
655 if (set->crtc->fb == NULL) 669 if (set->crtc->fb == NULL)
656 changed = true; 670 mode_changed = true;
671 else if ((set->fb->bits_per_pixel !=
672 set->crtc->fb->bits_per_pixel) ||
673 set->fb->depth != set->crtc->fb->depth)
674 fb_changed = true;
657 else 675 else
658 flip_or_move = true; 676 fb_changed = true;
659 } 677 }
660 678
661 if (set->x != set->crtc->x || set->y != set->crtc->y) 679 if (set->x != set->crtc->x || set->y != set->crtc->y)
662 flip_or_move = true; 680 fb_changed = true;
663 681
664 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { 682 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
665 DRM_DEBUG("modes are different\n"); 683 DRM_DEBUG("modes are different\n");
666 drm_mode_debug_printmodeline(&set->crtc->mode); 684 drm_mode_debug_printmodeline(&set->crtc->mode);
667 drm_mode_debug_printmodeline(set->mode); 685 drm_mode_debug_printmodeline(set->mode);
668 changed = true; 686 mode_changed = true;
669 } 687 }
670 688
671 /* a) traverse passed in connector list and get encoders for them */ 689 /* a) traverse passed in connector list and get encoders for them */
@@ -688,7 +706,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
688 } 706 }
689 707
690 if (new_encoder != connector->encoder) { 708 if (new_encoder != connector->encoder) {
691 changed = true; 709 mode_changed = true;
692 connector->encoder = new_encoder; 710 connector->encoder = new_encoder;
693 } 711 }
694 } 712 }
@@ -715,16 +733,16 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
715 new_crtc = set->crtc; 733 new_crtc = set->crtc;
716 } 734 }
717 if (new_crtc != connector->encoder->crtc) { 735 if (new_crtc != connector->encoder->crtc) {
718 changed = true; 736 mode_changed = true;
719 connector->encoder->crtc = new_crtc; 737 connector->encoder->crtc = new_crtc;
720 } 738 }
721 } 739 }
722 740
723 /* mode_set_base is not a required function */ 741 /* mode_set_base is not a required function */
724 if (flip_or_move && !crtc_funcs->mode_set_base) 742 if (fb_changed && !crtc_funcs->mode_set_base)
725 changed = true; 743 mode_changed = true;
726 744
727 if (changed) { 745 if (mode_changed) {
728 old_fb = set->crtc->fb; 746 old_fb = set->crtc->fb;
729 set->crtc->fb = set->fb; 747 set->crtc->fb = set->fb;
730 set->crtc->enabled = (set->mode != NULL); 748 set->crtc->enabled = (set->mode != NULL);
@@ -743,7 +761,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
743 set->crtc->desired_mode = set->mode; 761 set->crtc->desired_mode = set->mode;
744 } 762 }
745 drm_helper_disable_unused_functions(dev); 763 drm_helper_disable_unused_functions(dev);
746 } else if (flip_or_move) { 764 } else if (fb_changed) {
747 old_fb = set->crtc->fb; 765 old_fb = set->crtc->fb;
748 if (set->crtc->fb != set->fb) 766 if (set->crtc->fb != set->fb)
749 set->crtc->fb = set->fb; 767 set->crtc->fb = set->fb;