drm/atomic-helper: Add NO_DISABLE_AFTER_MODESET flag support for plane commit
authorLiu Ying <gnuiyl@gmail.com>
Mon, 29 Aug 2016 09:12:03 +0000 (17:12 +0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 29 Aug 2016 09:29:37 +0000 (11:29 +0200)
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: Daniel 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: Liu Ying <gnuiyl@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1472461923-14364-1-git-send-email-gnuiyl@gmail.com
16 files changed:
drivers/gpu/drm/arm/malidp_drv.c
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/imx/imx-drm-core.c
drivers/gpu/drm/mediatek/mtk_drm_drv.c
drivers/gpu/drm/msm/msm_atomic.c
drivers/gpu/drm/omapdrm/omap_drv.c
drivers/gpu/drm/rcar-du/rcar_du_kms.c
drivers/gpu/drm/rockchip/rockchip_drm_fb.c
drivers/gpu/drm/sti/sti_drv.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tilcdc/tilcdc_drv.c
drivers/gpu/drm/vc4/vc4_kms.c
drivers/gpu/drm/virtio/virtgpu_display.c
include/drm/drm_atomic_helper.h

index 82171d223f2d4f469ebfeac54aeba04cab4b015a..c383d724527f662dd3dadc15702d56442e164280 100644 (file)
@@ -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_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);
 
index d4a3d61b7b06edaa869b03a17e1da51a76580277..8e7483d90c47fd5328464644673a5cededf24ac5 100644 (file)
@@ -457,7 +457,7 @@ atmel_hlcdc_dc_atomic_complete(struct atmel_hlcdc_dc_commit *commit)
 
        /* Apply the atomic update. */
        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_wait_for_vblanks(dev, old_state);
index 5f82290f2f0fba0e5fbe17f582abc9f7a3a28b38..6fdd7ba478969db606c1e1a23b32e7fbe742969f 100644 (file)
@@ -1148,7 +1148,8 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
  *
  *     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
  * these three functions for more details.
@@ -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_planes(dev, state, false);
+       drm_atomic_helper_commit_planes(dev, state, 0);
 
        drm_atomic_helper_commit_modeset_enables(dev, state);
 
@@ -1678,7 +1679,7 @@ bool plane_crtc_active(struct drm_plane_state *state)
  * drm_atomic_helper_commit_planes - commit plane state
  * @dev: DRM device
  * @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
  * 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)
  * most drivers don't need to be immediately notified of plane updates for a
  * disabled CRTC.
  *
- * Unless otherwise needed, drivers are advised to set the @active_only
- * parameters to true in order not to receive plane update notifications related
- * to a disabled CRTC. This avoids the need to manually ignore plane updates in
+ * Unless otherwise needed, drivers are advised to set the ACTIVE_ONLY flag in
+ * @flags in order not to receive plane update notifications related to a
+ * 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
  * with updates on disabled CRTCs, for example when supporting runtime PM.
  *
- * The drm_atomic_helper_commit() default implementation only sets @active_only
- * to false to most closely match the behaviour of the legacy helpers. This should
- * not be copied blindly by drivers.
+ * Drivers may set the NO_DISABLE_AFTER_MODESET flag in @flags if the relevant
+ * display controllers require to disable a CRTC's planes when the CRTC is
+ * 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,
                                     struct drm_atomic_state *old_state,
-                                    bool active_only)
+                                    uint32_t flags)
 {
        struct drm_crtc *crtc;
        struct drm_crtc_state *old_crtc_state;
        struct drm_plane *plane;
        struct drm_plane_state *old_plane_state;
        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) {
                const struct drm_crtc_helper_funcs *funcs;
@@ -1760,10 +1770,19 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
                /*
                 * 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);
-               else if (plane->state->crtc || disabling)
+               } else if (plane->state->crtc || disabling) {
                        funcs->atomic_update(plane, old_plane_state);
+               }
        }
 
        for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
index 877d2efa28e2171a1d2e07f4feef9a9fdd1eac7c..486943e70f70bc7137a8e64a156cf8d12b8e9bc3 100644 (file)
@@ -105,7 +105,7 @@ static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit)
                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);
 
index 438bac8fbc2bb5976f131e4200a85813de63142c..56dfc4cd50c6b09432293f4b1b5ef89280a59fee 100644 (file)
@@ -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_planes(dev, state, true);
+       drm_atomic_helper_commit_planes(dev, state,
+                                       DRM_PLANE_COMMIT_ACTIVE_ONLY);
 
        drm_atomic_helper_commit_modeset_enables(dev, state);
 
index 0e769abd0c2cd5fb4aa419d67a179b8e2afdaf6c..72c1ae4e02d4315252a606a812fbe7a9a2017663 100644 (file)
@@ -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_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.
         */
        drm_atomic_helper_commit_modeset_disables(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);
 
index 4a8a6f1f1151a7a824ce0da479e8cd3cb956e9a6..5df252cebf1cfd80ae39c8be504cd32ecede9c3f 100644 (file)
@@ -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_planes(dev, state, false);
+       drm_atomic_helper_commit_planes(dev, state, 0);
 
        drm_atomic_helper_commit_modeset_enables(dev, state);
 
index 3dd78f2045f9991029aa6e08c4160ceb333d5ad6..e1cfba51cff64d11971a8cb0740e6c56faf7b690 100644 (file)
@@ -96,7 +96,7 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
        dispc_runtime_get();
 
        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);
 
        omap_atomic_wait_for_completion(dev, old_state);
index f03eb55318c1cfb3fc3914fd9184f251f245bd41..bd9c3bb9252c68520af8233412c69253bfd04838 100644 (file)
@@ -257,7 +257,8 @@ static void rcar_du_atomic_complete(struct rcar_du_commit *commit)
        /* Apply the atomic update. */
        drm_atomic_helper_commit_modeset_disables(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);
 
index 55c52734c52d3f63895f1cac04c639df0a41f503..7ca8f347d79f62a025c73f37f3e382c9084d328f 100644 (file)
@@ -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_planes(dev, state, true);
+       drm_atomic_helper_commit_planes(dev, state,
+                                       DRM_PLANE_COMMIT_ACTIVE_ONLY);
 
        drm_atomic_helper_commit_hw_done(state);
 
index f8311b2bc84ee9eb1cab304d4eaee88bae65a702..7cd3804c6deef355ae097661fdc35c320e5ed3d4 100644 (file)
@@ -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_planes(drm, state, false);
+       drm_atomic_helper_commit_planes(drm, state, 0);
        drm_atomic_helper_commit_modeset_enables(drm, state);
 
        drm_atomic_helper_wait_for_vblanks(drm, state);
index 755264d9db229be535a05654250cd69e6876a722..4b9f1c79cd7b01f4ba70e52743f7592d1ce014dd 100644 (file)
@@ -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_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);
 
index 3404d245d28d7ac67ddd2aede6611d5a0ce9d26c..4405e4bc8056844d95644dc209230d02d894154b 100644 (file)
@@ -118,7 +118,7 @@ static int tilcdc_commit(struct drm_device *dev,
 
        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);
 
index 4ac894d993cd80472777b2a3bacc2fcf0dd52810..c1f65c6c8e601e9331768ca040a5609cad686b2e 100644 (file)
@@ -44,7 +44,7 @@ vc4_atomic_complete_commit(struct vc4_commit *c)
 
        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);
 
index 4e192aa2d0216fe15d9f7746e3092886b55e031d..7cf3678623c3a1b0254b88b76d8f8ad95f7a08ce 100644 (file)
@@ -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_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);
 
index 1abf2c0227a68e469911cb7a583f186a3f72207c..f86682825d68844892ea137adf02f72df00490f0 100644 (file)
@@ -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,
                                     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,
                                     struct drm_atomic_state *state,
-                                    bool active_only);
+                                    uint32_t flags);
 void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
                                      struct drm_atomic_state *old_state);
 void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state);