summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic_helper.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-10-29 11:34:56 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-11-06 21:02:22 +0100
commite2330f0719515e41090a4d9685b931888b7c01d6 (patch)
treea4397df4818daa8a5ebdf68e3b0ac88422e8b6db /drivers/gpu/drm/drm_atomic_helper.c
parent042652ed95996a9ef6dcddddc53b5d8bc7fa887e (diff)
drm/atomic: Integrate fence support
This patch is for enabling async commits. It replaces an earlier approach which added an async boolean paramter to the ->prepare_fb callbacks. The idea is that prepare_fb picks up the right fence to synchronize against, which is then used by the synchronous commit helper. For async commits drivers can either register a callback to the fence or simply do the synchronous wait in their async work queue. v2: Remove unused variable. v3: Only wait for fences after the point of no return in the part of the commit function which can be run asynchronously. This is after the atomic state has been swapped in, hence now check plane->state->fence. Also add a WARN_ON to make sure we don't try to wait on a fence when there's no fb, just as a sanity check. Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/gpu/drm/drm_atomic_helper.c')
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 077c792c46e..4808e71dedb 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -30,6 +30,7 @@
#include <drm/drm_plane_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_atomic_helper.h>
+#include <linux/fence.h>
static void
drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
@@ -712,6 +713,26 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_atomic_helper_commit_post_planes);
+static void wait_for_fences(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ int nplanes = dev->mode_config.num_total_plane;
+ int i;
+
+ for (i = 0; i < nplanes; i++) {
+ struct drm_plane *plane = state->planes[i];
+
+ if (!plane || !plane->state->fence)
+ continue;
+
+ WARN_ON(!plane->state->fb);
+
+ fence_wait(plane->state->fence, false);
+ fence_put(plane->state->fence);
+ plane->state->fence = NULL;
+ }
+}
+
static void
wait_for_vblanks(struct drm_device *dev, struct drm_atomic_state *old_state)
{
@@ -809,6 +830,8 @@ int drm_atomic_helper_commit(struct drm_device *dev,
* current layout.
*/
+ wait_for_fences(dev, state);
+
drm_atomic_helper_commit_pre_planes(dev, state);
drm_atomic_helper_commit_planes(dev, state);