root/drivers/gpu/drm/drm_atomic_state_helper.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __drm_atomic_helper_crtc_reset
  2. drm_atomic_helper_crtc_reset
  3. __drm_atomic_helper_crtc_duplicate_state
  4. drm_atomic_helper_crtc_duplicate_state
  5. __drm_atomic_helper_crtc_destroy_state
  6. drm_atomic_helper_crtc_destroy_state
  7. __drm_atomic_helper_plane_reset
  8. drm_atomic_helper_plane_reset
  9. __drm_atomic_helper_plane_duplicate_state
  10. drm_atomic_helper_plane_duplicate_state
  11. __drm_atomic_helper_plane_destroy_state
  12. drm_atomic_helper_plane_destroy_state
  13. __drm_atomic_helper_connector_reset
  14. drm_atomic_helper_connector_reset
  15. drm_atomic_helper_connector_tv_reset
  16. __drm_atomic_helper_connector_duplicate_state
  17. drm_atomic_helper_connector_duplicate_state
  18. __drm_atomic_helper_connector_destroy_state
  19. drm_atomic_helper_connector_destroy_state
  20. __drm_atomic_helper_private_obj_duplicate_state

   1 /*
   2  * Copyright (C) 2018 Intel Corp.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors:
  23  * Rob Clark <robdclark@gmail.com>
  24  * Daniel Vetter <daniel.vetter@ffwll.ch>
  25  */
  26 
  27 #include <drm/drm_atomic.h>
  28 #include <drm/drm_atomic_state_helper.h>
  29 #include <drm/drm_connector.h>
  30 #include <drm/drm_crtc.h>
  31 #include <drm/drm_device.h>
  32 #include <drm/drm_plane.h>
  33 #include <drm/drm_print.h>
  34 #include <drm/drm_writeback.h>
  35 
  36 #include <linux/slab.h>
  37 #include <linux/dma-fence.h>
  38 
  39 /**
  40  * DOC: atomic state reset and initialization
  41  *
  42  * Both the drm core and the atomic helpers assume that there is always the full
  43  * and correct atomic software state for all connectors, CRTCs and planes
  44  * available. Which is a bit a problem on driver load and also after system
  45  * suspend. One way to solve this is to have a hardware state read-out
  46  * infrastructure which reconstructs the full software state (e.g. the i915
  47  * driver).
  48  *
  49  * The simpler solution is to just reset the software state to everything off,
  50  * which is easiest to do by calling drm_mode_config_reset(). To facilitate this
  51  * the atomic helpers provide default reset implementations for all hooks.
  52  *
  53  * On the upside the precise state tracking of atomic simplifies system suspend
  54  * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe
  55  * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume().
  56  * For other drivers the building blocks are split out, see the documentation
  57  * for these functions.
  58  */
  59 
  60 /**
  61  * __drm_atomic_helper_crtc_reset - reset state on CRTC
  62  * @crtc: drm CRTC
  63  * @crtc_state: CRTC state to assign
  64  *
  65  * Initializes the newly allocated @crtc_state and assigns it to
  66  * the &drm_crtc->state pointer of @crtc, usually required when
  67  * initializing the drivers or when called from the &drm_crtc_funcs.reset
  68  * hook.
  69  *
  70  * This is useful for drivers that subclass the CRTC state.
  71  */
  72 void
  73 __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
  74                                struct drm_crtc_state *crtc_state)
  75 {
  76         if (crtc_state)
  77                 crtc_state->crtc = crtc;
  78 
  79         crtc->state = crtc_state;
  80 }
  81 EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
  82 
  83 /**
  84  * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
  85  * @crtc: drm CRTC
  86  *
  87  * Resets the atomic state for @crtc by freeing the state pointer (which might
  88  * be NULL, e.g. at driver load time) and allocating a new empty state object.
  89  */
  90 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
  91 {
  92         struct drm_crtc_state *crtc_state =
  93                 kzalloc(sizeof(*crtc->state), GFP_KERNEL);
  94 
  95         if (crtc->state)
  96                 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
  97 
  98         __drm_atomic_helper_crtc_reset(crtc, crtc_state);
  99 }
 100 EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
 101 
 102 /**
 103  * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
 104  * @crtc: CRTC object
 105  * @state: atomic CRTC state
 106  *
 107  * Copies atomic state from a CRTC's current state and resets inferred values.
 108  * This is useful for drivers that subclass the CRTC state.
 109  */
 110 void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
 111                                               struct drm_crtc_state *state)
 112 {
 113         memcpy(state, crtc->state, sizeof(*state));
 114 
 115         if (state->mode_blob)
 116                 drm_property_blob_get(state->mode_blob);
 117         if (state->degamma_lut)
 118                 drm_property_blob_get(state->degamma_lut);
 119         if (state->ctm)
 120                 drm_property_blob_get(state->ctm);
 121         if (state->gamma_lut)
 122                 drm_property_blob_get(state->gamma_lut);
 123         state->mode_changed = false;
 124         state->active_changed = false;
 125         state->planes_changed = false;
 126         state->connectors_changed = false;
 127         state->color_mgmt_changed = false;
 128         state->zpos_changed = false;
 129         state->commit = NULL;
 130         state->event = NULL;
 131         state->async_flip = false;
 132 
 133         /* Self refresh should be canceled when a new update is available */
 134         state->active = drm_atomic_crtc_effectively_active(state);
 135         state->self_refresh_active = false;
 136 }
 137 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
 138 
 139 /**
 140  * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
 141  * @crtc: drm CRTC
 142  *
 143  * Default CRTC state duplicate hook for drivers which don't have their own
 144  * subclassed CRTC state structure.
 145  */
 146 struct drm_crtc_state *
 147 drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
 148 {
 149         struct drm_crtc_state *state;
 150 
 151         if (WARN_ON(!crtc->state))
 152                 return NULL;
 153 
 154         state = kmalloc(sizeof(*state), GFP_KERNEL);
 155         if (state)
 156                 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
 157 
 158         return state;
 159 }
 160 EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
 161 
 162 /**
 163  * __drm_atomic_helper_crtc_destroy_state - release CRTC state
 164  * @state: CRTC state object to release
 165  *
 166  * Releases all resources stored in the CRTC state without actually freeing
 167  * the memory of the CRTC state. This is useful for drivers that subclass the
 168  * CRTC state.
 169  */
 170 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
 171 {
 172         if (state->commit) {
 173                 /*
 174                  * In the event that a non-blocking commit returns
 175                  * -ERESTARTSYS before the commit_tail work is queued, we will
 176                  * have an extra reference to the commit object. Release it, if
 177                  * the event has not been consumed by the worker.
 178                  *
 179                  * state->event may be freed, so we can't directly look at
 180                  * state->event->base.completion.
 181                  */
 182                 if (state->event && state->commit->abort_completion)
 183                         drm_crtc_commit_put(state->commit);
 184 
 185                 kfree(state->commit->event);
 186                 state->commit->event = NULL;
 187 
 188                 drm_crtc_commit_put(state->commit);
 189         }
 190 
 191         drm_property_blob_put(state->mode_blob);
 192         drm_property_blob_put(state->degamma_lut);
 193         drm_property_blob_put(state->ctm);
 194         drm_property_blob_put(state->gamma_lut);
 195 }
 196 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
 197 
 198 /**
 199  * drm_atomic_helper_crtc_destroy_state - default state destroy hook
 200  * @crtc: drm CRTC
 201  * @state: CRTC state object to release
 202  *
 203  * Default CRTC state destroy hook for drivers which don't have their own
 204  * subclassed CRTC state structure.
 205  */
 206 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
 207                                           struct drm_crtc_state *state)
 208 {
 209         __drm_atomic_helper_crtc_destroy_state(state);
 210         kfree(state);
 211 }
 212 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
 213 
 214 /**
 215  * __drm_atomic_helper_plane_reset - resets planes state to default values
 216  * @plane: plane object, must not be NULL
 217  * @state: atomic plane state, must not be NULL
 218  *
 219  * Initializes plane state to default. This is useful for drivers that subclass
 220  * the plane state.
 221  */
 222 void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
 223                                      struct drm_plane_state *state)
 224 {
 225         state->plane = plane;
 226         state->rotation = DRM_MODE_ROTATE_0;
 227 
 228         state->alpha = DRM_BLEND_ALPHA_OPAQUE;
 229         state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
 230 
 231         plane->state = state;
 232 }
 233 EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
 234 
 235 /**
 236  * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes
 237  * @plane: drm plane
 238  *
 239  * Resets the atomic state for @plane by freeing the state pointer (which might
 240  * be NULL, e.g. at driver load time) and allocating a new empty state object.
 241  */
 242 void drm_atomic_helper_plane_reset(struct drm_plane *plane)
 243 {
 244         if (plane->state)
 245                 __drm_atomic_helper_plane_destroy_state(plane->state);
 246 
 247         kfree(plane->state);
 248         plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
 249         if (plane->state)
 250                 __drm_atomic_helper_plane_reset(plane, plane->state);
 251 }
 252 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
 253 
 254 /**
 255  * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
 256  * @plane: plane object
 257  * @state: atomic plane state
 258  *
 259  * Copies atomic state from a plane's current state. This is useful for
 260  * drivers that subclass the plane state.
 261  */
 262 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 263                                                struct drm_plane_state *state)
 264 {
 265         memcpy(state, plane->state, sizeof(*state));
 266 
 267         if (state->fb)
 268                 drm_framebuffer_get(state->fb);
 269 
 270         state->fence = NULL;
 271         state->commit = NULL;
 272         state->fb_damage_clips = NULL;
 273 }
 274 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
 275 
 276 /**
 277  * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
 278  * @plane: drm plane
 279  *
 280  * Default plane state duplicate hook for drivers which don't have their own
 281  * subclassed plane state structure.
 282  */
 283 struct drm_plane_state *
 284 drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
 285 {
 286         struct drm_plane_state *state;
 287 
 288         if (WARN_ON(!plane->state))
 289                 return NULL;
 290 
 291         state = kmalloc(sizeof(*state), GFP_KERNEL);
 292         if (state)
 293                 __drm_atomic_helper_plane_duplicate_state(plane, state);
 294 
 295         return state;
 296 }
 297 EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
 298 
 299 /**
 300  * __drm_atomic_helper_plane_destroy_state - release plane state
 301  * @state: plane state object to release
 302  *
 303  * Releases all resources stored in the plane state without actually freeing
 304  * the memory of the plane state. This is useful for drivers that subclass the
 305  * plane state.
 306  */
 307 void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
 308 {
 309         if (state->fb)
 310                 drm_framebuffer_put(state->fb);
 311 
 312         if (state->fence)
 313                 dma_fence_put(state->fence);
 314 
 315         if (state->commit)
 316                 drm_crtc_commit_put(state->commit);
 317 
 318         drm_property_blob_put(state->fb_damage_clips);
 319 }
 320 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
 321 
 322 /**
 323  * drm_atomic_helper_plane_destroy_state - default state destroy hook
 324  * @plane: drm plane
 325  * @state: plane state object to release
 326  *
 327  * Default plane state destroy hook for drivers which don't have their own
 328  * subclassed plane state structure.
 329  */
 330 void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
 331                                            struct drm_plane_state *state)
 332 {
 333         __drm_atomic_helper_plane_destroy_state(state);
 334         kfree(state);
 335 }
 336 EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
 337 
 338 /**
 339  * __drm_atomic_helper_connector_reset - reset state on connector
 340  * @connector: drm connector
 341  * @conn_state: connector state to assign
 342  *
 343  * Initializes the newly allocated @conn_state and assigns it to
 344  * the &drm_connector->state pointer of @connector, usually required when
 345  * initializing the drivers or when called from the &drm_connector_funcs.reset
 346  * hook.
 347  *
 348  * This is useful for drivers that subclass the connector state.
 349  */
 350 void
 351 __drm_atomic_helper_connector_reset(struct drm_connector *connector,
 352                                     struct drm_connector_state *conn_state)
 353 {
 354         if (conn_state)
 355                 conn_state->connector = connector;
 356 
 357         connector->state = conn_state;
 358 }
 359 EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
 360 
 361 /**
 362  * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors
 363  * @connector: drm connector
 364  *
 365  * Resets the atomic state for @connector by freeing the state pointer (which
 366  * might be NULL, e.g. at driver load time) and allocating a new empty state
 367  * object.
 368  */
 369 void drm_atomic_helper_connector_reset(struct drm_connector *connector)
 370 {
 371         struct drm_connector_state *conn_state =
 372                 kzalloc(sizeof(*conn_state), GFP_KERNEL);
 373 
 374         if (connector->state)
 375                 __drm_atomic_helper_connector_destroy_state(connector->state);
 376 
 377         kfree(connector->state);
 378         __drm_atomic_helper_connector_reset(connector, conn_state);
 379 }
 380 EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
 381 
 382 /**
 383  * drm_atomic_helper_connector_tv_reset - Resets TV connector properties
 384  * @connector: DRM connector
 385  *
 386  * Resets the TV-related properties attached to a connector.
 387  */
 388 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
 389 {
 390         struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
 391         struct drm_connector_state *state = connector->state;
 392 
 393         state->tv.margins.left = cmdline->tv_margins.left;
 394         state->tv.margins.right = cmdline->tv_margins.right;
 395         state->tv.margins.top = cmdline->tv_margins.top;
 396         state->tv.margins.bottom = cmdline->tv_margins.bottom;
 397 }
 398 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 399 
 400 /**
 401  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
 402  * @connector: connector object
 403  * @state: atomic connector state
 404  *
 405  * Copies atomic state from a connector's current state. This is useful for
 406  * drivers that subclass the connector state.
 407  */
 408 void
 409 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
 410                                             struct drm_connector_state *state)
 411 {
 412         memcpy(state, connector->state, sizeof(*state));
 413         if (state->crtc)
 414                 drm_connector_get(connector);
 415         state->commit = NULL;
 416 
 417         if (state->hdr_output_metadata)
 418                 drm_property_blob_get(state->hdr_output_metadata);
 419 
 420         /* Don't copy over a writeback job, they are used only once */
 421         state->writeback_job = NULL;
 422 }
 423 EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
 424 
 425 /**
 426  * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
 427  * @connector: drm connector
 428  *
 429  * Default connector state duplicate hook for drivers which don't have their own
 430  * subclassed connector state structure.
 431  */
 432 struct drm_connector_state *
 433 drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
 434 {
 435         struct drm_connector_state *state;
 436 
 437         if (WARN_ON(!connector->state))
 438                 return NULL;
 439 
 440         state = kmalloc(sizeof(*state), GFP_KERNEL);
 441         if (state)
 442                 __drm_atomic_helper_connector_duplicate_state(connector, state);
 443 
 444         return state;
 445 }
 446 EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
 447 
 448 /**
 449  * __drm_atomic_helper_connector_destroy_state - release connector state
 450  * @state: connector state object to release
 451  *
 452  * Releases all resources stored in the connector state without actually
 453  * freeing the memory of the connector state. This is useful for drivers that
 454  * subclass the connector state.
 455  */
 456 void
 457 __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
 458 {
 459         if (state->crtc)
 460                 drm_connector_put(state->connector);
 461 
 462         if (state->commit)
 463                 drm_crtc_commit_put(state->commit);
 464 
 465         if (state->writeback_job)
 466                 drm_writeback_cleanup_job(state->writeback_job);
 467 
 468         drm_property_blob_put(state->hdr_output_metadata);
 469 }
 470 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
 471 
 472 /**
 473  * drm_atomic_helper_connector_destroy_state - default state destroy hook
 474  * @connector: drm connector
 475  * @state: connector state object to release
 476  *
 477  * Default connector state destroy hook for drivers which don't have their own
 478  * subclassed connector state structure.
 479  */
 480 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
 481                                           struct drm_connector_state *state)
 482 {
 483         __drm_atomic_helper_connector_destroy_state(state);
 484         kfree(state);
 485 }
 486 EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
 487 
 488 /**
 489  * __drm_atomic_helper_private_duplicate_state - copy atomic private state
 490  * @obj: CRTC object
 491  * @state: new private object state
 492  *
 493  * Copies atomic state from a private objects's current state and resets inferred values.
 494  * This is useful for drivers that subclass the private state.
 495  */
 496 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
 497                                                      struct drm_private_state *state)
 498 {
 499         memcpy(state, obj->state, sizeof(*state));
 500 }
 501 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);

/* [<][>][^][v][top][bottom][index][help] */