Commit 81a099ac authored by Maxime Ripard's avatar Maxime Ripard Committed by Daniel Vetter

drm/atomic: implement drm_atomic_helper_commit_tail for runtime_pm users

The current drm_atomic_helper_commit_tail helper works only if the CRTC is
accessible, and documents an alternative implementation that is supposed to
be used if that happens.

That implementation is then duplicated by some drivers. Instead of
documenting it, let's implement an helper that all the relevant users can
use directly.
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/a8f92dc70048bab746e94dadd1c23200626aff60.1500555652.git-series.maxime.ripard@free-electrons.comSigned-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent fc2157b6
...@@ -1290,23 +1290,13 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done); ...@@ -1290,23 +1290,13 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done);
* @old_state: atomic state object with old state structures * @old_state: atomic state object with old state structures
* *
* This is the default implementation for the * This is the default implementation for the
* &drm_mode_config_helper_funcs.atomic_commit_tail hook. * &drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers
* that do not support runtime_pm or do not need the CRTC to be
* enabled to perform a commit. Otherwise, see
* drm_atomic_helper_commit_tail_rpm().
* *
* Note that the default ordering of how the various stages are called is to * Note that the default ordering of how the various stages are called is to
* match the legacy modeset helper library closest. One peculiarity of that is * match the legacy modeset helper library closest.
* that it doesn't mesh well with runtime PM at all.
*
* For drivers supporting runtime PM the recommended sequence is instead ::
*
* 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,
* DRM_PLANE_COMMIT_ACTIVE_ONLY);
*
* for committing the atomic update to hardware. See the kerneldoc entries for
* these three functions for more details.
*/ */
void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state) void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
{ {
...@@ -1326,6 +1316,35 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state) ...@@ -1326,6 +1316,35 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
} }
EXPORT_SYMBOL(drm_atomic_helper_commit_tail); EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
/**
* drm_atomic_helper_commit_tail_rpm - commit atomic update to hardware
* @old_state: new modeset state to be committed
*
* This is an alternative implementation for the
* &drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers
* that support runtime_pm or need the CRTC to be enabled to perform a
* commit. Otherwise, one should use the default implementation
* drm_atomic_helper_commit_tail().
*/
void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
{
struct drm_device *dev = old_state->dev;
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,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_commit_hw_done(old_state);
drm_atomic_helper_wait_for_vblanks(dev, old_state);
drm_atomic_helper_cleanup_planes(dev, old_state);
}
EXPORT_SYMBOL(drm_atomic_helper_commit_tail_rpm);
static void commit_tail(struct drm_atomic_state *old_state) static void commit_tail(struct drm_atomic_state *old_state)
{ {
struct drm_device *dev = old_state->dev; struct drm_device *dev = old_state->dev;
......
...@@ -187,33 +187,8 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index) ...@@ -187,33 +187,8 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
return exynos_fb->dma_addr[index]; return exynos_fb->dma_addr[index];
} }
static void exynos_drm_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
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_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_commit_hw_done(state);
drm_atomic_helper_wait_for_vblanks(dev, state);
drm_atomic_helper_cleanup_planes(dev, state);
}
static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = { static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
.atomic_commit_tail = exynos_drm_atomic_commit_tail, .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
}; };
static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
......
...@@ -172,27 +172,8 @@ static void rockchip_drm_output_poll_changed(struct drm_device *dev) ...@@ -172,27 +172,8 @@ static void rockchip_drm_output_poll_changed(struct drm_device *dev)
drm_fb_helper_hotplug_event(&private->fbdev_helper); drm_fb_helper_hotplug_event(&private->fbdev_helper);
} }
static void
rockchip_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
drm_atomic_helper_commit_modeset_disables(dev, state);
drm_atomic_helper_commit_modeset_enables(dev, state);
drm_atomic_helper_commit_planes(dev, state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
drm_atomic_helper_commit_hw_done(state);
drm_atomic_helper_wait_for_vblanks(dev, state);
drm_atomic_helper_cleanup_planes(dev, state);
}
static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = { static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
.atomic_commit_tail = rockchip_atomic_commit_tail, .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
}; };
static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = { static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
......
...@@ -43,6 +43,7 @@ int drm_atomic_helper_check_planes(struct drm_device *dev, ...@@ -43,6 +43,7 @@ int drm_atomic_helper_check_planes(struct drm_device *dev,
int drm_atomic_helper_check(struct drm_device *dev, int drm_atomic_helper_check(struct drm_device *dev,
struct drm_atomic_state *state); struct drm_atomic_state *state);
void drm_atomic_helper_commit_tail(struct drm_atomic_state *state); void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *state);
int drm_atomic_helper_commit(struct drm_device *dev, int drm_atomic_helper_commit(struct drm_device *dev,
struct drm_atomic_state *state, struct drm_atomic_state *state,
bool nonblock); bool nonblock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment