Commit fd40a63c authored by André Almeida's avatar André Almeida Committed by Dmitry Baryshkov
Browse files

drm/atomic: Let drivers decide which planes to async flip



Currently, DRM atomic uAPI allows only primary planes to be flipped
asynchronously. However, each driver might be able to perform async
flips in other different plane types. To enable drivers to set their own
restrictions on which type of plane they can or cannot flip, use the
existing atomic_async_check() from struct drm_plane_helper_funcs to
enhance this flexibility, thus allowing different plane types to be able
to do async flips as well.

Create a new parameter for the atomic_async_check(), `bool flip`. This
parameter is used to distinguish when this function is being called from
a plane update from a full page flip.

In order to prevent regressions and such, we keep the current policy: we
skip the driver check for the primary plane, because it is always
allowed to do async flips on it.

Signed-off-by: default avatarAndré Almeida <andrealmeid@igalia.com>
Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: default avatarChristopher Snowhill <chris@kode54.net>
Tested-by: default avatarChristopher Snowhill <chris@kode54.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20250127-tonyk-async_flip-v12-1-0f7f8a8610d3@igalia.com


Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
parent 6fe52b63
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1966,7 +1966,7 @@ int drm_atomic_helper_async_check(struct drm_device *dev,
		return -EBUSY;
	}

	ret = funcs->atomic_async_check(plane, state);
	ret = funcs->atomic_async_check(plane, state, false);
	if (ret != 0)
		drm_dbg_atomic(dev,
			       "[PLANE:%d:%s] driver async check failed\n",
+27 −10
Original line number Diff line number Diff line
@@ -27,8 +27,9 @@
 * Daniel Vetter <daniel.vetter@ffwll.ch>
 */

#include <drm/drm_atomic_uapi.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_print.h>
#include <drm/drm_drv.h>
@@ -1063,6 +1064,7 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
		struct drm_plane *plane = obj_to_plane(obj);
		struct drm_plane_state *plane_state;
		struct drm_mode_config *config = &plane->dev->mode_config;
		const struct drm_plane_helper_funcs *plane_funcs = plane->helper_private;

		plane_state = drm_atomic_get_plane_state(state, plane);
		if (IS_ERR(plane_state)) {
@@ -1070,16 +1072,31 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
			break;
		}

		if (async_flip &&
		    (plane_state->plane->type != DRM_PLANE_TYPE_PRIMARY ||
		     (prop != config->prop_fb_id &&
		if (async_flip) {
			/* check if the prop does a nop change */
			if ((prop != config->prop_fb_id &&
			     prop != config->prop_in_fence_fd &&
		      prop != config->prop_fb_damage_clips))) {
			     prop != config->prop_fb_damage_clips)) {
				ret = drm_atomic_plane_get_property(plane, plane_state,
								    prop, &old_val);
				ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop);
			}

			/* ask the driver if this non-primary plane is supported */
			if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
				ret = -EINVAL;

				if (plane_funcs && plane_funcs->atomic_async_check)
					ret = plane_funcs->atomic_async_check(plane, state, true);

				if (ret) {
					drm_dbg_atomic(prop->dev,
						       "[PLANE:%d:%s] does not support async flips\n",
						       obj->id, plane->name);
					break;
				}
			}
		}

		ret = drm_atomic_plane_set_property(plane,
				plane_state, file_priv,
+2 −1
Original line number Diff line number Diff line
@@ -171,7 +171,8 @@ static const struct drm_plane_helper_funcs lsdc_primary_helper_funcs = {
};

static int lsdc_cursor_plane_atomic_async_check(struct drm_plane *plane,
						struct drm_atomic_state *state)
						struct drm_atomic_state *state,
						bool flip)
{
	struct drm_plane_state *new_state;
	struct drm_crtc_state *crtc_state;
+1 −1
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ static void mtk_plane_destroy_state(struct drm_plane *plane,
}

static int mtk_plane_atomic_async_check(struct drm_plane *plane,
					struct drm_atomic_state *state)
					struct drm_atomic_state *state, bool flip)
{
	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
										 plane);
+1 −1
Original line number Diff line number Diff line
@@ -368,7 +368,7 @@ static void mdp5_plane_atomic_update(struct drm_plane *plane,
}

static int mdp5_plane_atomic_async_check(struct drm_plane *plane,
					 struct drm_atomic_state *state)
					 struct drm_atomic_state *state, bool flip)
{
	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
										 plane);
Loading