aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_atomic.c')
-rw-r--r--drivers/gpu/drm/drm_atomic.c61
1 files changed, 42 insertions, 19 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 7bb3845d9974..aeee083c7f95 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1432,6 +1432,45 @@ static int atomic_set_prop(struct drm_atomic_state *state,
1432 return ret; 1432 return ret;
1433} 1433}
1434 1434
1435/**
1436 * drm_atomic_update_old_fb -- Unset old_fb pointers and set plane->fb pointers.
1437 *
1438 * @dev: drm device to check.
1439 * @plane_mask: plane mask for planes that were updated.
1440 * @ret: return value, can be -EDEADLK for a retry.
1441 *
1442 * Before doing an update plane->old_fb is set to plane->fb,
1443 * but before dropping the locks old_fb needs to be set to NULL
1444 * and plane->fb updated. This is a common operation for each
1445 * atomic update, so this call is split off as a helper.
1446 */
1447void drm_atomic_clean_old_fb(struct drm_device *dev,
1448 unsigned plane_mask,
1449 int ret)
1450{
1451 struct drm_plane *plane;
1452
1453 /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping
1454 * locks (ie. while it is still safe to deref plane->state). We
1455 * need to do this here because the driver entry points cannot
1456 * distinguish between legacy and atomic ioctls.
1457 */
1458 drm_for_each_plane_mask(plane, dev, plane_mask) {
1459 if (ret == 0) {
1460 struct drm_framebuffer *new_fb = plane->state->fb;
1461 if (new_fb)
1462 drm_framebuffer_reference(new_fb);
1463 plane->fb = new_fb;
1464 plane->crtc = plane->state->crtc;
1465
1466 if (plane->old_fb)
1467 drm_framebuffer_unreference(plane->old_fb);
1468 }
1469 plane->old_fb = NULL;
1470 }
1471}
1472EXPORT_SYMBOL(drm_atomic_clean_old_fb);
1473
1435int drm_mode_atomic_ioctl(struct drm_device *dev, 1474int drm_mode_atomic_ioctl(struct drm_device *dev,
1436 void *data, struct drm_file *file_priv) 1475 void *data, struct drm_file *file_priv)
1437{ 1476{
@@ -1446,7 +1485,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
1446 struct drm_plane *plane; 1485 struct drm_plane *plane;
1447 struct drm_crtc *crtc; 1486 struct drm_crtc *crtc;
1448 struct drm_crtc_state *crtc_state; 1487 struct drm_crtc_state *crtc_state;
1449 unsigned plane_mask = 0; 1488 unsigned plane_mask;
1450 int ret = 0; 1489 int ret = 0;
1451 unsigned int i, j; 1490 unsigned int i, j;
1452 1491
@@ -1486,6 +1525,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
1486 state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET); 1525 state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);
1487 1526
1488retry: 1527retry:
1528 plane_mask = 0;
1489 copied_objs = 0; 1529 copied_objs = 0;
1490 copied_props = 0; 1530 copied_props = 0;
1491 1531
@@ -1576,24 +1616,7 @@ retry:
1576 } 1616 }
1577 1617
1578out: 1618out:
1579 /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping 1619 drm_atomic_clean_old_fb(dev, plane_mask, ret);
1580 * locks (ie. while it is still safe to deref plane->state). We
1581 * need to do this here because the driver entry points cannot
1582 * distinguish between legacy and atomic ioctls.
1583 */
1584 drm_for_each_plane_mask(plane, dev, plane_mask) {
1585 if (ret == 0) {
1586 struct drm_framebuffer *new_fb = plane->state->fb;
1587 if (new_fb)
1588 drm_framebuffer_reference(new_fb);
1589 plane->fb = new_fb;
1590 plane->crtc = plane->state->crtc;
1591
1592 if (plane->old_fb)
1593 drm_framebuffer_unreference(plane->old_fb);
1594 }
1595 plane->old_fb = NULL;
1596 }
1597 1620
1598 if (ret && arg->flags & DRM_MODE_PAGE_FLIP_EVENT) { 1621 if (ret && arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
1599 /* 1622 /*