drm/modeset-helper: Add simple modeset suspend/resume helpers

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
This commit is contained in:
Noralf Trønnes 2017-11-06 20:18:08 +01:00
parent b66d0f3486
commit ca038cfb5c
3 changed files with 88 additions and 0 deletions

View 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);

View 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;
};

View 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