Commit 2b58e98d authored by Liu Ying's avatar Liu Ying Committed by Daniel Vetter

drm/atomic-helper: Add NO_DISABLE_AFTER_MODESET flag support for plane commit

Drivers may set the NO_DISABLE_AFTER_MODESET flag in the 'flags' parameter
of the helper drm_atomic_helper_commit_planes() if the relevant display
controllers(e.g., IPUv3 for imx-drm) require to disable a CRTC's planes
when the CRTC is disabled. The helper would skip the ->atomic_disable
call for a plane if the CRTC of the old plane state needs a modesetting
operation. Of course, the drivers need to disable the planes in their CRTC
disable callbacks since no one else would do that.
Suggested-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: David Airlie <airlied@linux.ie>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Peter Senna Tschudin <peter.senna@gmail.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: default avatarLiu Ying <gnuiyl@gmail.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1472461923-14364-1-git-send-email-gnuiyl@gmail.com
parent 28500291
...@@ -91,7 +91,8 @@ static void malidp_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -91,7 +91,8 @@ static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_disables(drm, state); drm_atomic_helper_commit_modeset_disables(drm, state);
drm_atomic_helper_commit_modeset_enables(drm, state); drm_atomic_helper_commit_modeset_enables(drm, state);
drm_atomic_helper_commit_planes(drm, state, true); drm_atomic_helper_commit_planes(drm, state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
malidp_atomic_commit_hw_done(state); malidp_atomic_commit_hw_done(state);
......
...@@ -457,7 +457,7 @@ atmel_hlcdc_dc_atomic_complete(struct atmel_hlcdc_dc_commit *commit) ...@@ -457,7 +457,7 @@ atmel_hlcdc_dc_atomic_complete(struct atmel_hlcdc_dc_commit *commit)
/* Apply the atomic update. */ /* Apply the atomic update. */
drm_atomic_helper_commit_modeset_disables(dev, old_state); drm_atomic_helper_commit_modeset_disables(dev, old_state);
drm_atomic_helper_commit_planes(dev, old_state, false); drm_atomic_helper_commit_planes(dev, old_state, 0);
drm_atomic_helper_commit_modeset_enables(dev, old_state); drm_atomic_helper_commit_modeset_enables(dev, old_state);
drm_atomic_helper_wait_for_vblanks(dev, old_state); drm_atomic_helper_wait_for_vblanks(dev, old_state);
......
...@@ -1148,7 +1148,8 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks); ...@@ -1148,7 +1148,8 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
* *
* drm_atomic_helper_commit_modeset_enables(dev, state); * drm_atomic_helper_commit_modeset_enables(dev, state);
* *
* drm_atomic_helper_commit_planes(dev, state, true); * drm_atomic_helper_commit_planes(dev, state,
* DRM_PLANE_COMMIT_ACTIVE_ONLY);
* *
* for committing the atomic update to hardware. See the kerneldoc entries for * for committing the atomic update to hardware. See the kerneldoc entries for
* these three functions for more details. * these three functions for more details.
...@@ -1159,7 +1160,7 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *state) ...@@ -1159,7 +1160,7 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_disables(dev, state);
drm_atomic_helper_commit_planes(dev, state, false); drm_atomic_helper_commit_planes(dev, state, 0);
drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state);
...@@ -1678,7 +1679,7 @@ bool plane_crtc_active(struct drm_plane_state *state) ...@@ -1678,7 +1679,7 @@ bool plane_crtc_active(struct drm_plane_state *state)
* drm_atomic_helper_commit_planes - commit plane state * drm_atomic_helper_commit_planes - commit plane state
* @dev: DRM device * @dev: DRM device
* @old_state: atomic state object with old state structures * @old_state: atomic state object with old state structures
* @active_only: Only commit on active CRTC if set * @flags: flags for committing plane state
* *
* This function commits the new plane state using the plane and atomic helper * This function commits the new plane state using the plane and atomic helper
* functions for planes and crtcs. It assumes that the atomic state has already * functions for planes and crtcs. It assumes that the atomic state has already
...@@ -1698,25 +1699,34 @@ bool plane_crtc_active(struct drm_plane_state *state) ...@@ -1698,25 +1699,34 @@ bool plane_crtc_active(struct drm_plane_state *state)
* most drivers don't need to be immediately notified of plane updates for a * most drivers don't need to be immediately notified of plane updates for a
* disabled CRTC. * disabled CRTC.
* *
* Unless otherwise needed, drivers are advised to set the @active_only * Unless otherwise needed, drivers are advised to set the ACTIVE_ONLY flag in
* parameters to true in order not to receive plane update notifications related * @flags in order not to receive plane update notifications related to a
* to a disabled CRTC. This avoids the need to manually ignore plane updates in * disabled CRTC. This avoids the need to manually ignore plane updates in
* driver code when the driver and/or hardware can't or just don't need to deal * driver code when the driver and/or hardware can't or just don't need to deal
* with updates on disabled CRTCs, for example when supporting runtime PM. * with updates on disabled CRTCs, for example when supporting runtime PM.
* *
* The drm_atomic_helper_commit() default implementation only sets @active_only * Drivers may set the NO_DISABLE_AFTER_MODESET flag in @flags if the relevant
* to false to most closely match the behaviour of the legacy helpers. This should * display controllers require to disable a CRTC's planes when the CRTC is
* not be copied blindly by drivers. * disabled. This function would skip the ->atomic_disable call for a plane if
* the CRTC of the old plane state needs a modesetting operation. Of course,
* the drivers need to disable the planes in their CRTC disable callbacks
* since no one else would do that.
*
* The drm_atomic_helper_commit() default implementation doesn't set the
* ACTIVE_ONLY flag to most closely match the behaviour of the legacy helpers.
* This should not be copied blindly by drivers.
*/ */
void drm_atomic_helper_commit_planes(struct drm_device *dev, void drm_atomic_helper_commit_planes(struct drm_device *dev,
struct drm_atomic_state *old_state, struct drm_atomic_state *old_state,
bool active_only) uint32_t flags)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *old_crtc_state;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *old_plane_state; struct drm_plane_state *old_plane_state;
int i; int i;
bool active_only = flags & DRM_PLANE_COMMIT_ACTIVE_ONLY;
bool no_disable = flags & DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET;
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
...@@ -1760,11 +1770,20 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1760,11 +1770,20 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
/* /*
* Special-case disabling the plane if drivers support it. * Special-case disabling the plane if drivers support it.
*/ */
if (disabling && funcs->atomic_disable) if (disabling && funcs->atomic_disable) {
struct drm_crtc_state *crtc_state;
crtc_state = old_plane_state->crtc->state;
if (drm_atomic_crtc_needs_modeset(crtc_state) &&
no_disable)
continue;
funcs->atomic_disable(plane, old_plane_state); funcs->atomic_disable(plane, old_plane_state);
else if (plane->state->crtc || disabling) } else if (plane->state->crtc || disabling) {
funcs->atomic_update(plane, old_plane_state); funcs->atomic_update(plane, old_plane_state);
} }
}
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
......
...@@ -105,7 +105,7 @@ static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit) ...@@ -105,7 +105,7 @@ static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit)
atomic_inc(&exynos_crtc->pending_update); atomic_inc(&exynos_crtc->pending_update);
} }
drm_atomic_helper_commit_planes(dev, state, false); drm_atomic_helper_commit_planes(dev, state, 0);
exynos_atomic_wait_for_commit(state); exynos_atomic_wait_for_commit(state);
......
...@@ -193,7 +193,8 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -193,7 +193,8 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_disables(dev, state);
drm_atomic_helper_commit_planes(dev, state, true); drm_atomic_helper_commit_planes(dev, state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state);
......
...@@ -70,13 +70,15 @@ static void mtk_atomic_complete(struct mtk_drm_private *private, ...@@ -70,13 +70,15 @@ static void mtk_atomic_complete(struct mtk_drm_private *private,
* *
* drm_atomic_helper_commit_modeset_disables(dev, state); * drm_atomic_helper_commit_modeset_disables(dev, state);
* drm_atomic_helper_commit_modeset_enables(dev, state); * drm_atomic_helper_commit_modeset_enables(dev, state);
* drm_atomic_helper_commit_planes(dev, state, true); * drm_atomic_helper_commit_planes(dev, state,
* DRM_PLANE_COMMIT_ACTIVE_ONLY);
* *
* See the kerneldoc entries for these three functions for more details. * See the kerneldoc entries for these three functions for more details.
*/ */
drm_atomic_helper_commit_modeset_disables(drm, state); drm_atomic_helper_commit_modeset_disables(drm, state);
drm_atomic_helper_commit_modeset_enables(drm, state); drm_atomic_helper_commit_modeset_enables(drm, state);
drm_atomic_helper_commit_planes(drm, state, true); drm_atomic_helper_commit_planes(drm, state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_wait_for_vblanks(drm, state); drm_atomic_helper_wait_for_vblanks(drm, state);
......
...@@ -118,7 +118,7 @@ static void complete_commit(struct msm_commit *c, bool async) ...@@ -118,7 +118,7 @@ static void complete_commit(struct msm_commit *c, bool async)
drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_disables(dev, state);
drm_atomic_helper_commit_planes(dev, state, false); drm_atomic_helper_commit_planes(dev, state, 0);
drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state);
......
...@@ -96,7 +96,7 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit) ...@@ -96,7 +96,7 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
dispc_runtime_get(); dispc_runtime_get();
drm_atomic_helper_commit_modeset_disables(dev, old_state); drm_atomic_helper_commit_modeset_disables(dev, old_state);
drm_atomic_helper_commit_planes(dev, old_state, false); drm_atomic_helper_commit_planes(dev, old_state, 0);
drm_atomic_helper_commit_modeset_enables(dev, old_state); drm_atomic_helper_commit_modeset_enables(dev, old_state);
omap_atomic_wait_for_completion(dev, old_state); omap_atomic_wait_for_completion(dev, old_state);
......
...@@ -257,7 +257,8 @@ static void rcar_du_atomic_complete(struct rcar_du_commit *commit) ...@@ -257,7 +257,8 @@ static void rcar_du_atomic_complete(struct rcar_du_commit *commit)
/* Apply the atomic update. */ /* Apply the atomic update. */
drm_atomic_helper_commit_modeset_disables(dev, old_state); drm_atomic_helper_commit_modeset_disables(dev, old_state);
drm_atomic_helper_commit_modeset_enables(dev, old_state); drm_atomic_helper_commit_modeset_enables(dev, old_state);
drm_atomic_helper_commit_planes(dev, old_state, true); drm_atomic_helper_commit_planes(dev, old_state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_wait_for_vblanks(dev, old_state); drm_atomic_helper_wait_for_vblanks(dev, old_state);
......
...@@ -233,7 +233,8 @@ rockchip_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -233,7 +233,8 @@ rockchip_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state);
drm_atomic_helper_commit_planes(dev, state, true); drm_atomic_helper_commit_planes(dev, state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_commit_hw_done(state); drm_atomic_helper_commit_hw_done(state);
......
...@@ -178,7 +178,7 @@ static void sti_atomic_complete(struct sti_private *private, ...@@ -178,7 +178,7 @@ static void sti_atomic_complete(struct sti_private *private,
*/ */
drm_atomic_helper_commit_modeset_disables(drm, state); drm_atomic_helper_commit_modeset_disables(drm, state);
drm_atomic_helper_commit_planes(drm, state, false); drm_atomic_helper_commit_planes(drm, state, 0);
drm_atomic_helper_commit_modeset_enables(drm, state); drm_atomic_helper_commit_modeset_enables(drm, state);
drm_atomic_helper_wait_for_vblanks(drm, state); drm_atomic_helper_wait_for_vblanks(drm, state);
......
...@@ -57,7 +57,8 @@ static void tegra_atomic_complete(struct tegra_drm *tegra, ...@@ -57,7 +57,8 @@ static void tegra_atomic_complete(struct tegra_drm *tegra,
drm_atomic_helper_commit_modeset_disables(drm, state); drm_atomic_helper_commit_modeset_disables(drm, state);
drm_atomic_helper_commit_modeset_enables(drm, state); drm_atomic_helper_commit_modeset_enables(drm, state);
drm_atomic_helper_commit_planes(drm, state, true); drm_atomic_helper_commit_planes(drm, state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_wait_for_vblanks(drm, state); drm_atomic_helper_wait_for_vblanks(drm, state);
......
...@@ -118,7 +118,7 @@ static int tilcdc_commit(struct drm_device *dev, ...@@ -118,7 +118,7 @@ static int tilcdc_commit(struct drm_device *dev,
drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_disables(dev, state);
drm_atomic_helper_commit_planes(dev, state, false); drm_atomic_helper_commit_planes(dev, state, 0);
drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state);
......
...@@ -44,7 +44,7 @@ vc4_atomic_complete_commit(struct vc4_commit *c) ...@@ -44,7 +44,7 @@ vc4_atomic_complete_commit(struct vc4_commit *c)
drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_disables(dev, state);
drm_atomic_helper_commit_planes(dev, state, false); drm_atomic_helper_commit_planes(dev, state, 0);
drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state);
......
...@@ -338,7 +338,8 @@ static void vgdev_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -338,7 +338,8 @@ static void vgdev_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_disables(dev, state);
drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state);
drm_atomic_helper_commit_planes(dev, state, true); drm_atomic_helper_commit_planes(dev, state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_commit_hw_done(state); drm_atomic_helper_commit_hw_done(state);
......
...@@ -65,9 +65,13 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, ...@@ -65,9 +65,13 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
int drm_atomic_helper_prepare_planes(struct drm_device *dev, int drm_atomic_helper_prepare_planes(struct drm_device *dev,
struct drm_atomic_state *state); struct drm_atomic_state *state);
#define DRM_PLANE_COMMIT_ACTIVE_ONLY BIT(0)
#define DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET BIT(1)
void drm_atomic_helper_commit_planes(struct drm_device *dev, void drm_atomic_helper_commit_planes(struct drm_device *dev,
struct drm_atomic_state *state, struct drm_atomic_state *state,
bool active_only); uint32_t flags);
void drm_atomic_helper_cleanup_planes(struct drm_device *dev, void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
struct drm_atomic_state *old_state); struct drm_atomic_state *old_state);
void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state); void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment