LCOV - code coverage report
Current view: top level - dev/pci/drm - drm_atomic.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 634 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 36 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      29             : #include <dev/pci/drm/drmP.h>
      30             : #include <dev/pci/drm/drm_atomic.h>
      31             : #include <dev/pci/drm/drm_plane_helper.h>
      32             : 
      33             : /**
      34             :  * drm_atomic_state_default_release -
      35             :  * release memory initialized by drm_atomic_state_init
      36             :  * @state: atomic state
      37             :  *
      38             :  * Free all the memory allocated by drm_atomic_state_init.
      39             :  * This is useful for drivers that subclass the atomic state.
      40             :  */
      41           0 : void drm_atomic_state_default_release(struct drm_atomic_state *state)
      42             : {
      43           0 :         kfree(state->connectors);
      44           0 :         kfree(state->connector_states);
      45           0 :         kfree(state->crtcs);
      46           0 :         kfree(state->crtc_states);
      47           0 :         kfree(state->planes);
      48           0 :         kfree(state->plane_states);
      49           0 : }
      50             : EXPORT_SYMBOL(drm_atomic_state_default_release);
      51             : 
      52             : /**
      53             :  * drm_atomic_state_init - init new atomic state
      54             :  * @dev: DRM device
      55             :  * @state: atomic state
      56             :  *
      57             :  * Default implementation for filling in a new atomic state.
      58             :  * This is useful for drivers that subclass the atomic state.
      59             :  */
      60             : int
      61           0 : drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
      62             : {
      63             :         /* TODO legacy paths should maybe do a better job about
      64             :          * setting this appropriately?
      65             :          */
      66           0 :         state->allow_modeset = true;
      67             : 
      68           0 :         state->num_connector = ACCESS_ONCE(dev->mode_config.num_connector);
      69             : 
      70           0 :         state->crtcs = kcalloc(dev->mode_config.num_crtc,
      71             :                                sizeof(*state->crtcs), GFP_KERNEL);
      72           0 :         if (!state->crtcs)
      73             :                 goto fail;
      74           0 :         state->crtc_states = kcalloc(dev->mode_config.num_crtc,
      75             :                                      sizeof(*state->crtc_states), GFP_KERNEL);
      76           0 :         if (!state->crtc_states)
      77             :                 goto fail;
      78           0 :         state->planes = kcalloc(dev->mode_config.num_total_plane,
      79             :                                 sizeof(*state->planes), GFP_KERNEL);
      80           0 :         if (!state->planes)
      81             :                 goto fail;
      82           0 :         state->plane_states = kcalloc(dev->mode_config.num_total_plane,
      83             :                                       sizeof(*state->plane_states), GFP_KERNEL);
      84           0 :         if (!state->plane_states)
      85             :                 goto fail;
      86           0 :         state->connectors = kcalloc(state->num_connector,
      87             :                                     sizeof(*state->connectors),
      88             :                                     GFP_KERNEL);
      89           0 :         if (!state->connectors)
      90             :                 goto fail;
      91           0 :         state->connector_states = kcalloc(state->num_connector,
      92             :                                           sizeof(*state->connector_states),
      93             :                                           GFP_KERNEL);
      94           0 :         if (!state->connector_states)
      95             :                 goto fail;
      96             : 
      97           0 :         state->dev = dev;
      98             : 
      99             :         DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
     100             : 
     101           0 :         return 0;
     102             : fail:
     103           0 :         drm_atomic_state_default_release(state);
     104           0 :         return -ENOMEM;
     105           0 : }
     106             : EXPORT_SYMBOL(drm_atomic_state_init);
     107             : 
     108             : /**
     109             :  * drm_atomic_state_alloc - allocate atomic state
     110             :  * @dev: DRM device
     111             :  *
     112             :  * This allocates an empty atomic state to track updates.
     113             :  */
     114             : struct drm_atomic_state *
     115           0 : drm_atomic_state_alloc(struct drm_device *dev)
     116             : {
     117           0 :         struct drm_mode_config *config = &dev->mode_config;
     118             :         struct drm_atomic_state *state;
     119             : 
     120           0 :         if (!config->funcs->atomic_state_alloc) {
     121           0 :                 state = kzalloc(sizeof(*state), GFP_KERNEL);
     122           0 :                 if (!state)
     123           0 :                         return NULL;
     124           0 :                 if (drm_atomic_state_init(dev, state) < 0) {
     125           0 :                         kfree(state);
     126           0 :                         return NULL;
     127             :                 }
     128           0 :                 return state;
     129             :         }
     130             : 
     131           0 :         return config->funcs->atomic_state_alloc(dev);
     132           0 : }
     133             : EXPORT_SYMBOL(drm_atomic_state_alloc);
     134             : 
     135             : /**
     136             :  * drm_atomic_state_default_clear - clear base atomic state
     137             :  * @state: atomic state
     138             :  *
     139             :  * Default implementation for clearing atomic state.
     140             :  * This is useful for drivers that subclass the atomic state.
     141             :  */
     142           0 : void drm_atomic_state_default_clear(struct drm_atomic_state *state)
     143             : {
     144           0 :         struct drm_device *dev = state->dev;
     145           0 :         struct drm_mode_config *config = &dev->mode_config;
     146             :         int i;
     147             : 
     148             :         DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
     149             : 
     150           0 :         for (i = 0; i < state->num_connector; i++) {
     151           0 :                 struct drm_connector *connector = state->connectors[i];
     152             : 
     153           0 :                 if (!connector || !connector->funcs)
     154           0 :                         continue;
     155             : 
     156             :                 /*
     157             :                  * FIXME: Async commits can race with connector unplugging and
     158             :                  * there's currently nothing that prevents cleanup up state for
     159             :                  * deleted connectors. As long as the callback doesn't look at
     160             :                  * the connector we'll be fine though, so make sure that's the
     161             :                  * case by setting all connector pointers to NULL.
     162             :                  */
     163           0 :                 state->connector_states[i]->connector = NULL;
     164           0 :                 connector->funcs->atomic_destroy_state(NULL,
     165           0 :                                                        state->connector_states[i]);
     166           0 :                 state->connectors[i] = NULL;
     167           0 :                 state->connector_states[i] = NULL;
     168           0 :         }
     169             : 
     170           0 :         for (i = 0; i < config->num_crtc; i++) {
     171           0 :                 struct drm_crtc *crtc = state->crtcs[i];
     172             : 
     173           0 :                 if (!crtc)
     174           0 :                         continue;
     175             : 
     176           0 :                 crtc->funcs->atomic_destroy_state(crtc,
     177           0 :                                                   state->crtc_states[i]);
     178           0 :                 state->crtcs[i] = NULL;
     179           0 :                 state->crtc_states[i] = NULL;
     180           0 :         }
     181             : 
     182           0 :         for (i = 0; i < config->num_total_plane; i++) {
     183           0 :                 struct drm_plane *plane = state->planes[i];
     184             : 
     185           0 :                 if (!plane)
     186           0 :                         continue;
     187             : 
     188           0 :                 plane->funcs->atomic_destroy_state(plane,
     189           0 :                                                    state->plane_states[i]);
     190           0 :                 state->planes[i] = NULL;
     191           0 :                 state->plane_states[i] = NULL;
     192           0 :         }
     193           0 : }
     194             : EXPORT_SYMBOL(drm_atomic_state_default_clear);
     195             : 
     196             : /**
     197             :  * drm_atomic_state_clear - clear state object
     198             :  * @state: atomic state
     199             :  *
     200             :  * When the w/w mutex algorithm detects a deadlock we need to back off and drop
     201             :  * all locks. So someone else could sneak in and change the current modeset
     202             :  * configuration. Which means that all the state assembled in @state is no
     203             :  * longer an atomic update to the current state, but to some arbitrary earlier
     204             :  * state. Which could break assumptions the driver's ->atomic_check likely
     205             :  * relies on.
     206             :  *
     207             :  * Hence we must clear all cached state and completely start over, using this
     208             :  * function.
     209             :  */
     210           0 : void drm_atomic_state_clear(struct drm_atomic_state *state)
     211             : {
     212           0 :         struct drm_device *dev = state->dev;
     213           0 :         struct drm_mode_config *config = &dev->mode_config;
     214             : 
     215           0 :         if (config->funcs->atomic_state_clear)
     216           0 :                 config->funcs->atomic_state_clear(state);
     217             :         else
     218           0 :                 drm_atomic_state_default_clear(state);
     219           0 : }
     220             : EXPORT_SYMBOL(drm_atomic_state_clear);
     221             : 
     222             : /**
     223             :  * drm_atomic_state_free - free all memory for an atomic state
     224             :  * @state: atomic state to deallocate
     225             :  *
     226             :  * This frees all memory associated with an atomic state, including all the
     227             :  * per-object state for planes, crtcs and connectors.
     228             :  */
     229           0 : void drm_atomic_state_free(struct drm_atomic_state *state)
     230             : {
     231             :         struct drm_device *dev;
     232             :         struct drm_mode_config *config;
     233             : 
     234           0 :         if (!state)
     235           0 :                 return;
     236             : 
     237           0 :         dev = state->dev;
     238           0 :         config = &dev->mode_config;
     239             : 
     240           0 :         drm_atomic_state_clear(state);
     241             : 
     242             :         DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
     243             : 
     244           0 :         if (config->funcs->atomic_state_free) {
     245           0 :                 config->funcs->atomic_state_free(state);
     246           0 :         } else {
     247           0 :                 drm_atomic_state_default_release(state);
     248           0 :                 kfree(state);
     249             :         }
     250           0 : }
     251             : EXPORT_SYMBOL(drm_atomic_state_free);
     252             : 
     253             : /**
     254             :  * drm_atomic_get_crtc_state - get crtc state
     255             :  * @state: global atomic state object
     256             :  * @crtc: crtc to get state object for
     257             :  *
     258             :  * This function returns the crtc state for the given crtc, allocating it if
     259             :  * needed. It will also grab the relevant crtc lock to make sure that the state
     260             :  * is consistent.
     261             :  *
     262             :  * Returns:
     263             :  *
     264             :  * Either the allocated state or the error code encoded into the pointer. When
     265             :  * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
     266             :  * entire atomic sequence must be restarted. All other errors are fatal.
     267             :  */
     268             : struct drm_crtc_state *
     269           0 : drm_atomic_get_crtc_state(struct drm_atomic_state *state,
     270             :                           struct drm_crtc *crtc)
     271             : {
     272           0 :         int ret, index = drm_crtc_index(crtc);
     273             :         struct drm_crtc_state *crtc_state;
     274             : 
     275           0 :         crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
     276           0 :         if (crtc_state)
     277           0 :                 return crtc_state;
     278             : 
     279           0 :         ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
     280           0 :         if (ret)
     281           0 :                 return ERR_PTR(ret);
     282             : 
     283           0 :         crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
     284           0 :         if (!crtc_state)
     285           0 :                 return ERR_PTR(-ENOMEM);
     286             : 
     287           0 :         state->crtc_states[index] = crtc_state;
     288           0 :         state->crtcs[index] = crtc;
     289           0 :         crtc_state->state = state;
     290             : 
     291             :         DRM_DEBUG_ATOMIC("Added [CRTC:%d] %p state to %p\n",
     292             :                          crtc->base.id, crtc_state, state);
     293             : 
     294           0 :         return crtc_state;
     295           0 : }
     296             : EXPORT_SYMBOL(drm_atomic_get_crtc_state);
     297             : 
     298             : /**
     299             :  * drm_atomic_set_mode_for_crtc - set mode for CRTC
     300             :  * @state: the CRTC whose incoming state to update
     301             :  * @mode: kernel-internal mode to use for the CRTC, or NULL to disable
     302             :  *
     303             :  * Set a mode (originating from the kernel) on the desired CRTC state. Does
     304             :  * not change any other state properties, including enable, active, or
     305             :  * mode_changed.
     306             :  *
     307             :  * RETURNS:
     308             :  * Zero on success, error code on failure. Cannot return -EDEADLK.
     309             :  */
     310           0 : int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
     311             :                                  struct drm_display_mode *mode)
     312             : {
     313           0 :         struct drm_mode_modeinfo umode;
     314             : 
     315             :         /* Early return for no change. */
     316           0 :         if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0)
     317           0 :                 return 0;
     318             : 
     319           0 :         if (state->mode_blob)
     320           0 :                 drm_property_unreference_blob(state->mode_blob);
     321           0 :         state->mode_blob = NULL;
     322             : 
     323           0 :         if (mode) {
     324           0 :                 drm_mode_convert_to_umode(&umode, mode);
     325           0 :                 state->mode_blob =
     326           0 :                         drm_property_create_blob(state->crtc->dev,
     327             :                                                  sizeof(umode),
     328             :                                                  &umode);
     329           0 :                 if (IS_ERR(state->mode_blob))
     330           0 :                         return PTR_ERR(state->mode_blob);
     331             : 
     332           0 :                 drm_mode_copy(&state->mode, mode);
     333           0 :                 state->enable = true;
     334             :                 DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
     335             :                                  mode->name, state);
     336           0 :         } else {
     337           0 :                 memset(&state->mode, 0, sizeof(state->mode));
     338           0 :                 state->enable = false;
     339             :                 DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
     340             :                                  state);
     341             :         }
     342             : 
     343           0 :         return 0;
     344           0 : }
     345             : EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc);
     346             : 
     347             : /**
     348             :  * drm_atomic_set_mode_prop_for_crtc - set mode for CRTC
     349             :  * @state: the CRTC whose incoming state to update
     350             :  * @blob: pointer to blob property to use for mode
     351             :  *
     352             :  * Set a mode (originating from a blob property) on the desired CRTC state.
     353             :  * This function will take a reference on the blob property for the CRTC state,
     354             :  * and release the reference held on the state's existing mode property, if any
     355             :  * was set.
     356             :  *
     357             :  * RETURNS:
     358             :  * Zero on success, error code on failure. Cannot return -EDEADLK.
     359             :  */
     360           0 : int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
     361             :                                       struct drm_property_blob *blob)
     362             : {
     363           0 :         if (blob == state->mode_blob)
     364           0 :                 return 0;
     365             : 
     366           0 :         if (state->mode_blob)
     367           0 :                 drm_property_unreference_blob(state->mode_blob);
     368           0 :         state->mode_blob = NULL;
     369             : 
     370           0 :         memset(&state->mode, 0, sizeof(state->mode));
     371             : 
     372           0 :         if (blob) {
     373           0 :                 if (blob->length != sizeof(struct drm_mode_modeinfo) ||
     374           0 :                     drm_mode_convert_umode(&state->mode,
     375           0 :                                            (const struct drm_mode_modeinfo *)
     376           0 :                                             blob->data))
     377           0 :                         return -EINVAL;
     378             : 
     379           0 :                 state->mode_blob = drm_property_reference_blob(blob);
     380           0 :                 state->enable = true;
     381             :                 DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
     382             :                                  state->mode.name, state);
     383           0 :         } else {
     384           0 :                 state->enable = false;
     385             :                 DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
     386             :                                  state);
     387             :         }
     388             : 
     389           0 :         return 0;
     390           0 : }
     391             : EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
     392             : 
     393             : /**
     394             :  * drm_atomic_crtc_set_property - set property on CRTC
     395             :  * @crtc: the drm CRTC to set a property on
     396             :  * @state: the state object to update with the new property value
     397             :  * @property: the property to set
     398             :  * @val: the new property value
     399             :  *
     400             :  * Use this instead of calling crtc->atomic_set_property directly.
     401             :  * This function handles generic/core properties and calls out to
     402             :  * driver's ->atomic_set_property() for driver properties.  To ensure
     403             :  * consistent behavior you must call this function rather than the
     404             :  * driver hook directly.
     405             :  *
     406             :  * RETURNS:
     407             :  * Zero on success, error code on failure
     408             :  */
     409           0 : int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
     410             :                 struct drm_crtc_state *state, struct drm_property *property,
     411             :                 uint64_t val)
     412             : {
     413           0 :         struct drm_device *dev = crtc->dev;
     414           0 :         struct drm_mode_config *config = &dev->mode_config;
     415             :         int ret;
     416             : 
     417           0 :         if (property == config->prop_active)
     418           0 :                 state->active = val;
     419           0 :         else if (property == config->prop_mode_id) {
     420             :                 struct drm_property_blob *mode =
     421           0 :                         drm_property_lookup_blob(dev, val);
     422           0 :                 ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
     423           0 :                 if (mode)
     424           0 :                         drm_property_unreference_blob(mode);
     425             :                 return ret;
     426             :         }
     427           0 :         else if (crtc->funcs->atomic_set_property)
     428           0 :                 return crtc->funcs->atomic_set_property(crtc, state, property, val);
     429             :         else
     430           0 :                 return -EINVAL;
     431             : 
     432           0 :         return 0;
     433           0 : }
     434             : EXPORT_SYMBOL(drm_atomic_crtc_set_property);
     435             : 
     436             : /*
     437             :  * This function handles generic/core properties and calls out to
     438             :  * driver's ->atomic_get_property() for driver properties.  To ensure
     439             :  * consistent behavior you must call this function rather than the
     440             :  * driver hook directly.
     441             :  */
     442             : static int
     443           0 : drm_atomic_crtc_get_property(struct drm_crtc *crtc,
     444             :                 const struct drm_crtc_state *state,
     445             :                 struct drm_property *property, uint64_t *val)
     446             : {
     447           0 :         struct drm_device *dev = crtc->dev;
     448           0 :         struct drm_mode_config *config = &dev->mode_config;
     449             : 
     450           0 :         if (property == config->prop_active)
     451           0 :                 *val = state->active;
     452           0 :         else if (property == config->prop_mode_id)
     453           0 :                 *val = (state->mode_blob) ? state->mode_blob->base.id : 0;
     454           0 :         else if (crtc->funcs->atomic_get_property)
     455           0 :                 return crtc->funcs->atomic_get_property(crtc, state, property, val);
     456             :         else
     457           0 :                 return -EINVAL;
     458             : 
     459           0 :         return 0;
     460           0 : }
     461             : 
     462             : /**
     463             :  * drm_atomic_crtc_check - check crtc state
     464             :  * @crtc: crtc to check
     465             :  * @state: crtc state to check
     466             :  *
     467             :  * Provides core sanity checks for crtc state.
     468             :  *
     469             :  * RETURNS:
     470             :  * Zero on success, error code on failure
     471             :  */
     472           0 : static int drm_atomic_crtc_check(struct drm_crtc *crtc,
     473             :                 struct drm_crtc_state *state)
     474             : {
     475             :         /* NOTE: we explicitly don't enforce constraints such as primary
     476             :          * layer covering entire screen, since that is something we want
     477             :          * to allow (on hw that supports it).  For hw that does not, it
     478             :          * should be checked in driver's crtc->atomic_check() vfunc.
     479             :          *
     480             :          * TODO: Add generic modeset state checks once we support those.
     481             :          */
     482             : 
     483           0 :         if (state->active && !state->enable) {
     484             :                 DRM_DEBUG_ATOMIC("[CRTC:%d] active without enabled\n",
     485             :                                  crtc->base.id);
     486           0 :                 return -EINVAL;
     487             :         }
     488             : 
     489             :         /* The state->enable vs. state->mode_blob checks can be WARN_ON,
     490             :          * as this is a kernel-internal detail that userspace should never
     491             :          * be able to trigger. */
     492           0 :         if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
     493           0 :             WARN_ON(state->enable && !state->mode_blob)) {
     494             :                 DRM_DEBUG_ATOMIC("[CRTC:%d] enabled without mode blob\n",
     495             :                                  crtc->base.id);
     496           0 :                 return -EINVAL;
     497             :         }
     498             : 
     499           0 :         if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
     500           0 :             WARN_ON(!state->enable && state->mode_blob)) {
     501             :                 DRM_DEBUG_ATOMIC("[CRTC:%d] disabled with mode blob\n",
     502             :                                  crtc->base.id);
     503           0 :                 return -EINVAL;
     504             :         }
     505             : 
     506           0 :         return 0;
     507           0 : }
     508             : 
     509             : /**
     510             :  * drm_atomic_get_plane_state - get plane state
     511             :  * @state: global atomic state object
     512             :  * @plane: plane to get state object for
     513             :  *
     514             :  * This function returns the plane state for the given plane, allocating it if
     515             :  * needed. It will also grab the relevant plane lock to make sure that the state
     516             :  * is consistent.
     517             :  *
     518             :  * Returns:
     519             :  *
     520             :  * Either the allocated state or the error code encoded into the pointer. When
     521             :  * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
     522             :  * entire atomic sequence must be restarted. All other errors are fatal.
     523             :  */
     524             : struct drm_plane_state *
     525           0 : drm_atomic_get_plane_state(struct drm_atomic_state *state,
     526             :                           struct drm_plane *plane)
     527             : {
     528           0 :         int ret, index = drm_plane_index(plane);
     529             :         struct drm_plane_state *plane_state;
     530             : 
     531           0 :         plane_state = drm_atomic_get_existing_plane_state(state, plane);
     532           0 :         if (plane_state)
     533           0 :                 return plane_state;
     534             : 
     535           0 :         ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
     536           0 :         if (ret)
     537           0 :                 return ERR_PTR(ret);
     538             : 
     539           0 :         plane_state = plane->funcs->atomic_duplicate_state(plane);
     540           0 :         if (!plane_state)
     541           0 :                 return ERR_PTR(-ENOMEM);
     542             : 
     543           0 :         state->plane_states[index] = plane_state;
     544           0 :         state->planes[index] = plane;
     545           0 :         plane_state->state = state;
     546             : 
     547             :         DRM_DEBUG_ATOMIC("Added [PLANE:%d] %p state to %p\n",
     548             :                          plane->base.id, plane_state, state);
     549             : 
     550           0 :         if (plane_state->crtc) {
     551             :                 struct drm_crtc_state *crtc_state;
     552             : 
     553           0 :                 crtc_state = drm_atomic_get_crtc_state(state,
     554             :                                                        plane_state->crtc);
     555           0 :                 if (IS_ERR(crtc_state))
     556           0 :                         return ERR_CAST(crtc_state);
     557           0 :         }
     558             : 
     559           0 :         return plane_state;
     560           0 : }
     561             : EXPORT_SYMBOL(drm_atomic_get_plane_state);
     562             : 
     563             : /**
     564             :  * drm_atomic_plane_set_property - set property on plane
     565             :  * @plane: the drm plane to set a property on
     566             :  * @state: the state object to update with the new property value
     567             :  * @property: the property to set
     568             :  * @val: the new property value
     569             :  *
     570             :  * Use this instead of calling plane->atomic_set_property directly.
     571             :  * This function handles generic/core properties and calls out to
     572             :  * driver's ->atomic_set_property() for driver properties.  To ensure
     573             :  * consistent behavior you must call this function rather than the
     574             :  * driver hook directly.
     575             :  *
     576             :  * RETURNS:
     577             :  * Zero on success, error code on failure
     578             :  */
     579           0 : int drm_atomic_plane_set_property(struct drm_plane *plane,
     580             :                 struct drm_plane_state *state, struct drm_property *property,
     581             :                 uint64_t val)
     582             : {
     583           0 :         struct drm_device *dev = plane->dev;
     584           0 :         struct drm_mode_config *config = &dev->mode_config;
     585             : 
     586           0 :         if (property == config->prop_fb_id) {
     587           0 :                 struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
     588           0 :                 drm_atomic_set_fb_for_plane(state, fb);
     589           0 :                 if (fb)
     590           0 :                         drm_framebuffer_unreference(fb);
     591           0 :         } else if (property == config->prop_crtc_id) {
     592           0 :                 struct drm_crtc *crtc = drm_crtc_find(dev, val);
     593           0 :                 return drm_atomic_set_crtc_for_plane(state, crtc);
     594           0 :         } else if (property == config->prop_crtc_x) {
     595           0 :                 state->crtc_x = U642I64(val);
     596           0 :         } else if (property == config->prop_crtc_y) {
     597           0 :                 state->crtc_y = U642I64(val);
     598           0 :         } else if (property == config->prop_crtc_w) {
     599           0 :                 state->crtc_w = val;
     600           0 :         } else if (property == config->prop_crtc_h) {
     601           0 :                 state->crtc_h = val;
     602           0 :         } else if (property == config->prop_src_x) {
     603           0 :                 state->src_x = val;
     604           0 :         } else if (property == config->prop_src_y) {
     605           0 :                 state->src_y = val;
     606           0 :         } else if (property == config->prop_src_w) {
     607           0 :                 state->src_w = val;
     608           0 :         } else if (property == config->prop_src_h) {
     609           0 :                 state->src_h = val;
     610           0 :         } else if (property == config->rotation_property) {
     611           0 :                 state->rotation = val;
     612           0 :         } else if (plane->funcs->atomic_set_property) {
     613           0 :                 return plane->funcs->atomic_set_property(plane, state,
     614             :                                 property, val);
     615             :         } else {
     616           0 :                 return -EINVAL;
     617             :         }
     618             : 
     619           0 :         return 0;
     620           0 : }
     621             : EXPORT_SYMBOL(drm_atomic_plane_set_property);
     622             : 
     623             : /*
     624             :  * This function handles generic/core properties and calls out to
     625             :  * driver's ->atomic_get_property() for driver properties.  To ensure
     626             :  * consistent behavior you must call this function rather than the
     627             :  * driver hook directly.
     628             :  */
     629             : static int
     630           0 : drm_atomic_plane_get_property(struct drm_plane *plane,
     631             :                 const struct drm_plane_state *state,
     632             :                 struct drm_property *property, uint64_t *val)
     633             : {
     634           0 :         struct drm_device *dev = plane->dev;
     635           0 :         struct drm_mode_config *config = &dev->mode_config;
     636             : 
     637           0 :         if (property == config->prop_fb_id) {
     638           0 :                 *val = (state->fb) ? state->fb->base.id : 0;
     639           0 :         } else if (property == config->prop_crtc_id) {
     640           0 :                 *val = (state->crtc) ? state->crtc->base.id : 0;
     641           0 :         } else if (property == config->prop_crtc_x) {
     642           0 :                 *val = I642U64(state->crtc_x);
     643           0 :         } else if (property == config->prop_crtc_y) {
     644           0 :                 *val = I642U64(state->crtc_y);
     645           0 :         } else if (property == config->prop_crtc_w) {
     646           0 :                 *val = state->crtc_w;
     647           0 :         } else if (property == config->prop_crtc_h) {
     648           0 :                 *val = state->crtc_h;
     649           0 :         } else if (property == config->prop_src_x) {
     650           0 :                 *val = state->src_x;
     651           0 :         } else if (property == config->prop_src_y) {
     652           0 :                 *val = state->src_y;
     653           0 :         } else if (property == config->prop_src_w) {
     654           0 :                 *val = state->src_w;
     655           0 :         } else if (property == config->prop_src_h) {
     656           0 :                 *val = state->src_h;
     657           0 :         } else if (property == config->rotation_property) {
     658           0 :                 *val = state->rotation;
     659           0 :         } else if (plane->funcs->atomic_get_property) {
     660           0 :                 return plane->funcs->atomic_get_property(plane, state, property, val);
     661             :         } else {
     662           0 :                 return -EINVAL;
     663             :         }
     664             : 
     665           0 :         return 0;
     666           0 : }
     667             : 
     668             : static bool
     669           0 : plane_switching_crtc(struct drm_atomic_state *state,
     670             :                      struct drm_plane *plane,
     671             :                      struct drm_plane_state *plane_state)
     672             : {
     673           0 :         if (!plane->state->crtc || !plane_state->crtc)
     674           0 :                 return false;
     675             : 
     676           0 :         if (plane->state->crtc == plane_state->crtc)
     677           0 :                 return false;
     678             : 
     679             :         /* This could be refined, but currently there's no helper or driver code
     680             :          * to implement direct switching of active planes nor userspace to take
     681             :          * advantage of more direct plane switching without the intermediate
     682             :          * full OFF state.
     683             :          */
     684           0 :         return true;
     685           0 : }
     686             : 
     687             : /**
     688             :  * drm_atomic_plane_check - check plane state
     689             :  * @plane: plane to check
     690             :  * @state: plane state to check
     691             :  *
     692             :  * Provides core sanity checks for plane state.
     693             :  *
     694             :  * RETURNS:
     695             :  * Zero on success, error code on failure
     696             :  */
     697           0 : static int drm_atomic_plane_check(struct drm_plane *plane,
     698             :                 struct drm_plane_state *state)
     699             : {
     700             :         unsigned int fb_width, fb_height;
     701             :         int ret;
     702             : 
     703             :         /* either *both* CRTC and FB must be set, or neither */
     704           0 :         if (WARN_ON(state->crtc && !state->fb)) {
     705             :                 DRM_DEBUG_ATOMIC("CRTC set but no FB\n");
     706           0 :                 return -EINVAL;
     707           0 :         } else if (WARN_ON(state->fb && !state->crtc)) {
     708             :                 DRM_DEBUG_ATOMIC("FB set but no CRTC\n");
     709           0 :                 return -EINVAL;
     710             :         }
     711             : 
     712             :         /* if disabled, we don't care about the rest of the state: */
     713           0 :         if (!state->crtc)
     714           0 :                 return 0;
     715             : 
     716             :         /* Check whether this plane is usable on this CRTC */
     717           0 :         if (!(plane->possible_crtcs & drm_crtc_mask(state->crtc))) {
     718             :                 DRM_DEBUG_ATOMIC("Invalid crtc for plane\n");
     719           0 :                 return -EINVAL;
     720             :         }
     721             : 
     722             :         /* Check whether this plane supports the fb pixel format. */
     723           0 :         ret = drm_plane_check_pixel_format(plane, state->fb->pixel_format);
     724           0 :         if (ret) {
     725             :                 DRM_DEBUG_ATOMIC("Invalid pixel format %s\n",
     726             :                                  drm_get_format_name(state->fb->pixel_format));
     727           0 :                 return ret;
     728             :         }
     729             : 
     730             :         /* Give drivers some help against integer overflows */
     731           0 :         if (state->crtc_w > INT_MAX ||
     732           0 :             state->crtc_x > INT_MAX - (int32_t) state->crtc_w ||
     733           0 :             state->crtc_h > INT_MAX ||
     734           0 :             state->crtc_y > INT_MAX - (int32_t) state->crtc_h) {
     735             :                 DRM_DEBUG_ATOMIC("Invalid CRTC coordinates %ux%u+%d+%d\n",
     736             :                                  state->crtc_w, state->crtc_h,
     737             :                                  state->crtc_x, state->crtc_y);
     738           0 :                 return -ERANGE;
     739             :         }
     740             : 
     741           0 :         fb_width = state->fb->width << 16;
     742           0 :         fb_height = state->fb->height << 16;
     743             : 
     744             :         /* Make sure source coordinates are inside the fb. */
     745           0 :         if (state->src_w > fb_width ||
     746           0 :             state->src_x > fb_width - state->src_w ||
     747           0 :             state->src_h > fb_height ||
     748           0 :             state->src_y > fb_height - state->src_h) {
     749             :                 DRM_DEBUG_ATOMIC("Invalid source coordinates "
     750             :                                  "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
     751             :                                  state->src_w >> 16, ((state->src_w & 0xffff) * 15625) >> 10,
     752             :                                  state->src_h >> 16, ((state->src_h & 0xffff) * 15625) >> 10,
     753             :                                  state->src_x >> 16, ((state->src_x & 0xffff) * 15625) >> 10,
     754             :                                  state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10);
     755           0 :                 return -ENOSPC;
     756             :         }
     757             : 
     758           0 :         if (plane_switching_crtc(state->state, plane, state)) {
     759             :                 DRM_DEBUG_ATOMIC("[PLANE:%d] switching CRTC directly\n",
     760             :                                  plane->base.id);
     761           0 :                 return -EINVAL;
     762             :         }
     763             : 
     764           0 :         return 0;
     765           0 : }
     766             : 
     767             : /**
     768             :  * drm_atomic_get_connector_state - get connector state
     769             :  * @state: global atomic state object
     770             :  * @connector: connector to get state object for
     771             :  *
     772             :  * This function returns the connector state for the given connector,
     773             :  * allocating it if needed. It will also grab the relevant connector lock to
     774             :  * make sure that the state is consistent.
     775             :  *
     776             :  * Returns:
     777             :  *
     778             :  * Either the allocated state or the error code encoded into the pointer. When
     779             :  * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
     780             :  * entire atomic sequence must be restarted. All other errors are fatal.
     781             :  */
     782             : struct drm_connector_state *
     783           0 : drm_atomic_get_connector_state(struct drm_atomic_state *state,
     784             :                           struct drm_connector *connector)
     785             : {
     786             :         int ret, index;
     787           0 :         struct drm_mode_config *config = &connector->dev->mode_config;
     788             :         struct drm_connector_state *connector_state;
     789             : 
     790           0 :         ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
     791           0 :         if (ret)
     792           0 :                 return ERR_PTR(ret);
     793             : 
     794           0 :         index = drm_connector_index(connector);
     795             : 
     796             :         /*
     797             :          * Construction of atomic state updates can race with a connector
     798             :          * hot-add which might overflow. In this case flip the table and just
     799             :          * restart the entire ioctl - no one is fast enough to livelock a cpu
     800             :          * with physical hotplug events anyway.
     801             :          *
     802             :          * Note that we only grab the indexes once we have the right lock to
     803             :          * prevent hotplug/unplugging of connectors. So removal is no problem,
     804             :          * at most the array is a bit too large.
     805             :          */
     806           0 :         if (index >= state->num_connector) {
     807             :                 DRM_DEBUG_ATOMIC("Hot-added connector would overflow state array, restarting\n");
     808           0 :                 return ERR_PTR(-EAGAIN);
     809             :         }
     810             : 
     811           0 :         if (state->connector_states[index])
     812           0 :                 return state->connector_states[index];
     813             : 
     814           0 :         connector_state = connector->funcs->atomic_duplicate_state(connector);
     815           0 :         if (!connector_state)
     816           0 :                 return ERR_PTR(-ENOMEM);
     817             : 
     818           0 :         state->connector_states[index] = connector_state;
     819           0 :         state->connectors[index] = connector;
     820           0 :         connector_state->state = state;
     821             : 
     822             :         DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
     823             :                          connector->base.id, connector_state, state);
     824             : 
     825           0 :         if (connector_state->crtc) {
     826             :                 struct drm_crtc_state *crtc_state;
     827             : 
     828           0 :                 crtc_state = drm_atomic_get_crtc_state(state,
     829             :                                                        connector_state->crtc);
     830           0 :                 if (IS_ERR(crtc_state))
     831           0 :                         return ERR_CAST(crtc_state);
     832           0 :         }
     833             : 
     834           0 :         return connector_state;
     835           0 : }
     836             : EXPORT_SYMBOL(drm_atomic_get_connector_state);
     837             : 
     838             : /**
     839             :  * drm_atomic_connector_set_property - set property on connector.
     840             :  * @connector: the drm connector to set a property on
     841             :  * @state: the state object to update with the new property value
     842             :  * @property: the property to set
     843             :  * @val: the new property value
     844             :  *
     845             :  * Use this instead of calling connector->atomic_set_property directly.
     846             :  * This function handles generic/core properties and calls out to
     847             :  * driver's ->atomic_set_property() for driver properties.  To ensure
     848             :  * consistent behavior you must call this function rather than the
     849             :  * driver hook directly.
     850             :  *
     851             :  * RETURNS:
     852             :  * Zero on success, error code on failure
     853             :  */
     854           0 : int drm_atomic_connector_set_property(struct drm_connector *connector,
     855             :                 struct drm_connector_state *state, struct drm_property *property,
     856             :                 uint64_t val)
     857             : {
     858           0 :         struct drm_device *dev = connector->dev;
     859           0 :         struct drm_mode_config *config = &dev->mode_config;
     860             : 
     861           0 :         if (property == config->prop_crtc_id) {
     862           0 :                 struct drm_crtc *crtc = drm_crtc_find(dev, val);
     863           0 :                 return drm_atomic_set_crtc_for_connector(state, crtc);
     864           0 :         } else if (property == config->dpms_property) {
     865             :                 /* setting DPMS property requires special handling, which
     866             :                  * is done in legacy setprop path for us.  Disallow (for
     867             :                  * now?) atomic writes to DPMS property:
     868             :                  */
     869           0 :                 return -EINVAL;
     870           0 :         } else if (connector->funcs->atomic_set_property) {
     871           0 :                 return connector->funcs->atomic_set_property(connector,
     872             :                                 state, property, val);
     873             :         } else {
     874           0 :                 return -EINVAL;
     875             :         }
     876           0 : }
     877             : EXPORT_SYMBOL(drm_atomic_connector_set_property);
     878             : 
     879             : /*
     880             :  * This function handles generic/core properties and calls out to
     881             :  * driver's ->atomic_get_property() for driver properties.  To ensure
     882             :  * consistent behavior you must call this function rather than the
     883             :  * driver hook directly.
     884             :  */
     885             : static int
     886           0 : drm_atomic_connector_get_property(struct drm_connector *connector,
     887             :                 const struct drm_connector_state *state,
     888             :                 struct drm_property *property, uint64_t *val)
     889             : {
     890           0 :         struct drm_device *dev = connector->dev;
     891           0 :         struct drm_mode_config *config = &dev->mode_config;
     892             : 
     893           0 :         if (property == config->prop_crtc_id) {
     894           0 :                 *val = (state->crtc) ? state->crtc->base.id : 0;
     895           0 :         } else if (property == config->dpms_property) {
     896           0 :                 *val = connector->dpms;
     897           0 :         } else if (connector->funcs->atomic_get_property) {
     898           0 :                 return connector->funcs->atomic_get_property(connector,
     899             :                                 state, property, val);
     900             :         } else {
     901           0 :                 return -EINVAL;
     902             :         }
     903             : 
     904           0 :         return 0;
     905           0 : }
     906             : 
     907           0 : int drm_atomic_get_property(struct drm_mode_object *obj,
     908             :                 struct drm_property *property, uint64_t *val)
     909             : {
     910           0 :         struct drm_device *dev = property->dev;
     911             :         int ret;
     912             : 
     913           0 :         switch (obj->type) {
     914             :         case DRM_MODE_OBJECT_CONNECTOR: {
     915           0 :                 struct drm_connector *connector = obj_to_connector(obj);
     916           0 :                 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
     917           0 :                 ret = drm_atomic_connector_get_property(connector,
     918           0 :                                 connector->state, property, val);
     919             :                 break;
     920             :         }
     921             :         case DRM_MODE_OBJECT_CRTC: {
     922           0 :                 struct drm_crtc *crtc = obj_to_crtc(obj);
     923           0 :                 WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
     924           0 :                 ret = drm_atomic_crtc_get_property(crtc,
     925           0 :                                 crtc->state, property, val);
     926             :                 break;
     927             :         }
     928             :         case DRM_MODE_OBJECT_PLANE: {
     929           0 :                 struct drm_plane *plane = obj_to_plane(obj);
     930           0 :                 WARN_ON(!drm_modeset_is_locked(&plane->mutex));
     931           0 :                 ret = drm_atomic_plane_get_property(plane,
     932           0 :                                 plane->state, property, val);
     933             :                 break;
     934             :         }
     935             :         default:
     936             :                 ret = -EINVAL;
     937           0 :                 break;
     938             :         }
     939             : 
     940           0 :         return ret;
     941             : }
     942             : 
     943             : /**
     944             :  * drm_atomic_set_crtc_for_plane - set crtc for plane
     945             :  * @plane_state: the plane whose incoming state to update
     946             :  * @crtc: crtc to use for the plane
     947             :  *
     948             :  * Changing the assigned crtc for a plane requires us to grab the lock and state
     949             :  * for the new crtc, as needed. This function takes care of all these details
     950             :  * besides updating the pointer in the state object itself.
     951             :  *
     952             :  * Returns:
     953             :  * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
     954             :  * then the w/w mutex code has detected a deadlock and the entire atomic
     955             :  * sequence must be restarted. All other errors are fatal.
     956             :  */
     957             : int
     958           0 : drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
     959             :                               struct drm_crtc *crtc)
     960             : {
     961           0 :         struct drm_plane *plane = plane_state->plane;
     962             :         struct drm_crtc_state *crtc_state;
     963             :         /* Nothing to do for same crtc*/
     964           0 :         if (plane_state->crtc == crtc)
     965           0 :                 return 0;
     966           0 :         if (plane_state->crtc) {
     967           0 :                 crtc_state = drm_atomic_get_crtc_state(plane_state->state,
     968             :                                                        plane_state->crtc);
     969           0 :                 if (WARN_ON(IS_ERR(crtc_state)))
     970           0 :                         return PTR_ERR(crtc_state);
     971             : 
     972           0 :                 crtc_state->plane_mask &= ~(1 << drm_plane_index(plane));
     973           0 :         }
     974             : 
     975           0 :         plane_state->crtc = crtc;
     976             : 
     977           0 :         if (crtc) {
     978           0 :                 crtc_state = drm_atomic_get_crtc_state(plane_state->state,
     979             :                                                        crtc);
     980           0 :                 if (IS_ERR(crtc_state))
     981           0 :                         return PTR_ERR(crtc_state);
     982           0 :                 crtc_state->plane_mask |= (1 << drm_plane_index(plane));
     983           0 :         }
     984             : 
     985             :         if (crtc)
     986             :                 DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d]\n",
     987             :                                  plane_state, crtc->base.id);
     988             :         else
     989             :                 DRM_DEBUG_ATOMIC("Link plane state %p to [NOCRTC]\n",
     990             :                                  plane_state);
     991             : 
     992           0 :         return 0;
     993           0 : }
     994             : EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane);
     995             : 
     996             : /**
     997             :  * drm_atomic_set_fb_for_plane - set framebuffer for plane
     998             :  * @plane_state: atomic state object for the plane
     999             :  * @fb: fb to use for the plane
    1000             :  *
    1001             :  * Changing the assigned framebuffer for a plane requires us to grab a reference
    1002             :  * to the new fb and drop the reference to the old fb, if there is one. This
    1003             :  * function takes care of all these details besides updating the pointer in the
    1004             :  * state object itself.
    1005             :  */
    1006             : void
    1007           0 : drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
    1008             :                             struct drm_framebuffer *fb)
    1009             : {
    1010           0 :         if (plane_state->fb)
    1011           0 :                 drm_framebuffer_unreference(plane_state->fb);
    1012           0 :         if (fb)
    1013           0 :                 drm_framebuffer_reference(fb);
    1014           0 :         plane_state->fb = fb;
    1015             : 
    1016             :         if (fb)
    1017             :                 DRM_DEBUG_ATOMIC("Set [FB:%d] for plane state %p\n",
    1018             :                                  fb->base.id, plane_state);
    1019             :         else
    1020             :                 DRM_DEBUG_ATOMIC("Set [NOFB] for plane state %p\n",
    1021             :                                  plane_state);
    1022           0 : }
    1023             : EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
    1024             : 
    1025             : /**
    1026             :  * drm_atomic_set_crtc_for_connector - set crtc for connector
    1027             :  * @conn_state: atomic state object for the connector
    1028             :  * @crtc: crtc to use for the connector
    1029             :  *
    1030             :  * Changing the assigned crtc for a connector requires us to grab the lock and
    1031             :  * state for the new crtc, as needed. This function takes care of all these
    1032             :  * details besides updating the pointer in the state object itself.
    1033             :  *
    1034             :  * Returns:
    1035             :  * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
    1036             :  * then the w/w mutex code has detected a deadlock and the entire atomic
    1037             :  * sequence must be restarted. All other errors are fatal.
    1038             :  */
    1039             : int
    1040           0 : drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
    1041             :                                   struct drm_crtc *crtc)
    1042             : {
    1043             :         struct drm_crtc_state *crtc_state;
    1044             : 
    1045           0 :         if (crtc) {
    1046           0 :                 crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc);
    1047           0 :                 if (IS_ERR(crtc_state))
    1048           0 :                         return PTR_ERR(crtc_state);
    1049             :         }
    1050             : 
    1051           0 :         conn_state->crtc = crtc;
    1052             : 
    1053             :         if (crtc)
    1054             :                 DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d]\n",
    1055             :                                  conn_state, crtc->base.id);
    1056             :         else
    1057             :                 DRM_DEBUG_ATOMIC("Link connector state %p to [NOCRTC]\n",
    1058             :                                  conn_state);
    1059             : 
    1060           0 :         return 0;
    1061           0 : }
    1062             : EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
    1063             : 
    1064             : /**
    1065             :  * drm_atomic_add_affected_connectors - add connectors for crtc
    1066             :  * @state: atomic state
    1067             :  * @crtc: DRM crtc
    1068             :  *
    1069             :  * This function walks the current configuration and adds all connectors
    1070             :  * currently using @crtc to the atomic configuration @state. Note that this
    1071             :  * function must acquire the connection mutex. This can potentially cause
    1072             :  * unneeded seralization if the update is just for the planes on one crtc. Hence
    1073             :  * drivers and helpers should only call this when really needed (e.g. when a
    1074             :  * full modeset needs to happen due to some change).
    1075             :  *
    1076             :  * Returns:
    1077             :  * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
    1078             :  * then the w/w mutex code has detected a deadlock and the entire atomic
    1079             :  * sequence must be restarted. All other errors are fatal.
    1080             :  */
    1081             : int
    1082           0 : drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
    1083             :                                    struct drm_crtc *crtc)
    1084             : {
    1085           0 :         struct drm_mode_config *config = &state->dev->mode_config;
    1086             :         struct drm_connector *connector;
    1087             :         struct drm_connector_state *conn_state;
    1088             :         int ret;
    1089             : 
    1090           0 :         ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
    1091           0 :         if (ret)
    1092           0 :                 return ret;
    1093             : 
    1094             :         DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d] to %p\n",
    1095             :                          crtc->base.id, state);
    1096             : 
    1097             :         /*
    1098             :          * Changed connectors are already in @state, so only need to look at the
    1099             :          * current configuration.
    1100             :          */
    1101           0 :         drm_for_each_connector(connector, state->dev) {
    1102           0 :                 if (connector->state->crtc != crtc)
    1103             :                         continue;
    1104             : 
    1105           0 :                 conn_state = drm_atomic_get_connector_state(state, connector);
    1106           0 :                 if (IS_ERR(conn_state))
    1107           0 :                         return PTR_ERR(conn_state);
    1108             :         }
    1109             : 
    1110           0 :         return 0;
    1111           0 : }
    1112             : EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
    1113             : 
    1114             : /**
    1115             :  * drm_atomic_add_affected_planes - add planes for crtc
    1116             :  * @state: atomic state
    1117             :  * @crtc: DRM crtc
    1118             :  *
    1119             :  * This function walks the current configuration and adds all planes
    1120             :  * currently used by @crtc to the atomic configuration @state. This is useful
    1121             :  * when an atomic commit also needs to check all currently enabled plane on
    1122             :  * @crtc, e.g. when changing the mode. It's also useful when re-enabling a CRTC
    1123             :  * to avoid special code to force-enable all planes.
    1124             :  *
    1125             :  * Since acquiring a plane state will always also acquire the w/w mutex of the
    1126             :  * current CRTC for that plane (if there is any) adding all the plane states for
    1127             :  * a CRTC will not reduce parallism of atomic updates.
    1128             :  *
    1129             :  * Returns:
    1130             :  * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
    1131             :  * then the w/w mutex code has detected a deadlock and the entire atomic
    1132             :  * sequence must be restarted. All other errors are fatal.
    1133             :  */
    1134             : int
    1135           0 : drm_atomic_add_affected_planes(struct drm_atomic_state *state,
    1136             :                                struct drm_crtc *crtc)
    1137             : {
    1138             :         struct drm_plane *plane;
    1139             : 
    1140           0 :         WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc));
    1141             : 
    1142           0 :         drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
    1143             :                 struct drm_plane_state *plane_state =
    1144           0 :                         drm_atomic_get_plane_state(state, plane);
    1145             : 
    1146           0 :                 if (IS_ERR(plane_state))
    1147           0 :                         return PTR_ERR(plane_state);
    1148           0 :         }
    1149           0 :         return 0;
    1150           0 : }
    1151             : EXPORT_SYMBOL(drm_atomic_add_affected_planes);
    1152             : 
    1153             : /**
    1154             :  * drm_atomic_connectors_for_crtc - count number of connected outputs
    1155             :  * @state: atomic state
    1156             :  * @crtc: DRM crtc
    1157             :  *
    1158             :  * This function counts all connectors which will be connected to @crtc
    1159             :  * according to @state. Useful to recompute the enable state for @crtc.
    1160             :  */
    1161             : int
    1162           0 : drm_atomic_connectors_for_crtc(struct drm_atomic_state *state,
    1163             :                                struct drm_crtc *crtc)
    1164             : {
    1165             :         struct drm_connector *connector;
    1166             :         struct drm_connector_state *conn_state;
    1167             : 
    1168             :         int i, num_connected_connectors = 0;
    1169             : 
    1170           0 :         for_each_connector_in_state(state, connector, conn_state, i) {
    1171           0 :                 if (conn_state->crtc == crtc)
    1172           0 :                         num_connected_connectors++;
    1173             :         }
    1174             : 
    1175             :         DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d]\n",
    1176             :                          state, num_connected_connectors, crtc->base.id);
    1177             : 
    1178           0 :         return num_connected_connectors;
    1179             : }
    1180             : EXPORT_SYMBOL(drm_atomic_connectors_for_crtc);
    1181             : 
    1182             : /**
    1183             :  * drm_atomic_legacy_backoff - locking backoff for legacy ioctls
    1184             :  * @state: atomic state
    1185             :  *
    1186             :  * This function should be used by legacy entry points which don't understand
    1187             :  * -EDEADLK semantics. For simplicity this one will grab all modeset locks after
    1188             :  * the slowpath completed.
    1189             :  */
    1190           0 : void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
    1191             : {
    1192           0 :         int ret;
    1193             : 
    1194             : retry:
    1195           0 :         drm_modeset_backoff(state->acquire_ctx);
    1196             : 
    1197           0 :         ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
    1198           0 :                                state->acquire_ctx);
    1199           0 :         if (ret)
    1200           0 :                 goto retry;
    1201           0 :         ret = drm_modeset_lock_all_crtcs(state->dev,
    1202           0 :                                          state->acquire_ctx);
    1203           0 :         if (ret)
    1204           0 :                 goto retry;
    1205           0 : }
    1206             : EXPORT_SYMBOL(drm_atomic_legacy_backoff);
    1207             : 
    1208             : /**
    1209             :  * drm_atomic_check_only - check whether a given config would work
    1210             :  * @state: atomic configuration to check
    1211             :  *
    1212             :  * Note that this function can return -EDEADLK if the driver needed to acquire
    1213             :  * more locks but encountered a deadlock. The caller must then do the usual w/w
    1214             :  * backoff dance and restart. All other errors are fatal.
    1215             :  *
    1216             :  * Returns:
    1217             :  * 0 on success, negative error code on failure.
    1218             :  */
    1219           0 : int drm_atomic_check_only(struct drm_atomic_state *state)
    1220             : {
    1221           0 :         struct drm_device *dev = state->dev;
    1222           0 :         struct drm_mode_config *config = &dev->mode_config;
    1223             :         struct drm_plane *plane;
    1224             :         struct drm_plane_state *plane_state;
    1225             :         struct drm_crtc *crtc;
    1226             :         struct drm_crtc_state *crtc_state;
    1227             :         int i, ret = 0;
    1228             : 
    1229             :         DRM_DEBUG_ATOMIC("checking %p\n", state);
    1230             : 
    1231           0 :         for_each_plane_in_state(state, plane, plane_state, i) {
    1232           0 :                 ret = drm_atomic_plane_check(plane, plane_state);
    1233           0 :                 if (ret) {
    1234             :                         DRM_DEBUG_ATOMIC("[PLANE:%d] atomic core check failed\n",
    1235             :                                          plane->base.id);
    1236           0 :                         return ret;
    1237             :                 }
    1238             :         }
    1239             : 
    1240           0 :         for_each_crtc_in_state(state, crtc, crtc_state, i) {
    1241           0 :                 ret = drm_atomic_crtc_check(crtc, crtc_state);
    1242           0 :                 if (ret) {
    1243             :                         DRM_DEBUG_ATOMIC("[CRTC:%d] atomic core check failed\n",
    1244             :                                          crtc->base.id);
    1245           0 :                         return ret;
    1246             :                 }
    1247             :         }
    1248             : 
    1249           0 :         if (config->funcs->atomic_check)
    1250           0 :                 ret = config->funcs->atomic_check(state->dev, state);
    1251             : 
    1252           0 :         if (ret)
    1253           0 :                 return ret;
    1254             : 
    1255           0 :         if (!state->allow_modeset) {
    1256           0 :                 for_each_crtc_in_state(state, crtc, crtc_state, i) {
    1257           0 :                         if (drm_atomic_crtc_needs_modeset(crtc_state)) {
    1258             :                                 DRM_DEBUG_ATOMIC("[CRTC:%d] requires full modeset\n",
    1259             :                                                  crtc->base.id);
    1260           0 :                                 return -EINVAL;
    1261             :                         }
    1262             :                 }
    1263             :         }
    1264             : 
    1265           0 :         return 0;
    1266           0 : }
    1267             : EXPORT_SYMBOL(drm_atomic_check_only);
    1268             : 
    1269             : /**
    1270             :  * drm_atomic_commit - commit configuration atomically
    1271             :  * @state: atomic configuration to check
    1272             :  *
    1273             :  * Note that this function can return -EDEADLK if the driver needed to acquire
    1274             :  * more locks but encountered a deadlock. The caller must then do the usual w/w
    1275             :  * backoff dance and restart. All other errors are fatal.
    1276             :  *
    1277             :  * Also note that on successful execution ownership of @state is transferred
    1278             :  * from the caller of this function to the function itself. The caller must not
    1279             :  * free or in any other way access @state. If the function fails then the caller
    1280             :  * must clean up @state itself.
    1281             :  *
    1282             :  * Returns:
    1283             :  * 0 on success, negative error code on failure.
    1284             :  */
    1285           0 : int drm_atomic_commit(struct drm_atomic_state *state)
    1286             : {
    1287           0 :         struct drm_mode_config *config = &state->dev->mode_config;
    1288             :         int ret;
    1289             : 
    1290           0 :         ret = drm_atomic_check_only(state);
    1291           0 :         if (ret)
    1292           0 :                 return ret;
    1293             : 
    1294             :         DRM_DEBUG_ATOMIC("commiting %p\n", state);
    1295             : 
    1296           0 :         return config->funcs->atomic_commit(state->dev, state, false);
    1297           0 : }
    1298             : EXPORT_SYMBOL(drm_atomic_commit);
    1299             : 
    1300             : /**
    1301             :  * drm_atomic_async_commit - atomic&async configuration commit
    1302             :  * @state: atomic configuration to check
    1303             :  *
    1304             :  * Note that this function can return -EDEADLK if the driver needed to acquire
    1305             :  * more locks but encountered a deadlock. The caller must then do the usual w/w
    1306             :  * backoff dance and restart. All other errors are fatal.
    1307             :  *
    1308             :  * Also note that on successful execution ownership of @state is transferred
    1309             :  * from the caller of this function to the function itself. The caller must not
    1310             :  * free or in any other way access @state. If the function fails then the caller
    1311             :  * must clean up @state itself.
    1312             :  *
    1313             :  * Returns:
    1314             :  * 0 on success, negative error code on failure.
    1315             :  */
    1316           0 : int drm_atomic_async_commit(struct drm_atomic_state *state)
    1317             : {
    1318           0 :         struct drm_mode_config *config = &state->dev->mode_config;
    1319             :         int ret;
    1320             : 
    1321           0 :         ret = drm_atomic_check_only(state);
    1322           0 :         if (ret)
    1323           0 :                 return ret;
    1324             : 
    1325             :         DRM_DEBUG_ATOMIC("commiting %p asynchronously\n", state);
    1326             : 
    1327           0 :         return config->funcs->atomic_commit(state->dev, state, true);
    1328           0 : }
    1329             : EXPORT_SYMBOL(drm_atomic_async_commit);
    1330             : 
    1331             : /*
    1332             :  * The big monstor ioctl
    1333             :  */
    1334             : 
    1335           0 : static struct drm_pending_vblank_event *create_vblank_event(
    1336             :                 struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
    1337             : {
    1338             :         struct drm_pending_vblank_event *e = NULL;
    1339             :         unsigned long flags;
    1340             : 
    1341           0 :         spin_lock_irqsave(&dev->event_lock, flags);
    1342           0 :         if (file_priv->event_space < sizeof e->event) {
    1343           0 :                 spin_unlock_irqrestore(&dev->event_lock, flags);
    1344           0 :                 goto out;
    1345             :         }
    1346           0 :         file_priv->event_space -= sizeof e->event;
    1347           0 :         spin_unlock_irqrestore(&dev->event_lock, flags);
    1348             : 
    1349           0 :         e = kzalloc(sizeof *e, GFP_KERNEL);
    1350           0 :         if (e == NULL) {
    1351           0 :                 spin_lock_irqsave(&dev->event_lock, flags);
    1352           0 :                 file_priv->event_space += sizeof e->event;
    1353           0 :                 spin_unlock_irqrestore(&dev->event_lock, flags);
    1354           0 :                 goto out;
    1355             :         }
    1356             : 
    1357           0 :         e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
    1358           0 :         e->event.base.length = sizeof e->event;
    1359           0 :         e->event.user_data = user_data;
    1360           0 :         e->base.event = &e->event.base;
    1361           0 :         e->base.file_priv = file_priv;
    1362           0 :         e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
    1363             : 
    1364             : out:
    1365           0 :         return e;
    1366             : }
    1367             : 
    1368           0 : static void destroy_vblank_event(struct drm_device *dev,
    1369             :                 struct drm_file *file_priv, struct drm_pending_vblank_event *e)
    1370             : {
    1371             :         unsigned long flags;
    1372             : 
    1373           0 :         spin_lock_irqsave(&dev->event_lock, flags);
    1374           0 :         file_priv->event_space += sizeof e->event;
    1375           0 :         spin_unlock_irqrestore(&dev->event_lock, flags);
    1376           0 :         kfree(e);
    1377           0 : }
    1378             : 
    1379           0 : static int atomic_set_prop(struct drm_atomic_state *state,
    1380             :                 struct drm_mode_object *obj, struct drm_property *prop,
    1381             :                 uint64_t prop_value)
    1382             : {
    1383           0 :         struct drm_mode_object *ref;
    1384             :         int ret;
    1385             : 
    1386           0 :         if (!drm_property_change_valid_get(prop, prop_value, &ref))
    1387           0 :                 return -EINVAL;
    1388             : 
    1389           0 :         switch (obj->type) {
    1390             :         case DRM_MODE_OBJECT_CONNECTOR: {
    1391           0 :                 struct drm_connector *connector = obj_to_connector(obj);
    1392             :                 struct drm_connector_state *connector_state;
    1393             : 
    1394           0 :                 connector_state = drm_atomic_get_connector_state(state, connector);
    1395           0 :                 if (IS_ERR(connector_state)) {
    1396           0 :                         ret = PTR_ERR(connector_state);
    1397           0 :                         break;
    1398             :                 }
    1399             : 
    1400           0 :                 ret = drm_atomic_connector_set_property(connector,
    1401             :                                 connector_state, prop, prop_value);
    1402           0 :                 break;
    1403             :         }
    1404             :         case DRM_MODE_OBJECT_CRTC: {
    1405           0 :                 struct drm_crtc *crtc = obj_to_crtc(obj);
    1406             :                 struct drm_crtc_state *crtc_state;
    1407             : 
    1408           0 :                 crtc_state = drm_atomic_get_crtc_state(state, crtc);
    1409           0 :                 if (IS_ERR(crtc_state)) {
    1410           0 :                         ret = PTR_ERR(crtc_state);
    1411           0 :                         break;
    1412             :                 }
    1413             : 
    1414           0 :                 ret = drm_atomic_crtc_set_property(crtc,
    1415             :                                 crtc_state, prop, prop_value);
    1416           0 :                 break;
    1417             :         }
    1418             :         case DRM_MODE_OBJECT_PLANE: {
    1419           0 :                 struct drm_plane *plane = obj_to_plane(obj);
    1420             :                 struct drm_plane_state *plane_state;
    1421             : 
    1422           0 :                 plane_state = drm_atomic_get_plane_state(state, plane);
    1423           0 :                 if (IS_ERR(plane_state)) {
    1424           0 :                         ret = PTR_ERR(plane_state);
    1425           0 :                         break;
    1426             :                 }
    1427             : 
    1428           0 :                 ret = drm_atomic_plane_set_property(plane,
    1429             :                                 plane_state, prop, prop_value);
    1430           0 :                 break;
    1431             :         }
    1432             :         default:
    1433             :                 ret = -EINVAL;
    1434           0 :                 break;
    1435             :         }
    1436             : 
    1437           0 :         drm_property_change_valid_put(prop, ref);
    1438           0 :         return ret;
    1439           0 : }
    1440             : 
    1441             : /**
    1442             :  * drm_atomic_update_old_fb -- Unset old_fb pointers and set plane->fb pointers.
    1443             :  *
    1444             :  * @dev: drm device to check.
    1445             :  * @plane_mask: plane mask for planes that were updated.
    1446             :  * @ret: return value, can be -EDEADLK for a retry.
    1447             :  *
    1448             :  * Before doing an update plane->old_fb is set to plane->fb,
    1449             :  * but before dropping the locks old_fb needs to be set to NULL
    1450             :  * and plane->fb updated. This is a common operation for each
    1451             :  * atomic update, so this call is split off as a helper.
    1452             :  */
    1453           0 : void drm_atomic_clean_old_fb(struct drm_device *dev,
    1454             :                              unsigned plane_mask,
    1455             :                              int ret)
    1456             : {
    1457             :         struct drm_plane *plane;
    1458             : 
    1459             :         /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping
    1460             :          * locks (ie. while it is still safe to deref plane->state).  We
    1461             :          * need to do this here because the driver entry points cannot
    1462             :          * distinguish between legacy and atomic ioctls.
    1463             :          */
    1464           0 :         drm_for_each_plane_mask(plane, dev, plane_mask) {
    1465           0 :                 if (ret == 0) {
    1466           0 :                         struct drm_framebuffer *new_fb = plane->state->fb;
    1467           0 :                         if (new_fb)
    1468           0 :                                 drm_framebuffer_reference(new_fb);
    1469           0 :                         plane->fb = new_fb;
    1470           0 :                         plane->crtc = plane->state->crtc;
    1471             : 
    1472           0 :                         if (plane->old_fb)
    1473           0 :                                 drm_framebuffer_unreference(plane->old_fb);
    1474           0 :                 }
    1475           0 :                 plane->old_fb = NULL;
    1476           0 :         }
    1477           0 : }
    1478             : EXPORT_SYMBOL(drm_atomic_clean_old_fb);
    1479             : 
    1480           0 : int drm_mode_atomic_ioctl(struct drm_device *dev,
    1481             :                           void *data, struct drm_file *file_priv)
    1482             : {
    1483           0 :         struct drm_mode_atomic *arg = data;
    1484           0 :         uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr);
    1485           0 :         uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr);
    1486           0 :         uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
    1487           0 :         uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr);
    1488             :         unsigned int copied_objs, copied_props;
    1489             :         struct drm_atomic_state *state;
    1490           0 :         struct drm_modeset_acquire_ctx ctx;
    1491             :         struct drm_plane *plane;
    1492             :         struct drm_crtc *crtc;
    1493             :         struct drm_crtc_state *crtc_state;
    1494             :         unsigned plane_mask;
    1495             :         int ret = 0;
    1496             :         unsigned int i, j;
    1497             : 
    1498             :         /* disallow for drivers not supporting atomic: */
    1499           0 :         if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
    1500           0 :                 return -EINVAL;
    1501             : 
    1502             :         /* disallow for userspace that has not enabled atomic cap (even
    1503             :          * though this may be a bit overkill, since legacy userspace
    1504             :          * wouldn't know how to call this ioctl)
    1505             :          */
    1506           0 :         if (!file_priv->atomic)
    1507           0 :                 return -EINVAL;
    1508             : 
    1509           0 :         if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS)
    1510           0 :                 return -EINVAL;
    1511             : 
    1512           0 :         if (arg->reserved)
    1513           0 :                 return -EINVAL;
    1514             : 
    1515           0 :         if ((arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) &&
    1516           0 :                         !dev->mode_config.async_page_flip)
    1517           0 :                 return -EINVAL;
    1518             : 
    1519             :         /* can't test and expect an event at the same time. */
    1520           0 :         if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) &&
    1521           0 :                         (arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
    1522           0 :                 return -EINVAL;
    1523             : 
    1524           0 :         drm_modeset_acquire_init(&ctx, 0);
    1525             : 
    1526           0 :         state = drm_atomic_state_alloc(dev);
    1527           0 :         if (!state)
    1528           0 :                 return -ENOMEM;
    1529             : 
    1530           0 :         state->acquire_ctx = &ctx;
    1531           0 :         state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);
    1532             : 
    1533             : retry:
    1534             :         plane_mask = 0;
    1535             :         copied_objs = 0;
    1536             :         copied_props = 0;
    1537             : 
    1538           0 :         for (i = 0; i < arg->count_objs; i++) {
    1539           0 :                 uint32_t obj_id, count_props;
    1540             :                 struct drm_mode_object *obj;
    1541             : 
    1542           0 :                 if (get_user(obj_id, objs_ptr + copied_objs)) {
    1543             :                         ret = -EFAULT;
    1544           0 :                         goto out;
    1545             :                 }
    1546             : 
    1547           0 :                 obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY);
    1548           0 :                 if (!obj || !obj->properties) {
    1549             :                         ret = -ENOENT;
    1550           0 :                         goto out;
    1551             :                 }
    1552             : 
    1553           0 :                 if (get_user(count_props, count_props_ptr + copied_objs)) {
    1554             :                         ret = -EFAULT;
    1555           0 :                         goto out;
    1556             :                 }
    1557             : 
    1558           0 :                 copied_objs++;
    1559             : 
    1560           0 :                 for (j = 0; j < count_props; j++) {
    1561           0 :                         uint32_t prop_id;
    1562           0 :                         uint64_t prop_value;
    1563             :                         struct drm_property *prop;
    1564             : 
    1565           0 :                         if (get_user(prop_id, props_ptr + copied_props)) {
    1566             :                                 ret = -EFAULT;
    1567           0 :                                 goto out;
    1568             :                         }
    1569             : 
    1570           0 :                         prop = drm_property_find(dev, prop_id);
    1571           0 :                         if (!prop) {
    1572             :                                 ret = -ENOENT;
    1573           0 :                                 goto out;
    1574             :                         }
    1575             : 
    1576           0 :                         if (copy_from_user(&prop_value,
    1577           0 :                                            prop_values_ptr + copied_props,
    1578             :                                            sizeof(prop_value))) {
    1579             :                                 ret = -EFAULT;
    1580           0 :                                 goto out;
    1581             :                         }
    1582             : 
    1583           0 :                         ret = atomic_set_prop(state, obj, prop, prop_value);
    1584           0 :                         if (ret)
    1585           0 :                                 goto out;
    1586             : 
    1587           0 :                         copied_props++;
    1588           0 :                 }
    1589             : 
    1590           0 :                 if (obj->type == DRM_MODE_OBJECT_PLANE && count_props &&
    1591           0 :                     !(arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)) {
    1592           0 :                         plane = obj_to_plane(obj);
    1593           0 :                         plane_mask |= (1 << drm_plane_index(plane));
    1594           0 :                         plane->old_fb = plane->fb;
    1595           0 :                 }
    1596           0 :         }
    1597             : 
    1598           0 :         if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
    1599           0 :                 for_each_crtc_in_state(state, crtc, crtc_state, i) {
    1600             :                         struct drm_pending_vblank_event *e;
    1601             : 
    1602           0 :                         e = create_vblank_event(dev, file_priv, arg->user_data);
    1603           0 :                         if (!e) {
    1604             :                                 ret = -ENOMEM;
    1605           0 :                                 goto out;
    1606             :                         }
    1607             : 
    1608           0 :                         crtc_state->event = e;
    1609           0 :                 }
    1610             :         }
    1611             : 
    1612           0 :         if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
    1613             :                 /*
    1614             :                  * Unlike commit, check_only does not clean up state.
    1615             :                  * Below we call drm_atomic_state_free for it.
    1616             :                  */
    1617           0 :                 ret = drm_atomic_check_only(state);
    1618           0 :         } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
    1619           0 :                 ret = drm_atomic_async_commit(state);
    1620           0 :         } else {
    1621           0 :                 ret = drm_atomic_commit(state);
    1622             :         }
    1623             : 
    1624             : out:
    1625           0 :         drm_atomic_clean_old_fb(dev, plane_mask, ret);
    1626             : 
    1627           0 :         if (ret && arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
    1628             :                 /*
    1629             :                  * TEST_ONLY and PAGE_FLIP_EVENT are mutually exclusive,
    1630             :                  * if they weren't, this code should be called on success
    1631             :                  * for TEST_ONLY too.
    1632             :                  */
    1633             : 
    1634           0 :                 for_each_crtc_in_state(state, crtc, crtc_state, i) {
    1635           0 :                         if (!crtc_state->event)
    1636             :                                 continue;
    1637             : 
    1638           0 :                         destroy_vblank_event(dev, file_priv,
    1639             :                                              crtc_state->event);
    1640           0 :                 }
    1641             :         }
    1642             : 
    1643           0 :         if (ret == -EDEADLK) {
    1644           0 :                 drm_atomic_state_clear(state);
    1645           0 :                 drm_modeset_backoff(&ctx);
    1646           0 :                 goto retry;
    1647             :         }
    1648             : 
    1649           0 :         if (ret || arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
    1650           0 :                 drm_atomic_state_free(state);
    1651             : 
    1652           0 :         drm_modeset_drop_locks(&ctx);
    1653           0 :         drm_modeset_acquire_fini(&ctx);
    1654             : 
    1655           0 :         return ret;
    1656           0 : }

Generated by: LCOV version 1.13