diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-08 08:19:16 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-07-13 06:56:20 -0400 |
commit | 11c21e73f848844d439cbccb42a1018b8c560e5c (patch) | |
tree | 6e0563aca3d269d7f8383e58a003cd7555f830ac | |
parent | cf47a07ab8f65d1d1fdbb72f4c38efe293f7a623 (diff) |
drm: Resurrect atomic rmfb code
This was somehow lost between v3 and the merged version in Maarten's
patch merged as:
commit f2d580b9a8149735cbc4b59c4a8df60173658140
Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Date: Wed May 4 14:38:26 2016 +0200
drm/core: Do not preserve framebuffer on rmfb, v4.
Actual code copied from Maarten's patch, but with the slight change to
just use dev->mode_config.funcs->atomic_commit to decide whether to
use the atomic path or not.
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1465388359-8070-24-git-send-email-daniel.vetter@ffwll.ch
-rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 66 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc_internal.h | 1 |
3 files changed, 73 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index d99ab2f6663f..dac0875e669c 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
@@ -1564,6 +1564,72 @@ void drm_atomic_clean_old_fb(struct drm_device *dev, | |||
1564 | } | 1564 | } |
1565 | EXPORT_SYMBOL(drm_atomic_clean_old_fb); | 1565 | EXPORT_SYMBOL(drm_atomic_clean_old_fb); |
1566 | 1566 | ||
1567 | int drm_atomic_remove_fb(struct drm_framebuffer *fb) | ||
1568 | { | ||
1569 | struct drm_modeset_acquire_ctx ctx; | ||
1570 | struct drm_device *dev = fb->dev; | ||
1571 | struct drm_atomic_state *state; | ||
1572 | struct drm_plane *plane; | ||
1573 | int ret = 0; | ||
1574 | unsigned plane_mask; | ||
1575 | |||
1576 | state = drm_atomic_state_alloc(dev); | ||
1577 | if (!state) | ||
1578 | return -ENOMEM; | ||
1579 | |||
1580 | drm_modeset_acquire_init(&ctx, 0); | ||
1581 | state->acquire_ctx = &ctx; | ||
1582 | |||
1583 | retry: | ||
1584 | plane_mask = 0; | ||
1585 | ret = drm_modeset_lock_all_ctx(dev, &ctx); | ||
1586 | if (ret) | ||
1587 | goto unlock; | ||
1588 | |||
1589 | drm_for_each_plane(plane, dev) { | ||
1590 | struct drm_plane_state *plane_state; | ||
1591 | |||
1592 | if (plane->state->fb != fb) | ||
1593 | continue; | ||
1594 | |||
1595 | plane_state = drm_atomic_get_plane_state(state, plane); | ||
1596 | if (IS_ERR(plane_state)) { | ||
1597 | ret = PTR_ERR(plane_state); | ||
1598 | goto unlock; | ||
1599 | } | ||
1600 | |||
1601 | drm_atomic_set_fb_for_plane(plane_state, NULL); | ||
1602 | ret = drm_atomic_set_crtc_for_plane(plane_state, NULL); | ||
1603 | if (ret) | ||
1604 | goto unlock; | ||
1605 | |||
1606 | plane_mask |= BIT(drm_plane_index(plane)); | ||
1607 | |||
1608 | plane->old_fb = plane->fb; | ||
1609 | plane->fb = NULL; | ||
1610 | } | ||
1611 | |||
1612 | if (plane_mask) | ||
1613 | ret = drm_atomic_commit(state); | ||
1614 | |||
1615 | unlock: | ||
1616 | if (plane_mask) | ||
1617 | drm_atomic_clean_old_fb(dev, plane_mask, ret); | ||
1618 | |||
1619 | if (ret == -EDEADLK) { | ||
1620 | drm_modeset_backoff(&ctx); | ||
1621 | goto retry; | ||
1622 | } | ||
1623 | |||
1624 | if (ret || !plane_mask) | ||
1625 | drm_atomic_state_free(state); | ||
1626 | |||
1627 | drm_modeset_drop_locks(&ctx); | ||
1628 | drm_modeset_acquire_fini(&ctx); | ||
1629 | |||
1630 | return ret; | ||
1631 | } | ||
1632 | |||
1567 | int drm_mode_atomic_ioctl(struct drm_device *dev, | 1633 | int drm_mode_atomic_ioctl(struct drm_device *dev, |
1568 | void *data, struct drm_file *file_priv) | 1634 | void *data, struct drm_file *file_priv) |
1569 | { | 1635 | { |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 578bd6f5ce83..9d3f80efc9cc 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -613,6 +613,11 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) | |||
613 | * in this manner. | 613 | * in this manner. |
614 | */ | 614 | */ |
615 | if (drm_framebuffer_read_refcount(fb) > 1) { | 615 | if (drm_framebuffer_read_refcount(fb) > 1) { |
616 | if (dev->mode_config.funcs->atomic_commit) { | ||
617 | drm_atomic_remove_fb(fb); | ||
618 | goto out; | ||
619 | } | ||
620 | |||
616 | drm_modeset_lock_all(dev); | 621 | drm_modeset_lock_all(dev); |
617 | /* remove from any CRTC */ | 622 | /* remove from any CRTC */ |
618 | drm_for_each_crtc(crtc, dev) { | 623 | drm_for_each_crtc(crtc, dev) { |
@@ -630,6 +635,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) | |||
630 | drm_modeset_unlock_all(dev); | 635 | drm_modeset_unlock_all(dev); |
631 | } | 636 | } |
632 | 637 | ||
638 | out: | ||
633 | drm_framebuffer_unreference(fb); | 639 | drm_framebuffer_unreference(fb); |
634 | } | 640 | } |
635 | EXPORT_SYMBOL(drm_framebuffer_remove); | 641 | EXPORT_SYMBOL(drm_framebuffer_remove); |
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 47a500b90fd7..b248e2238a05 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h | |||
@@ -125,6 +125,7 @@ int drm_atomic_get_property(struct drm_mode_object *obj, | |||
125 | struct drm_property *property, uint64_t *val); | 125 | struct drm_property *property, uint64_t *val); |
126 | int drm_mode_atomic_ioctl(struct drm_device *dev, | 126 | int drm_mode_atomic_ioctl(struct drm_device *dev, |
127 | void *data, struct drm_file *file_priv); | 127 | void *data, struct drm_file *file_priv); |
128 | int drm_atomic_remove_fb(struct drm_framebuffer *fb); | ||
128 | 129 | ||
129 | int drm_modeset_register_all(struct drm_device *dev); | 130 | int drm_modeset_register_all(struct drm_device *dev); |
130 | void drm_modeset_unregister_all(struct drm_device *dev); | 131 | void drm_modeset_unregister_all(struct drm_device *dev); |