Commit 169b9182 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/atomic-helper: Add atomic_enable plane-helper callback



Add atomic_enable to struct drm_plane_helper_funcs. It enables a
plane independently from updating the plane's content. As such, it is
the inverse of the atomic_disable plane helper. Useful for hardware
where plane enable state is independent from plane content.

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230209154107.30680-2-tzimmermann@suse.de
parent 1e84dadb
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -2702,6 +2702,11 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
			funcs->atomic_disable(plane, old_state);
		} else if (new_plane_state->crtc || disabling) {
			funcs->atomic_update(plane, old_state);

			if (!disabling && funcs->atomic_enable) {
				if (drm_atomic_plane_enabling(old_plane_state, new_plane_state))
					funcs->atomic_enable(plane, old_state);
			}
		}
	}

@@ -2762,6 +2767,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
		struct drm_plane_state *new_plane_state =
			drm_atomic_get_new_plane_state(old_state, plane);
		const struct drm_plane_helper_funcs *plane_funcs;
		bool disabling;

		plane_funcs = plane->helper_private;

@@ -2771,12 +2777,18 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
		WARN_ON(new_plane_state->crtc &&
			new_plane_state->crtc != crtc);

		if (drm_atomic_plane_disabling(old_plane_state, new_plane_state) &&
		    plane_funcs->atomic_disable)
		disabling = drm_atomic_plane_disabling(old_plane_state, new_plane_state);

		if (disabling && plane_funcs->atomic_disable) {
			plane_funcs->atomic_disable(plane, old_state);
		else if (new_plane_state->crtc ||
			 drm_atomic_plane_disabling(old_plane_state, new_plane_state))
		} else if (new_plane_state->crtc || disabling) {
			plane_funcs->atomic_update(plane, old_state);

			if (!disabling && plane_funcs->atomic_enable) {
				if (drm_atomic_plane_enabling(old_plane_state, new_plane_state))
					plane_funcs->atomic_enable(plane, old_state);
			}
		}
	}

	if (crtc_funcs && crtc_funcs->atomic_flush)
+26 −0
Original line number Diff line number Diff line
@@ -209,6 +209,32 @@ int drm_atomic_helper_page_flip_target(
			      __drm_atomic_get_current_plane_state((crtc_state)->state, \
								   plane)))

/**
 * drm_atomic_plane_enabling - check whether a plane is being enabled
 * @old_plane_state: old atomic plane state
 * @new_plane_state: new atomic plane state
 *
 * Checks the atomic state of a plane to determine whether it's being enabled
 * or not. This also WARNs if it detects an invalid state (both CRTC and FB
 * need to either both be NULL or both be non-NULL).
 *
 * RETURNS:
 * True if the plane is being enabled, false otherwise.
 */
static inline bool drm_atomic_plane_enabling(struct drm_plane_state *old_plane_state,
					     struct drm_plane_state *new_plane_state)
{
	/*
	 * When enabling a plane, CRTC and FB should always be set together.
	 * Anything else should be considered a bug in the atomic core, so we
	 * gently warn about it.
	 */
	WARN_ON((!new_plane_state->crtc && new_plane_state->fb) ||
		(new_plane_state->crtc && !new_plane_state->fb));

	return !old_plane_state->crtc && new_plane_state->crtc;
}

/**
 * drm_atomic_plane_disabling - check whether a plane is being disabled
 * @old_plane_state: old atomic plane state
+28 −1
Original line number Diff line number Diff line
@@ -1331,6 +1331,32 @@ struct drm_plane_helper_funcs {
	 */
	void (*atomic_update)(struct drm_plane *plane,
			      struct drm_atomic_state *state);

	/**
	 * @atomic_enable:
	 *
	 * Drivers should use this function to unconditionally enable a plane.
	 * This hook is called in-between the &drm_crtc_helper_funcs.atomic_begin
	 * and drm_crtc_helper_funcs.atomic_flush callbacks. It is called after
	 * @atomic_update, which will be called for all enabled planes. Drivers
	 * that use @atomic_enable should set up a plane in @atomic_update and
	 * afterwards enable the plane in @atomic_enable. If a plane needs to be
	 * enabled before installing the scanout buffer, drivers can still do
	 * so in @atomic_update.
	 *
	 * Note that the power state of the display pipe when this function is
	 * called depends upon the exact helpers and calling sequence the driver
	 * has picked. See drm_atomic_helper_commit_planes() for a discussion of
	 * the tradeoffs and variants of plane commit helpers.
	 *
	 * This callback is used by the atomic modeset helpers, but it is
	 * optional. If implemented, @atomic_enable should be the inverse of
	 * @atomic_disable. Drivers that don't want to use either can still
	 * implement the complete plane update in @atomic_update.
	 */
	void (*atomic_enable)(struct drm_plane *plane,
			      struct drm_atomic_state *state);

	/**
	 * @atomic_disable:
	 *
@@ -1351,7 +1377,8 @@ struct drm_plane_helper_funcs {
	 * the tradeoffs and variants of plane commit helpers.
	 *
	 * This callback is used by the atomic modeset helpers and by the
	 * transitional plane helpers, but it is optional.
	 * transitional plane helpers, but it is optional. It's intended to
	 * reverse the effects of @atomic_enable.
	 */
	void (*atomic_disable)(struct drm_plane *plane,
			       struct drm_atomic_state *state);