Skip to content

Commit

Permalink
drm/atomic: implement drm_atomic_helper_commit_tail for runtime_pm users
Browse files Browse the repository at this point in the history
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: Maxime Ripard <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/a8f92dc70048bab746e94dadd1c23200626aff60.1500555652.git-series.maxime.ripard@free-electrons.com
Signed-off-by: Daniel Vetter <[email protected]>
  • Loading branch information
mripard authored and danvet committed Jul 26, 2017
1 parent fc2157b commit 81a099a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 61 deletions.
49 changes: 34 additions & 15 deletions drivers/gpu/drm/drm_atomic_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1290,23 +1290,13 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done);
* @old_state: atomic state object with old state structures
*
* 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
* match the legacy modeset helper library closest. One peculiarity of that is
* 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.
* match the legacy modeset helper library closest.
*/
void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
{
Expand All @@ -1326,6 +1316,35 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
}
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)
{
struct drm_device *dev = old_state->dev;
Expand Down
27 changes: 1 addition & 26 deletions drivers/gpu/drm/exynos/exynos_drm_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,33 +187,8 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int 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 = {
.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 = {
Expand Down
21 changes: 1 addition & 20 deletions drivers/gpu/drm/rockchip/rockchip_drm_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,27 +172,8 @@ static void rockchip_drm_output_poll_changed(struct drm_device *dev)
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 = {
.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 = {
Expand Down
1 change: 1 addition & 0 deletions include/drm/drm_atomic_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ int drm_atomic_helper_check_planes(struct drm_device *dev,
int drm_atomic_helper_check(struct drm_device *dev,
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,
struct drm_atomic_state *state,
bool nonblock);
Expand Down

0 comments on commit 81a099a

Please sign in to comment.