aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-06-05 21:56:00 -0400
committerDave Airlie <airlied@redhat.com>2019-06-05 21:57:13 -0400
commitdbd9f78ed23746e9708f773224eec2c8b33206e7 (patch)
treec3402e3caf21d9636f3d241d819b536adb0fd735
parent75cb3776fdffa94b424406aeb0efb76b122990f5 (diff)
parent283f1e383e91d96fe652fad549537ae15cf31d60 (diff)
Merge tag 'drm-misc-fixes-2019-06-05' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
- Allow fb changes in async commits (fixes igt failures) (Helen) - Actually unmap the scatterlist when unmapping udmabuf (Lucas) Cc: Lucas Stach <l.stach@pengutronix.de> Cc: Helen Koike <helen.koike@collabora.com> Signed-off-by: Dave Airlie <airlied@redhat.com> From: Sean Paul <sean@poorly.run> Link: https://patchwork.freedesktop.org/patch/msgid/20190605210335.GA35431@art_vandelay
-rw-r--r--drivers/dma-buf/udmabuf.c1
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c3
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c22
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c4
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c51
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c2
-rw-r--r--include/drm/drm_modeset_helper_vtables.h8
7 files changed, 53 insertions, 38 deletions
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index cd57747286f2..9635897458a0 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -77,6 +77,7 @@ static void unmap_udmabuf(struct dma_buf_attachment *at,
77 struct sg_table *sg, 77 struct sg_table *sg,
78 enum dma_data_direction direction) 78 enum dma_data_direction direction)
79{ 79{
80 dma_unmap_sg(at->dev, sg->sgl, sg->nents, direction);
80 sg_free_table(sg); 81 sg_free_table(sg);
81 kfree(sg); 82 kfree(sg);
82} 83}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index bcb1a93c0b4c..ab7c5c3004ee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4232,8 +4232,7 @@ static void dm_plane_atomic_async_update(struct drm_plane *plane,
4232 struct drm_plane_state *old_state = 4232 struct drm_plane_state *old_state =
4233 drm_atomic_get_old_plane_state(new_state->state, plane); 4233 drm_atomic_get_old_plane_state(new_state->state, plane);
4234 4234
4235 if (plane->state->fb != new_state->fb) 4235 swap(plane->state->fb, new_state->fb);
4236 drm_atomic_set_fb_for_plane(plane->state, new_state->fb);
4237 4236
4238 plane->state->src_x = new_state->src_x; 4237 plane->state->src_x = new_state->src_x;
4239 plane->state->src_y = new_state->src_y; 4238 plane->state->src_y = new_state->src_y;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 2e0cb4246cbd..22a5c617f670 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1607,15 +1607,6 @@ int drm_atomic_helper_async_check(struct drm_device *dev,
1607 old_plane_state->crtc != new_plane_state->crtc) 1607 old_plane_state->crtc != new_plane_state->crtc)
1608 return -EINVAL; 1608 return -EINVAL;
1609 1609
1610 /*
1611 * FIXME: Since prepare_fb and cleanup_fb are always called on
1612 * the new_plane_state for async updates we need to block framebuffer
1613 * changes. This prevents use of a fb that's been cleaned up and
1614 * double cleanups from occuring.
1615 */
1616 if (old_plane_state->fb != new_plane_state->fb)
1617 return -EINVAL;
1618
1619 funcs = plane->helper_private; 1610 funcs = plane->helper_private;
1620 if (!funcs->atomic_async_update) 1611 if (!funcs->atomic_async_update)
1621 return -EINVAL; 1612 return -EINVAL;
@@ -1646,6 +1637,8 @@ EXPORT_SYMBOL(drm_atomic_helper_async_check);
1646 * drm_atomic_async_check() succeeds. Async commits are not supposed to swap 1637 * drm_atomic_async_check() succeeds. Async commits are not supposed to swap
1647 * the states like normal sync commits, but just do in-place changes on the 1638 * the states like normal sync commits, but just do in-place changes on the
1648 * current state. 1639 * current state.
1640 *
1641 * TODO: Implement full swap instead of doing in-place changes.
1649 */ 1642 */
1650void drm_atomic_helper_async_commit(struct drm_device *dev, 1643void drm_atomic_helper_async_commit(struct drm_device *dev,
1651 struct drm_atomic_state *state) 1644 struct drm_atomic_state *state)
@@ -1656,6 +1649,9 @@ void drm_atomic_helper_async_commit(struct drm_device *dev,
1656 int i; 1649 int i;
1657 1650
1658 for_each_new_plane_in_state(state, plane, plane_state, i) { 1651 for_each_new_plane_in_state(state, plane, plane_state, i) {
1652 struct drm_framebuffer *new_fb = plane_state->fb;
1653 struct drm_framebuffer *old_fb = plane->state->fb;
1654
1659 funcs = plane->helper_private; 1655 funcs = plane->helper_private;
1660 funcs->atomic_async_update(plane, plane_state); 1656 funcs->atomic_async_update(plane, plane_state);
1661 1657
@@ -1664,11 +1660,17 @@ void drm_atomic_helper_async_commit(struct drm_device *dev,
1664 * plane->state in-place, make sure at least common 1660 * plane->state in-place, make sure at least common
1665 * properties have been properly updated. 1661 * properties have been properly updated.
1666 */ 1662 */
1667 WARN_ON_ONCE(plane->state->fb != plane_state->fb); 1663 WARN_ON_ONCE(plane->state->fb != new_fb);
1668 WARN_ON_ONCE(plane->state->crtc_x != plane_state->crtc_x); 1664 WARN_ON_ONCE(plane->state->crtc_x != plane_state->crtc_x);
1669 WARN_ON_ONCE(plane->state->crtc_y != plane_state->crtc_y); 1665 WARN_ON_ONCE(plane->state->crtc_y != plane_state->crtc_y);
1670 WARN_ON_ONCE(plane->state->src_x != plane_state->src_x); 1666 WARN_ON_ONCE(plane->state->src_x != plane_state->src_x);
1671 WARN_ON_ONCE(plane->state->src_y != plane_state->src_y); 1667 WARN_ON_ONCE(plane->state->src_y != plane_state->src_y);
1668
1669 /*
1670 * Make sure the FBs have been swapped so that cleanups in the
1671 * new_state performs a cleanup in the old FB.
1672 */
1673 WARN_ON_ONCE(plane_state->fb != old_fb);
1672 } 1674 }
1673} 1675}
1674EXPORT_SYMBOL(drm_atomic_helper_async_commit); 1676EXPORT_SYMBOL(drm_atomic_helper_async_commit);
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index be13140967b4..b854f471e9e5 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -502,6 +502,8 @@ static int mdp5_plane_atomic_async_check(struct drm_plane *plane,
502static void mdp5_plane_atomic_async_update(struct drm_plane *plane, 502static void mdp5_plane_atomic_async_update(struct drm_plane *plane,
503 struct drm_plane_state *new_state) 503 struct drm_plane_state *new_state)
504{ 504{
505 struct drm_framebuffer *old_fb = plane->state->fb;
506
505 plane->state->src_x = new_state->src_x; 507 plane->state->src_x = new_state->src_x;
506 plane->state->src_y = new_state->src_y; 508 plane->state->src_y = new_state->src_y;
507 plane->state->crtc_x = new_state->crtc_x; 509 plane->state->crtc_x = new_state->crtc_x;
@@ -524,6 +526,8 @@ static void mdp5_plane_atomic_async_update(struct drm_plane *plane,
524 526
525 *to_mdp5_plane_state(plane->state) = 527 *to_mdp5_plane_state(plane->state) =
526 *to_mdp5_plane_state(new_state); 528 *to_mdp5_plane_state(new_state);
529
530 new_state->fb = old_fb;
527} 531}
528 532
529static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = { 533static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 20a9c296d027..3bb242f7d32f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -924,29 +924,17 @@ static void vop_plane_atomic_async_update(struct drm_plane *plane,
924 struct drm_plane_state *new_state) 924 struct drm_plane_state *new_state)
925{ 925{
926 struct vop *vop = to_vop(plane->state->crtc); 926 struct vop *vop = to_vop(plane->state->crtc);
927 struct drm_plane_state *plane_state; 927 struct drm_framebuffer *old_fb = plane->state->fb;
928 928
929 plane_state = plane->funcs->atomic_duplicate_state(plane); 929 plane->state->crtc_x = new_state->crtc_x;
930 plane_state->crtc_x = new_state->crtc_x; 930 plane->state->crtc_y = new_state->crtc_y;
931 plane_state->crtc_y = new_state->crtc_y; 931 plane->state->crtc_h = new_state->crtc_h;
932 plane_state->crtc_h = new_state->crtc_h; 932 plane->state->crtc_w = new_state->crtc_w;
933 plane_state->crtc_w = new_state->crtc_w; 933 plane->state->src_x = new_state->src_x;
934 plane_state->src_x = new_state->src_x; 934 plane->state->src_y = new_state->src_y;
935 plane_state->src_y = new_state->src_y; 935 plane->state->src_h = new_state->src_h;
936 plane_state->src_h = new_state->src_h; 936 plane->state->src_w = new_state->src_w;
937 plane_state->src_w = new_state->src_w; 937 swap(plane->state->fb, new_state->fb);
938
939 if (plane_state->fb != new_state->fb)
940 drm_atomic_set_fb_for_plane(plane_state, new_state->fb);
941
942 swap(plane_state, plane->state);
943
944 if (plane->state->fb && plane->state->fb != new_state->fb) {
945 drm_framebuffer_get(plane->state->fb);
946 WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
947 drm_flip_work_queue(&vop->fb_unref_work, plane->state->fb);
948 set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
949 }
950 938
951 if (vop->is_enabled) { 939 if (vop->is_enabled) {
952 rockchip_drm_psr_inhibit_get_state(new_state->state); 940 rockchip_drm_psr_inhibit_get_state(new_state->state);
@@ -955,9 +943,22 @@ static void vop_plane_atomic_async_update(struct drm_plane *plane,
955 vop_cfg_done(vop); 943 vop_cfg_done(vop);
956 spin_unlock(&vop->reg_lock); 944 spin_unlock(&vop->reg_lock);
957 rockchip_drm_psr_inhibit_put_state(new_state->state); 945 rockchip_drm_psr_inhibit_put_state(new_state->state);
958 }
959 946
960 plane->funcs->atomic_destroy_state(plane, plane_state); 947 /*
948 * A scanout can still be occurring, so we can't drop the
949 * reference to the old framebuffer. To solve this we get a
950 * reference to old_fb and set a worker to release it later.
951 * FIXME: if we perform 500 async_update calls before the
952 * vblank, then we can have 500 different framebuffers waiting
953 * to be released.
954 */
955 if (old_fb && plane->state->fb != old_fb) {
956 drm_framebuffer_get(old_fb);
957 WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
958 drm_flip_work_queue(&vop->fb_unref_work, old_fb);
959 set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
960 }
961 }
961} 962}
962 963
963static const struct drm_plane_helper_funcs plane_helper_funcs = { 964static const struct drm_plane_helper_funcs plane_helper_funcs = {
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 4d918d3e4858..afc80b245ea3 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -1025,7 +1025,7 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane,
1025{ 1025{
1026 struct vc4_plane_state *vc4_state, *new_vc4_state; 1026 struct vc4_plane_state *vc4_state, *new_vc4_state;
1027 1027
1028 drm_atomic_set_fb_for_plane(plane->state, state->fb); 1028 swap(plane->state->fb, state->fb);
1029 plane->state->crtc_x = state->crtc_x; 1029 plane->state->crtc_x = state->crtc_x;
1030 plane->state->crtc_y = state->crtc_y; 1030 plane->state->crtc_y = state->crtc_y;
1031 plane->state->crtc_w = state->crtc_w; 1031 plane->state->crtc_w = state->crtc_w;
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index f9c94c2a1364..f7bbd0b0ecd1 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -1185,6 +1185,14 @@ struct drm_plane_helper_funcs {
1185 * current one with the new plane configurations in the new 1185 * current one with the new plane configurations in the new
1186 * plane_state. 1186 * plane_state.
1187 * 1187 *
1188 * Drivers should also swap the framebuffers between current plane
1189 * state (&drm_plane.state) and new_state.
1190 * This is required since cleanup for async commits is performed on
1191 * the new state, rather than old state like for traditional commits.
1192 * Since we want to give up the reference on the current (old) fb
1193 * instead of our brand new one, swap them in the driver during the
1194 * async commit.
1195 *
1188 * FIXME: 1196 * FIXME:
1189 * - It only works for single plane updates 1197 * - It only works for single plane updates
1190 * - Async Pageflips are not supported yet 1198 * - Async Pageflips are not supported yet