diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-11-05 02:14:14 +0300 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-11-05 20:07:01 +0300 |
commit | c2fcd274bce521cd824d96d7f26dfa57ea06478c (patch) | |
tree | 941d2b637ae159ffccef24e5af426ae9b0e246f0 /include/drm | |
parent | cc4ceb484b37b9369e0d4e8682b7ae1849ae4579 (diff) | |
download | linux-c2fcd274bce521cd824d96d7f26dfa57ea06478c.tar.xz |
drm: Add atomic/plane helpers
This is the first cut of atomic helper code. As-is it's only useful to
implement a pure atomic interface for plane updates.
Later patches will integrate this with the crtc helpers so that full
atomic updates are possible. We also need a pile of helpers to aid
drivers in transitioning from the legacy world to the shiny new atomic
age. Finally we need helpers to implement legacy ioctls on top of the
atomic interface.
The design of the overall helpers<->driver interaction is fairly
simple, but has an unfortunate large interface:
- We have ->atomic_check callbacks for crtcs and planes. The idea is
that connectors don't need any checking, and if they do they can
adjust the relevant crtc driver-private state. So no connector hooks
should be needed. Also the crtc helpers integration will do the
->best_encoder checks, so no need for that.
- Framebuffer pinning needs to be done before we can commit to the hw
state. This is especially important for async updates where we must
pin all buffers before returning to userspace, so that really only
hw failures can happen in the asynchronous worker.
Hence we add ->prepare_fb and ->cleanup_fb hooks for this resources
management.
- The actual atomic plane commit can't fail (except hw woes), so has
void return type. It has three stages:
1. Prepare all affected crtcs with crtc->atomic_begin. Drivers can
use this to unset the GO bit or similar latches to prevent plane
updates.
2. Update plane state by looping over all changed planes and calling
plane->atomic_update. Presuming the hardware is sane and has GO
bits drivers can simply bash the state into the hardware in this
function. Other drivers might use this to precompute hw state for
the final step.
3. Finally latch the update for the next vblank with
crtc->atomic_flush. Note that this function doesn't need to wait
for the vblank to happen even for the synchronous case.
v2: Clear drm_<obj>_state->state to NULL when swapping in state.
v3: Add TODO that we don't short-circuit plane updates for now. Likely
no one will care.
v4: Squash in a bit of polish that somehow landed in the wrong (later)
patche.
v5: Integrate atomic functions into the drm docbook and fixup the
kerneldoc.
v6: Fixup fixup patch squashing fumble.
v7: Don't touch the legacy plane state plane->fb and plane->crtc. This
is only used by the legacy ioctl code in the drm core, and that code
already takes care of updating the pointers in all relevant cases.
This is in stark contrast to connector->encoder->crtc links on the
modeset side, which we still need to set since the core doesn't touch
them.
Also some more kerneldoc polish.
v8: Drop outdated comment.
v9: Handle the state->state pointer correctly: Only clearing the
->state pointer when assigning the state to the kms object isn't good
enough. We also need to re-link the swapped out state into the
drm_atomic_state structure.
v10: Shuffle the misplaced docbook template hunk around that Sean spotted.
Cc: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'include/drm')
-rw-r--r-- | include/drm/drm_atomic_helper.h | 44 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 6 | ||||
-rw-r--r-- | include/drm/drm_crtc_helper.h | 6 | ||||
-rw-r--r-- | include/drm/drm_plane_helper.h | 22 |
4 files changed, 78 insertions, 0 deletions
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h new file mode 100644 index 000000000000..79938c62e7ad --- /dev/null +++ b/include/drm/drm_atomic_helper.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 Red Hat + * Copyright (C) 2014 Intel Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Rob Clark <robdclark@gmail.com> + * Daniel Vetter <daniel.vetter@ffwll.ch> + */ + +#ifndef DRM_ATOMIC_HELPER_H_ +#define DRM_ATOMIC_HELPER_H_ + +int drm_atomic_helper_check(struct drm_device *dev, + struct drm_atomic_state *state); + +int drm_atomic_helper_prepare_planes(struct drm_device *dev, + struct drm_atomic_state *state); +void drm_atomic_helper_commit_planes(struct drm_device *dev, + struct drm_atomic_state *state); +void drm_atomic_helper_cleanup_planes(struct drm_device *dev, + struct drm_atomic_state *old_state); + +void drm_atomic_helper_swap_state(struct drm_device *dev, + struct drm_atomic_state *state); + +#endif /* DRM_ATOMIC_HELPER_H_ */ diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c7a3400173a8..56147409408d 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -229,6 +229,7 @@ struct drm_atomic_state; /** * struct drm_crtc_state - mutable CRTC state * @enable: whether the CRTC should be enabled, gates all other state + * @planes_changed: for use by helpers and drivers when computing state updates * @mode: current mode timings * @event: optional pointer to a DRM event to signal upon completion of the * state update @@ -237,6 +238,9 @@ struct drm_atomic_state; struct drm_crtc_state { bool enable; + /* computed state bits used by helpers and drivers */ + bool planes_changed : 1; + struct drm_display_mode mode; struct drm_pending_vblank_event *event; @@ -747,6 +751,8 @@ struct drm_plane { enum drm_plane_type type; + void *helper_private; + struct drm_plane_state *state; }; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index a3d75fefd010..adec48b27aa5 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -81,6 +81,12 @@ struct drm_crtc_helper_funcs { /* disable crtc when not in use - more explicit than dpms off */ void (*disable)(struct drm_crtc *crtc); + + /* atomic helpers */ + int (*atomic_check)(struct drm_crtc *crtc, + struct drm_crtc_state *state); + void (*atomic_begin)(struct drm_crtc *crtc); + void (*atomic_flush)(struct drm_crtc *crtc); }; /** diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index fa60d19f91c0..8577ec8f3e6c 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -47,6 +47,28 @@ extern int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, const struct drm_crtc_funcs *funcs); +/** + * drm_plane_helper_funcs - helper operations for CRTCs + * + * The helper operations are called by the mid-layer CRTC helper. + */ +struct drm_plane_helper_funcs { + int (*prepare_fb)(struct drm_plane *plane, + struct drm_framebuffer *fb); + void (*cleanup_fb)(struct drm_plane *plane, + struct drm_framebuffer *fb); + + int (*atomic_check)(struct drm_plane *plane, + struct drm_plane_state *state); + void (*atomic_update)(struct drm_plane *plane); +}; + +static inline void drm_plane_helper_add(struct drm_plane *plane, + const struct drm_plane_helper_funcs *funcs) +{ + plane->helper_private = (void *)funcs; +} + extern int drm_plane_helper_check_update(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, |