Browse Source

drm/exynos: add exynos specific .atomic_commit()

exynos needs to update planes with the crtc enabled (mainly for the FIMD
case) so this specific atomic commit changes the order of
drm_atomic_helper_commit_modeset_enables() and
drm_atomic_helper_commit_planes() to commit planes after we enable crtc
and encoders.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Gustavo Padovan 10 years ago
parent
commit
d6562a291e
1 changed files with 32 additions and 1 deletions
  1. 32 1
      drivers/gpu/drm/exynos/exynos_drm_fb.c

+ 32 - 1
drivers/gpu/drm/exynos/exynos_drm_fb.c

@@ -16,6 +16,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_atomic_helper.h>
 #include <uapi/drm/exynos_drm.h>
 #include <uapi/drm/exynos_drm.h>
 
 
@@ -270,7 +271,37 @@ static int exynos_atomic_commit(struct drm_device *dev,
 				struct drm_atomic_state *state,
 				struct drm_atomic_state *state,
 				bool async)
 				bool async)
 {
 {
-	return drm_atomic_helper_commit(dev, state, false);
+	int ret;
+
+	ret = drm_atomic_helper_prepare_planes(dev, state);
+	if (ret)
+		return ret;
+
+	/* This is the point of no return */
+
+	drm_atomic_helper_swap_state(dev, state);
+
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	/*
+	 * Exynos can't update planes with CRTCs and encoders disabled,
+	 * its updates routines, specially for FIMD, requires the clocks
+	 * to be enabled. So it is necessary to handle the modeset operations
+	 * *before* the commit_planes() step, this way it will always
+	 * have the relevant clocks enabled to perform the update.
+	 */
+
+	drm_atomic_helper_commit_planes(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 exynos_drm_mode_config_funcs = {
 static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {