diff options
| -rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 48 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 2 |
2 files changed, 35 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; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8ccb9c3ab868..4372acff5a01 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -401,6 +401,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 401 | I915_WRITE(dspstride, crtc->fb->pitch); | 401 | I915_WRITE(dspstride, crtc->fb->pitch); |
| 402 | 402 | ||
| 403 | dspcntr = I915_READ(dspcntr_reg); | 403 | dspcntr = I915_READ(dspcntr_reg); |
| 404 | /* Mask out pixel format bits in case we change it */ | ||
| 405 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; | ||
| 404 | switch (crtc->fb->bits_per_pixel) { | 406 | switch (crtc->fb->bits_per_pixel) { |
| 405 | case 8: | 407 | case 8: |
| 406 | dspcntr |= DISPPLANE_8BPP; | 408 | dspcntr |= DISPPLANE_8BPP; |
