summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_crtc_helper.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2008-12-17 22:14:46 -0500
committerDave Airlie <airlied@linux.ie>2008-12-29 17:47:27 +1000
commit3c4fdcfb2941dc36b6a16bc509a2adb97c131716 (patch)
tree36fba683165c72b36037035f5c383cc18e7e8db8 /drivers/gpu/drm/drm_crtc_helper.c
parentd1e22c6ed05f3bfb3a7de0947498e7f3c868b296 (diff)
downloadlwn-3c4fdcfb2941dc36b6a16bc509a2adb97c131716.tar.gz
lwn-3c4fdcfb2941dc36b6a16bc509a2adb97c131716.zip
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.c20
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)
*/
bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
struct drm_display_mode *mode,
- int x, int y)
+ int x, int y,
+ struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct drm_display_mode *adjusted_mode, saved_mode;
@@ -462,7 +463,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
if (drm_mode_equal(&saved_mode, &crtc->mode)) {
if (saved_x != crtc->x || saved_y != crtc->y) {
- crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y);
+ crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
+ old_fb);
goto done;
}
}
@@ -501,7 +503,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
/* Set up the DPLL and any encoders state that needs to adjust or depend
* on the DPLL.
*/
- crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y);
+ crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -564,6 +566,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
struct drm_device *dev;
struct drm_crtc **save_crtcs, *new_crtc;
struct drm_encoder **save_encoders, *new_encoder;
+ struct drm_framebuffer *old_fb;
bool save_enabled;
bool changed = false;
bool flip_or_move = false;
@@ -684,13 +687,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
changed = true;
if (changed) {
+ old_fb = set->crtc->fb;
set->crtc->fb = set->fb;
set->crtc->enabled = (set->mode != NULL);
if (set->mode != NULL) {
DRM_DEBUG("attempting to set mode from userspace\n");
drm_mode_debug_printmodeline(set->mode);
if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
- set->x, set->y)) {
+ set->x, set->y,
+ old_fb)) {
ret = -EINVAL;
goto fail_set_mode;
}
@@ -701,9 +706,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
}
drm_helper_disable_unused_functions(dev);
} else if (flip_or_move) {
+ old_fb = set->crtc->fb;
if (set->crtc->fb != set->fb)
set->crtc->fb = set->fb;
- crtc_funcs->mode_set_base(set->crtc, set->x, set->y);
+ crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb);
}
kfree(save_encoders);
@@ -809,8 +815,8 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
if (!crtc->enabled)
continue;
- ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
- crtc->y);
+ ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
+ crtc->x, crtc->y, crtc->fb);
if (ret == false)
DRM_ERROR("failed to set mode on crtc %p\n", crtc);