@@ -673,7 +673,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
if (async)
return -EBUSY;
- ret = drm_atomic_helper_prepare_planes(dev, state);
+ ret = drm_atomic_helper_prepare_planes(dev, state, false);
if (ret)
return ret;
@@ -719,16 +719,22 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
* drm_atomic_helper_prepare_planes - prepare plane resources after commit
* @dev: DRM device
* @state: atomic state object with old state structures
+ * @async: asynchronous commit
*
* This function prepares plane state, specifically framebuffers, for the new
* configuration. If any failure is encountered this function will call
* ->cleanup_fb on any already successfully prepared framebuffer.
*
+ * If @async is true the driver callbacks should not wait for outstanding
+ * render, but instead ensure that the asynchronous commit work item is stalled
+ * sufficiently long.
+ *
* Returns:
* 0 on success, negative error code on failure.
*/
int drm_atomic_helper_prepare_planes(struct drm_device *dev,
- struct drm_atomic_state *state)
+ struct drm_atomic_state *state,
+ bool async)
{
int nplanes = dev->mode_config.num_total_plane;
int ret, i;
@@ -746,7 +752,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
fb = state->plane_states[i]->fb;
if (fb && funcs->prepare_fb) {
- ret = funcs->prepare_fb(plane, fb);
+ ret = funcs->prepare_fb(plane, fb, async);
if (ret)
goto fail;
}
@@ -993,7 +993,7 @@ int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
}
if (plane_funcs->prepare_fb) {
- ret = plane_funcs->prepare_fb(plane, plane_state->fb);
+ ret = plane_funcs->prepare_fb(plane, plane_state->fb, false);
if (ret)
goto fail;
}
@@ -435,7 +435,7 @@ int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
}
if (plane_funcs->prepare_fb) {
- ret = plane_funcs->prepare_fb(plane, fb);
+ ret = plane_funcs->prepare_fb(plane, fb, false);
if (ret)
goto fail;
}
@@ -514,7 +514,7 @@ int drm_plane_helper_disable(struct drm_plane *plane)
}
if (plane_funcs->prepare_fb) {
- ret = plane_funcs->prepare_fb(plane, fb);
+ ret = plane_funcs->prepare_fb(plane, fb, false);
if (ret)
goto fail;
}
@@ -40,7 +40,8 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev,
struct drm_atomic_state *old_state);
int drm_atomic_helper_prepare_planes(struct drm_device *dev,
- struct drm_atomic_state *state);
+ struct drm_atomic_state *state,
+ bool async);
void drm_atomic_helper_commit_planes(struct drm_device *dev,
struct drm_atomic_state *state);
void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
@@ -49,7 +49,8 @@
*/
struct drm_plane_helper_funcs {
int (*prepare_fb)(struct drm_plane *plane,
- struct drm_framebuffer *fb);
+ struct drm_framebuffer *fb,
+ bool async);
void (*cleanup_fb)(struct drm_plane *plane,
struct drm_framebuffer *fb);
Currently all helpers use ->prepare_fb for synchronous state updates, so we need the driver callback to wait for any outstanding rendering. But with async commit we really only want to reserve the framebuffer, but not stall for rendering. That should be done in the asynchronous worker. So add a boolean for this. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> --- drivers/gpu/drm/drm_atomic_helper.c | 12 +++++++++--- drivers/gpu/drm/drm_crtc_helper.c | 2 +- drivers/gpu/drm/drm_plane_helper.c | 4 ++-- include/drm/drm_atomic_helper.h | 3 ++- include/drm/drm_plane_helper.h | 3 ++- 5 files changed, 16 insertions(+), 8 deletions(-)