aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2016-06-08 08:19:16 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-07-13 06:56:20 -0400
commit11c21e73f848844d439cbccb42a1018b8c560e5c (patch)
tree6e0563aca3d269d7f8383e58a003cd7555f830ac
parentcf47a07ab8f65d1d1fdbb72f4c38efe293f7a623 (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.c66
-rw-r--r--drivers/gpu/drm/drm_crtc.c6
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h1
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}
1565EXPORT_SYMBOL(drm_atomic_clean_old_fb); 1565EXPORT_SYMBOL(drm_atomic_clean_old_fb);
1566 1566
1567int 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
1583retry:
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
1615unlock:
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
1567int drm_mode_atomic_ioctl(struct drm_device *dev, 1633int 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
638out:
633 drm_framebuffer_unreference(fb); 639 drm_framebuffer_unreference(fb);
634} 640}
635EXPORT_SYMBOL(drm_framebuffer_remove); 641EXPORT_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);
126int drm_mode_atomic_ioctl(struct drm_device *dev, 126int drm_mode_atomic_ioctl(struct drm_device *dev,
127 void *data, struct drm_file *file_priv); 127 void *data, struct drm_file *file_priv);
128int drm_atomic_remove_fb(struct drm_framebuffer *fb);
128 129
129int drm_modeset_register_all(struct drm_device *dev); 130int drm_modeset_register_all(struct drm_device *dev);
130void drm_modeset_unregister_all(struct drm_device *dev); 131void drm_modeset_unregister_all(struct drm_device *dev);