]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/modeset-helper: Add simple modeset suspend/resume helpers
authorNoralf Trønnes <noralf@tronnes.org>
Mon, 6 Nov 2017 19:18:08 +0000 (20:18 +0100)
committerNoralf Trønnes <noralf@tronnes.org>
Thu, 30 Nov 2017 17:18:08 +0000 (18:18 +0100)
Add drm_mode_config_helper_suspend/resume() which takes care of
atomic modeset suspend/resume for simple use cases.
The suspend state is stored in struct drm_mode_config.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20171106191812.38927-3-noralf@tronnes.org
drivers/gpu/drm/drm_modeset_helper.c
include/drm/drm_mode_config.h
include/drm/drm_modeset_helper.h

index 9cb1eede0b4d9444a40e9b575b0e0184f4d2c9a5..f1c24ab0ef09f6ca4c45d08c6c4552f11126516b 100644 (file)
@@ -20,6 +20,9 @@
  * OF THIS SOFTWARE.
  */
 
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
 #include <drm/drm_modeset_helper.h>
 #include <drm/drm_plane_helper.h>
 
@@ -156,3 +159,76 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
                                         NULL);
 }
 EXPORT_SYMBOL(drm_crtc_init);
+
+/**
+ * drm_mode_config_helper_suspend - Modeset suspend helper
+ * @dev: DRM device
+ *
+ * This helper function takes care of suspending the modeset side. It disables
+ * output polling if initialized, suspends fbdev if used and finally calls
+ * drm_atomic_helper_suspend().
+ * If suspending fails, fbdev and polling is re-enabled.
+ *
+ * Returns:
+ * Zero on success, negative error code on error.
+ *
+ * See also:
+ * drm_kms_helper_poll_disable() and drm_fb_helper_set_suspend_unlocked().
+ */
+int drm_mode_config_helper_suspend(struct drm_device *dev)
+{
+       struct drm_atomic_state *state;
+
+       if (!dev)
+               return 0;
+
+       drm_kms_helper_poll_disable(dev);
+       drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1);
+       state = drm_atomic_helper_suspend(dev);
+       if (IS_ERR(state)) {
+               drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
+               drm_kms_helper_poll_enable(dev);
+               return PTR_ERR(state);
+       }
+
+       dev->mode_config.suspend_state = state;
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_mode_config_helper_suspend);
+
+/**
+ * drm_mode_config_helper_resume - Modeset resume helper
+ * @dev: DRM device
+ *
+ * This helper function takes care of resuming the modeset side. It calls
+ * drm_atomic_helper_resume(), resumes fbdev if used and enables output polling
+ * if initiaized.
+ *
+ * Returns:
+ * Zero on success, negative error code on error.
+ *
+ * See also:
+ * drm_fb_helper_set_suspend_unlocked() and drm_kms_helper_poll_enable().
+ */
+int drm_mode_config_helper_resume(struct drm_device *dev)
+{
+       int ret;
+
+       if (!dev)
+               return 0;
+
+       if (WARN_ON(!dev->mode_config.suspend_state))
+               return -EINVAL;
+
+       ret = drm_atomic_helper_resume(dev, dev->mode_config.suspend_state);
+       if (ret)
+               DRM_ERROR("Failed to resume (%d)\n", ret);
+       dev->mode_config.suspend_state = NULL;
+
+       drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
+       drm_kms_helper_poll_enable(dev);
+
+       return ret;
+}
+EXPORT_SYMBOL(drm_mode_config_helper_resume);
index cf73c5eaab9808790b9bf432b5c762579a99d46e..eb3b8dba3e2c7a632684087cf383747bd7f08976 100644 (file)
@@ -753,6 +753,15 @@ struct drm_mode_config {
        /* cursor size */
        uint32_t cursor_width, cursor_height;
 
+       /**
+        * @suspend_state:
+        *
+        * Atomic state when suspended.
+        * Set by drm_mode_config_helper_suspend() and cleared by
+        * drm_mode_config_helper_resume().
+        */
+       struct drm_atomic_state *suspend_state;
+
        const struct drm_mode_config_helper_funcs *helper_private;
 };
 
index cb0ec92e11e60fbdfb942761ccb7dc2063f1dc73..efa337f031299166c7ce37d7e82b4ec854adfb2b 100644 (file)
@@ -34,4 +34,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_device *dev,
 int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
                  const struct drm_crtc_funcs *funcs);
 
+int drm_mode_config_helper_suspend(struct drm_device *dev);
+int drm_mode_config_helper_resume(struct drm_device *dev);
+
 #endif