Add atomic mode config funcs. The atomic_commit implementation is a
copy-paste from drm_atomic_helper_commit(), leaving out the async
test. The similar copy-paste implementation appears to be used in many
other drivers too. The standard drm_atomic_helper_check() is used for
checking.

Signed-off-by: Jyri Sarha <jsarha at ti.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 47 +++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 709bc90..66a283e 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -20,6 +20,8 @@
 #include <linux/component.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/suspend.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>

 #include "tilcdc_drv.h"
 #include "tilcdc_regs.h"
@@ -59,9 +61,54 @@ static void tilcdc_fb_output_poll_changed(struct drm_device 
*dev)
        drm_fbdev_cma_hotplug_event(priv->fbdev);
 }

+static int tilcdc_commit(struct drm_device *dev,
+                 struct drm_atomic_state *state,
+                 bool async)
+{
+       int ret;
+
+       ret = drm_atomic_helper_prepare_planes(dev, state);
+       if (ret)
+               return ret;
+
+       drm_atomic_helper_swap_state(dev, state);
+
+       /*
+        * Everything below can be run asynchronously without the need to grab
+        * any modeset locks at all under one condition: It must be guaranteed
+        * that the asynchronous work has either been cancelled (if the driver
+        * supports it, which at least requires that the framebuffers get
+        * cleaned up with drm_atomic_helper_cleanup_planes()) or completed
+        * before the new state gets committed on the software side with
+        * drm_atomic_helper_swap_state().
+        *
+        * This scheme allows new atomic state updates to be prepared and
+        * checked in parallel to the asynchronous completion of the previous
+        * update. Which is important since compositors need to figure out the
+        * composition of the next frame right after having submitted the
+        * current layout.
+        */
+
+       drm_atomic_helper_commit_modeset_disables(dev, state);
+
+       drm_atomic_helper_commit_planes(dev, state, false);
+
+       drm_atomic_helper_commit_modeset_enables(dev, state);
+
+       drm_atomic_helper_wait_for_vblanks(dev, state);
+
+       drm_atomic_helper_cleanup_planes(dev, state);
+
+       drm_atomic_state_free(state);
+
+       return 0;
+}
+
 static const struct drm_mode_config_funcs mode_config_funcs = {
        .fb_create = tilcdc_fb_create,
        .output_poll_changed = tilcdc_fb_output_poll_changed,
+       .atomic_check = drm_atomic_helper_check,
+       .atomic_commit = tilcdc_commit,
 };

 static int modeset_init(struct drm_device *dev)
-- 
1.9.1

Reply via email to