diff options
author | Kristian Høgsberg <krh@redhat.com> | 2008-12-17 22:14:46 -0500 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2008-12-29 02:47:27 -0500 |
commit | 3c4fdcfb2941dc36b6a16bc509a2adb97c131716 (patch) | |
tree | 36fba683165c72b36037035f5c383cc18e7e8db8 /drivers/gpu/drm/drm_crtc_helper.c | |
parent | d1e22c6ed05f3bfb3a7de0947498e7f3c868b296 (diff) |
drm: pin new and unpin old buffer when setting a mode.
This removes the requirement for user space to pin a buffer before
setting a mode that is backed by the pixels from that buffer.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/gpu/drm/drm_crtc_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 58e335967617..d8a982b71296 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -432,7 +432,8 @@ static void drm_setup_crtcs(struct drm_device *dev) | |||
432 | */ | 432 | */ |
433 | bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | 433 | bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, |
434 | struct drm_display_mode *mode, | 434 | struct drm_display_mode *mode, |
435 | int x, int y) | 435 | int x, int y, |
436 | struct drm_framebuffer *old_fb) | ||
436 | { | 437 | { |
437 | struct drm_device *dev = crtc->dev; | 438 | struct drm_device *dev = crtc->dev; |
438 | struct drm_display_mode *adjusted_mode, saved_mode; | 439 | struct drm_display_mode *adjusted_mode, saved_mode; |
@@ -462,7 +463,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
462 | 463 | ||
463 | if (drm_mode_equal(&saved_mode, &crtc->mode)) { | 464 | if (drm_mode_equal(&saved_mode, &crtc->mode)) { |
464 | if (saved_x != crtc->x || saved_y != crtc->y) { | 465 | if (saved_x != crtc->x || saved_y != crtc->y) { |
465 | crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y); | 466 | crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, |
467 | old_fb); | ||
466 | goto done; | 468 | goto done; |
467 | } | 469 | } |
468 | } | 470 | } |
@@ -501,7 +503,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
501 | /* Set up the DPLL and any encoders state that needs to adjust or depend | 503 | /* Set up the DPLL and any encoders state that needs to adjust or depend |
502 | * on the DPLL. | 504 | * on the DPLL. |
503 | */ | 505 | */ |
504 | crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y); | 506 | crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); |
505 | 507 | ||
506 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 508 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
507 | 509 | ||
@@ -564,6 +566,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
564 | struct drm_device *dev; | 566 | struct drm_device *dev; |
565 | struct drm_crtc **save_crtcs, *new_crtc; | 567 | struct drm_crtc **save_crtcs, *new_crtc; |
566 | struct drm_encoder **save_encoders, *new_encoder; | 568 | struct drm_encoder **save_encoders, *new_encoder; |
569 | struct drm_framebuffer *old_fb; | ||
567 | bool save_enabled; | 570 | bool save_enabled; |
568 | bool changed = false; | 571 | bool changed = false; |
569 | bool flip_or_move = false; | 572 | bool flip_or_move = false; |
@@ -684,13 +687,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
684 | changed = true; | 687 | changed = true; |
685 | 688 | ||
686 | if (changed) { | 689 | if (changed) { |
690 | old_fb = set->crtc->fb; | ||
687 | set->crtc->fb = set->fb; | 691 | set->crtc->fb = set->fb; |
688 | set->crtc->enabled = (set->mode != NULL); | 692 | set->crtc->enabled = (set->mode != NULL); |
689 | if (set->mode != NULL) { | 693 | if (set->mode != NULL) { |
690 | DRM_DEBUG("attempting to set mode from userspace\n"); | 694 | DRM_DEBUG("attempting to set mode from userspace\n"); |
691 | drm_mode_debug_printmodeline(set->mode); | 695 | drm_mode_debug_printmodeline(set->mode); |
692 | if (!drm_crtc_helper_set_mode(set->crtc, set->mode, | 696 | if (!drm_crtc_helper_set_mode(set->crtc, set->mode, |
693 | set->x, set->y)) { | 697 | set->x, set->y, |
698 | old_fb)) { | ||
694 | ret = -EINVAL; | 699 | ret = -EINVAL; |
695 | goto fail_set_mode; | 700 | goto fail_set_mode; |
696 | } | 701 | } |
@@ -701,9 +706,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
701 | } | 706 | } |
702 | drm_helper_disable_unused_functions(dev); | 707 | drm_helper_disable_unused_functions(dev); |
703 | } else if (flip_or_move) { | 708 | } else if (flip_or_move) { |
709 | old_fb = set->crtc->fb; | ||
704 | if (set->crtc->fb != set->fb) | 710 | if (set->crtc->fb != set->fb) |
705 | set->crtc->fb = set->fb; | 711 | set->crtc->fb = set->fb; |
706 | crtc_funcs->mode_set_base(set->crtc, set->x, set->y); | 712 | crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb); |
707 | } | 713 | } |
708 | 714 | ||
709 | kfree(save_encoders); | 715 | kfree(save_encoders); |
@@ -809,8 +815,8 @@ int drm_helper_resume_force_mode(struct drm_device *dev) | |||
809 | if (!crtc->enabled) | 815 | if (!crtc->enabled) |
810 | continue; | 816 | continue; |
811 | 817 | ||
812 | ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 818 | ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, |
813 | crtc->y); | 819 | crtc->x, crtc->y, crtc->fb); |
814 | 820 | ||
815 | if (ret == false) | 821 | if (ret == false) |
816 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); | 822 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); |