linux/include/drm/drm_atomic.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014 Red Hat
   3 * Copyright (C) 2014 Intel Corp.
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining a
   6 * copy of this software and associated documentation files (the "Software"),
   7 * to deal in the Software without restriction, including without limitation
   8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9 * and/or sell copies of the Software, and to permit persons to whom the
  10 * Software is furnished to do so, subject to the following conditions:
  11 *
  12 * The above copyright notice and this permission notice shall be included in
  13 * all copies or substantial portions of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21 * OTHER DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors:
  24 * Rob Clark <robdclark@gmail.com>
  25 * Daniel Vetter <daniel.vetter@ffwll.ch>
  26 */
  27
  28#ifndef DRM_ATOMIC_H_
  29#define DRM_ATOMIC_H_
  30
  31#include <drm/drm_crtc.h>
  32
  33/**
  34 * struct drm_crtc_commit - track modeset commits on a CRTC
  35 *
  36 * This structure is used to track pending modeset changes and atomic commit on
  37 * a per-CRTC basis. Since updating the list should never block this structure
  38 * is reference counted to allow waiters to safely wait on an event to complete,
  39 * without holding any locks.
  40 *
  41 * It has 3 different events in total to allow a fine-grained synchronization
  42 * between outstanding updates::
  43 *
  44 *      atomic commit thread                    hardware
  45 *
  46 *      write new state into hardware   ---->   ...
  47 *      signal hw_done
  48 *                                              switch to new state on next
  49 *      ...                                     v/hblank
  50 *
  51 *      wait for buffers to show up             ...
  52 *
  53 *      ...                                     send completion irq
  54 *                                              irq handler signals flip_done
  55 *      cleanup old buffers
  56 *
  57 *      signal cleanup_done
  58 *
  59 *      wait for flip_done              <----
  60 *      clean up atomic state
  61 *
  62 * The important bit to know is that cleanup_done is the terminal event, but the
  63 * ordering between flip_done and hw_done is entirely up to the specific driver
  64 * and modeset state change.
  65 *
  66 * For an implementation of how to use this look at
  67 * drm_atomic_helper_setup_commit() from the atomic helper library.
  68 */
  69struct drm_crtc_commit {
  70        /**
  71         * @crtc:
  72         *
  73         * DRM CRTC for this commit.
  74         */
  75        struct drm_crtc *crtc;
  76
  77        /**
  78         * @ref:
  79         *
  80         * Reference count for this structure. Needed to allow blocking on
  81         * completions without the risk of the completion disappearing
  82         * meanwhile.
  83         */
  84        struct kref ref;
  85
  86        /**
  87         * @flip_done:
  88         *
  89         * Will be signaled when the hardware has flipped to the new set of
  90         * buffers. Signals at the same time as when the drm event for this
  91         * commit is sent to userspace, or when an out-fence is singalled. Note
  92         * that for most hardware, in most cases this happens after @hw_done is
  93         * signalled.
  94         */
  95        struct completion flip_done;
  96
  97        /**
  98         * @hw_done:
  99         *
 100         * Will be signalled when all hw register changes for this commit have
 101         * been written out. Especially when disabling a pipe this can be much
 102         * later than than @flip_done, since that can signal already when the
 103         * screen goes black, whereas to fully shut down a pipe more register
 104         * I/O is required.
 105         *
 106         * Note that this does not need to include separately reference-counted
 107         * resources like backing storage buffer pinning, or runtime pm
 108         * management.
 109         */
 110        struct completion hw_done;
 111
 112        /**
 113         * @cleanup_done:
 114         *
 115         * Will be signalled after old buffers have been cleaned up by calling
 116         * drm_atomic_helper_cleanup_planes(). Since this can only happen after
 117         * a vblank wait completed it might be a bit later. This completion is
 118         * useful to throttle updates and avoid hardware updates getting ahead
 119         * of the buffer cleanup too much.
 120         */
 121        struct completion cleanup_done;
 122
 123        /**
 124         * @commit_entry:
 125         *
 126         * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock.
 127         */
 128        struct list_head commit_entry;
 129
 130        /**
 131         * @event:
 132         *
 133         * &drm_pending_vblank_event pointer to clean up private events.
 134         */
 135        struct drm_pending_vblank_event *event;
 136};
 137
 138struct __drm_planes_state {
 139        struct drm_plane *ptr;
 140        struct drm_plane_state *state;
 141};
 142
 143struct __drm_crtcs_state {
 144        struct drm_crtc *ptr;
 145        struct drm_crtc_state *state;
 146        struct drm_crtc_commit *commit;
 147};
 148
 149struct __drm_connnectors_state {
 150        struct drm_connector *ptr;
 151        struct drm_connector_state *state;
 152};
 153
 154/**
 155 * struct drm_atomic_state - the global state object for atomic updates
 156 * @dev: parent DRM device
 157 * @allow_modeset: allow full modeset
 158 * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
 159 * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL.
 160 * @planes: pointer to array of structures with per-plane data
 161 * @crtcs: pointer to array of CRTC pointers
 162 * @num_connector: size of the @connectors and @connector_states arrays
 163 * @connectors: pointer to array of structures with per-connector data
 164 * @acquire_ctx: acquire context for this atomic modeset state update
 165 */
 166struct drm_atomic_state {
 167        struct drm_device *dev;
 168        bool allow_modeset : 1;
 169        bool legacy_cursor_update : 1;
 170        bool legacy_set_config : 1;
 171        struct __drm_planes_state *planes;
 172        struct __drm_crtcs_state *crtcs;
 173        int num_connector;
 174        struct __drm_connnectors_state *connectors;
 175
 176        struct drm_modeset_acquire_ctx *acquire_ctx;
 177
 178        /**
 179         * @commit_work:
 180         *
 181         * Work item which can be used by the driver or helpers to execute the
 182         * commit without blocking.
 183         */
 184        struct work_struct commit_work;
 185};
 186
 187void drm_crtc_commit_put(struct drm_crtc_commit *commit);
 188static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
 189{
 190        kref_get(&commit->ref);
 191}
 192
 193struct drm_atomic_state * __must_check
 194drm_atomic_state_alloc(struct drm_device *dev);
 195void drm_atomic_state_clear(struct drm_atomic_state *state);
 196void drm_atomic_state_free(struct drm_atomic_state *state);
 197
 198int  __must_check
 199drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state);
 200void drm_atomic_state_default_clear(struct drm_atomic_state *state);
 201void drm_atomic_state_default_release(struct drm_atomic_state *state);
 202
 203struct drm_crtc_state * __must_check
 204drm_atomic_get_crtc_state(struct drm_atomic_state *state,
 205                          struct drm_crtc *crtc);
 206int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
 207                struct drm_crtc_state *state, struct drm_property *property,
 208                uint64_t val);
 209struct drm_plane_state * __must_check
 210drm_atomic_get_plane_state(struct drm_atomic_state *state,
 211                           struct drm_plane *plane);
 212int drm_atomic_plane_set_property(struct drm_plane *plane,
 213                struct drm_plane_state *state, struct drm_property *property,
 214                uint64_t val);
 215struct drm_connector_state * __must_check
 216drm_atomic_get_connector_state(struct drm_atomic_state *state,
 217                               struct drm_connector *connector);
 218int drm_atomic_connector_set_property(struct drm_connector *connector,
 219                struct drm_connector_state *state, struct drm_property *property,
 220                uint64_t val);
 221
 222/**
 223 * drm_atomic_get_existing_crtc_state - get crtc state, if it exists
 224 * @state: global atomic state object
 225 * @crtc: crtc to grab
 226 *
 227 * This function returns the crtc state for the given crtc, or NULL
 228 * if the crtc is not part of the global atomic state.
 229 */
 230static inline struct drm_crtc_state *
 231drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
 232                                   struct drm_crtc *crtc)
 233{
 234        return state->crtcs[drm_crtc_index(crtc)].state;
 235}
 236
 237/**
 238 * drm_atomic_get_existing_plane_state - get plane state, if it exists
 239 * @state: global atomic state object
 240 * @plane: plane to grab
 241 *
 242 * This function returns the plane state for the given plane, or NULL
 243 * if the plane is not part of the global atomic state.
 244 */
 245static inline struct drm_plane_state *
 246drm_atomic_get_existing_plane_state(struct drm_atomic_state *state,
 247                                    struct drm_plane *plane)
 248{
 249        return state->planes[drm_plane_index(plane)].state;
 250}
 251
 252/**
 253 * drm_atomic_get_existing_connector_state - get connector state, if it exists
 254 * @state: global atomic state object
 255 * @connector: connector to grab
 256 *
 257 * This function returns the connector state for the given connector,
 258 * or NULL if the connector is not part of the global atomic state.
 259 */
 260static inline struct drm_connector_state *
 261drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
 262                                        struct drm_connector *connector)
 263{
 264        int index = drm_connector_index(connector);
 265
 266        if (index >= state->num_connector)
 267                return NULL;
 268
 269        return state->connectors[index].state;
 270}
 271
 272/**
 273 * __drm_atomic_get_current_plane_state - get current plane state
 274 * @state: global atomic state object
 275 * @plane: plane to grab
 276 *
 277 * This function returns the plane state for the given plane, either from
 278 * @state, or if the plane isn't part of the atomic state update, from @plane.
 279 * This is useful in atomic check callbacks, when drivers need to peek at, but
 280 * not change, state of other planes, since it avoids threading an error code
 281 * back up the call chain.
 282 *
 283 * WARNING:
 284 *
 285 * Note that this function is in general unsafe since it doesn't check for the
 286 * required locking for access state structures. Drivers must ensure that it is
 287 * safe to access the returned state structure through other means. One common
 288 * example is when planes are fixed to a single CRTC, and the driver knows that
 289 * the CRTC lock is held already. In that case holding the CRTC lock gives a
 290 * read-lock on all planes connected to that CRTC. But if planes can be
 291 * reassigned things get more tricky. In that case it's better to use
 292 * drm_atomic_get_plane_state and wire up full error handling.
 293 *
 294 * Returns:
 295 *
 296 * Read-only pointer to the current plane state.
 297 */
 298static inline const struct drm_plane_state *
 299__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
 300                                     struct drm_plane *plane)
 301{
 302        if (state->planes[drm_plane_index(plane)].state)
 303                return state->planes[drm_plane_index(plane)].state;
 304
 305        return plane->state;
 306}
 307
 308int __must_check
 309drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
 310                             struct drm_display_mode *mode);
 311int __must_check
 312drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
 313                                  struct drm_property_blob *blob);
 314int __must_check
 315drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
 316                              struct drm_crtc *crtc);
 317void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
 318                                 struct drm_framebuffer *fb);
 319int __must_check
 320drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
 321                                  struct drm_crtc *crtc);
 322int __must_check
 323drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
 324                                   struct drm_crtc *crtc);
 325int __must_check
 326drm_atomic_add_affected_planes(struct drm_atomic_state *state,
 327                               struct drm_crtc *crtc);
 328
 329void drm_atomic_legacy_backoff(struct drm_atomic_state *state);
 330
 331void
 332drm_atomic_clean_old_fb(struct drm_device *dev, unsigned plane_mask, int ret);
 333
 334int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
 335int __must_check drm_atomic_commit(struct drm_atomic_state *state);
 336int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 337
 338#define for_each_connector_in_state(__state, connector, connector_state, __i) \
 339        for ((__i) = 0;                                                 \
 340             (__i) < (__state)->num_connector &&                                \
 341             ((connector) = (__state)->connectors[__i].ptr,                     \
 342             (connector_state) = (__state)->connectors[__i].state, 1);  \
 343             (__i)++)                                                   \
 344                for_each_if (connector)
 345
 346#define for_each_crtc_in_state(__state, crtc, crtc_state, __i)  \
 347        for ((__i) = 0;                                         \
 348             (__i) < (__state)->dev->mode_config.num_crtc &&    \
 349             ((crtc) = (__state)->crtcs[__i].ptr,                       \
 350             (crtc_state) = (__state)->crtcs[__i].state, 1);    \
 351             (__i)++)                                           \
 352                for_each_if (crtc_state)
 353
 354#define for_each_plane_in_state(__state, plane, plane_state, __i)               \
 355        for ((__i) = 0;                                                 \
 356             (__i) < (__state)->dev->mode_config.num_total_plane &&     \
 357             ((plane) = (__state)->planes[__i].ptr,                             \
 358             (plane_state) = (__state)->planes[__i].state, 1);          \
 359             (__i)++)                                                   \
 360                for_each_if (plane_state)
 361
 362/**
 363 * drm_atomic_crtc_needs_modeset - compute combined modeset need
 364 * @state: &drm_crtc_state for the CRTC
 365 *
 366 * To give drivers flexibility struct &drm_crtc_state has 3 booleans to track
 367 * whether the state CRTC changed enough to need a full modeset cycle:
 368 * connectors_changed, mode_changed and active_change. This helper simply
 369 * combines these three to compute the overall need for a modeset for @state.
 370 */
 371static inline bool
 372drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state)
 373{
 374        return state->mode_changed || state->active_changed ||
 375               state->connectors_changed;
 376}
 377
 378
 379#endif /* DRM_ATOMIC_H_ */
 380