Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2018 Intel Corp.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors:
0023  * Rob Clark <robdclark@gmail.com>
0024  * Daniel Vetter <daniel.vetter@ffwll.ch>
0025  */
0026 
0027 #include <drm/drm_atomic.h>
0028 #include <drm/drm_atomic_state_helper.h>
0029 #include <drm/drm_blend.h>
0030 #include <drm/drm_bridge.h>
0031 #include <drm/drm_connector.h>
0032 #include <drm/drm_crtc.h>
0033 #include <drm/drm_device.h>
0034 #include <drm/drm_framebuffer.h>
0035 #include <drm/drm_plane.h>
0036 #include <drm/drm_print.h>
0037 #include <drm/drm_vblank.h>
0038 #include <drm/drm_writeback.h>
0039 
0040 #include <linux/slab.h>
0041 #include <linux/dma-fence.h>
0042 
0043 /**
0044  * DOC: atomic state reset and initialization
0045  *
0046  * Both the drm core and the atomic helpers assume that there is always the full
0047  * and correct atomic software state for all connectors, CRTCs and planes
0048  * available. Which is a bit a problem on driver load and also after system
0049  * suspend. One way to solve this is to have a hardware state read-out
0050  * infrastructure which reconstructs the full software state (e.g. the i915
0051  * driver).
0052  *
0053  * The simpler solution is to just reset the software state to everything off,
0054  * which is easiest to do by calling drm_mode_config_reset(). To facilitate this
0055  * the atomic helpers provide default reset implementations for all hooks.
0056  *
0057  * On the upside the precise state tracking of atomic simplifies system suspend
0058  * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe
0059  * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume().
0060  * For other drivers the building blocks are split out, see the documentation
0061  * for these functions.
0062  */
0063 
0064 /**
0065  * __drm_atomic_helper_crtc_state_reset - reset the CRTC state
0066  * @crtc_state: atomic CRTC state, must not be NULL
0067  * @crtc: CRTC object, must not be NULL
0068  *
0069  * Initializes the newly allocated @crtc_state with default
0070  * values. This is useful for drivers that subclass the CRTC state.
0071  */
0072 void
0073 __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
0074                      struct drm_crtc *crtc)
0075 {
0076     crtc_state->crtc = crtc;
0077 }
0078 EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
0079 
0080 /**
0081  * __drm_atomic_helper_crtc_reset - reset state on CRTC
0082  * @crtc: drm CRTC
0083  * @crtc_state: CRTC state to assign
0084  *
0085  * Initializes the newly allocated @crtc_state and assigns it to
0086  * the &drm_crtc->state pointer of @crtc, usually required when
0087  * initializing the drivers or when called from the &drm_crtc_funcs.reset
0088  * hook.
0089  *
0090  * This is useful for drivers that subclass the CRTC state.
0091  */
0092 void
0093 __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
0094                    struct drm_crtc_state *crtc_state)
0095 {
0096     if (crtc_state)
0097         __drm_atomic_helper_crtc_state_reset(crtc_state, crtc);
0098 
0099     if (drm_dev_has_vblank(crtc->dev))
0100         drm_crtc_vblank_reset(crtc);
0101 
0102     crtc->state = crtc_state;
0103 }
0104 EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
0105 
0106 /**
0107  * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
0108  * @crtc: drm CRTC
0109  *
0110  * Resets the atomic state for @crtc by freeing the state pointer (which might
0111  * be NULL, e.g. at driver load time) and allocating a new empty state object.
0112  */
0113 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
0114 {
0115     struct drm_crtc_state *crtc_state =
0116         kzalloc(sizeof(*crtc->state), GFP_KERNEL);
0117 
0118     if (crtc->state)
0119         crtc->funcs->atomic_destroy_state(crtc, crtc->state);
0120 
0121     __drm_atomic_helper_crtc_reset(crtc, crtc_state);
0122 }
0123 EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
0124 
0125 /**
0126  * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
0127  * @crtc: CRTC object
0128  * @state: atomic CRTC state
0129  *
0130  * Copies atomic state from a CRTC's current state and resets inferred values.
0131  * This is useful for drivers that subclass the CRTC state.
0132  */
0133 void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
0134                           struct drm_crtc_state *state)
0135 {
0136     memcpy(state, crtc->state, sizeof(*state));
0137 
0138     if (state->mode_blob)
0139         drm_property_blob_get(state->mode_blob);
0140     if (state->degamma_lut)
0141         drm_property_blob_get(state->degamma_lut);
0142     if (state->ctm)
0143         drm_property_blob_get(state->ctm);
0144     if (state->gamma_lut)
0145         drm_property_blob_get(state->gamma_lut);
0146     state->mode_changed = false;
0147     state->active_changed = false;
0148     state->planes_changed = false;
0149     state->connectors_changed = false;
0150     state->color_mgmt_changed = false;
0151     state->zpos_changed = false;
0152     state->commit = NULL;
0153     state->event = NULL;
0154     state->async_flip = false;
0155 
0156     /* Self refresh should be canceled when a new update is available */
0157     state->active = drm_atomic_crtc_effectively_active(state);
0158     state->self_refresh_active = false;
0159 }
0160 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
0161 
0162 /**
0163  * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
0164  * @crtc: drm CRTC
0165  *
0166  * Default CRTC state duplicate hook for drivers which don't have their own
0167  * subclassed CRTC state structure.
0168  */
0169 struct drm_crtc_state *
0170 drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
0171 {
0172     struct drm_crtc_state *state;
0173 
0174     if (WARN_ON(!crtc->state))
0175         return NULL;
0176 
0177     state = kmalloc(sizeof(*state), GFP_KERNEL);
0178     if (state)
0179         __drm_atomic_helper_crtc_duplicate_state(crtc, state);
0180 
0181     return state;
0182 }
0183 EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
0184 
0185 /**
0186  * __drm_atomic_helper_crtc_destroy_state - release CRTC state
0187  * @state: CRTC state object to release
0188  *
0189  * Releases all resources stored in the CRTC state without actually freeing
0190  * the memory of the CRTC state. This is useful for drivers that subclass the
0191  * CRTC state.
0192  */
0193 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
0194 {
0195     if (state->commit) {
0196         /*
0197          * In the event that a non-blocking commit returns
0198          * -ERESTARTSYS before the commit_tail work is queued, we will
0199          * have an extra reference to the commit object. Release it, if
0200          * the event has not been consumed by the worker.
0201          *
0202          * state->event may be freed, so we can't directly look at
0203          * state->event->base.completion.
0204          */
0205         if (state->event && state->commit->abort_completion)
0206             drm_crtc_commit_put(state->commit);
0207 
0208         kfree(state->commit->event);
0209         state->commit->event = NULL;
0210 
0211         drm_crtc_commit_put(state->commit);
0212     }
0213 
0214     drm_property_blob_put(state->mode_blob);
0215     drm_property_blob_put(state->degamma_lut);
0216     drm_property_blob_put(state->ctm);
0217     drm_property_blob_put(state->gamma_lut);
0218 }
0219 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
0220 
0221 /**
0222  * drm_atomic_helper_crtc_destroy_state - default state destroy hook
0223  * @crtc: drm CRTC
0224  * @state: CRTC state object to release
0225  *
0226  * Default CRTC state destroy hook for drivers which don't have their own
0227  * subclassed CRTC state structure.
0228  */
0229 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
0230                       struct drm_crtc_state *state)
0231 {
0232     __drm_atomic_helper_crtc_destroy_state(state);
0233     kfree(state);
0234 }
0235 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
0236 
0237 /**
0238  * __drm_atomic_helper_plane_state_reset - resets plane state to default values
0239  * @plane_state: atomic plane state, must not be NULL
0240  * @plane: plane object, must not be NULL
0241  *
0242  * Initializes the newly allocated @plane_state with default
0243  * values. This is useful for drivers that subclass the CRTC state.
0244  */
0245 void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
0246                        struct drm_plane *plane)
0247 {
0248     u64 val;
0249 
0250     plane_state->plane = plane;
0251     plane_state->rotation = DRM_MODE_ROTATE_0;
0252 
0253     plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
0254     plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
0255 
0256     if (plane->color_encoding_property) {
0257         if (!drm_object_property_get_default_value(&plane->base,
0258                                plane->color_encoding_property,
0259                                &val))
0260             plane_state->color_encoding = val;
0261     }
0262 
0263     if (plane->color_range_property) {
0264         if (!drm_object_property_get_default_value(&plane->base,
0265                                plane->color_range_property,
0266                                &val))
0267             plane_state->color_range = val;
0268     }
0269 
0270     if (plane->zpos_property) {
0271         if (!drm_object_property_get_default_value(&plane->base,
0272                                plane->zpos_property,
0273                                &val)) {
0274             plane_state->zpos = val;
0275             plane_state->normalized_zpos = val;
0276         }
0277     }
0278 }
0279 EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
0280 
0281 /**
0282  * __drm_atomic_helper_plane_reset - reset state on plane
0283  * @plane: drm plane
0284  * @plane_state: plane state to assign
0285  *
0286  * Initializes the newly allocated @plane_state and assigns it to
0287  * the &drm_crtc->state pointer of @plane, usually required when
0288  * initializing the drivers or when called from the &drm_plane_funcs.reset
0289  * hook.
0290  *
0291  * This is useful for drivers that subclass the plane state.
0292  */
0293 void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
0294                      struct drm_plane_state *plane_state)
0295 {
0296     if (plane_state)
0297         __drm_atomic_helper_plane_state_reset(plane_state, plane);
0298 
0299     plane->state = plane_state;
0300 }
0301 EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
0302 
0303 /**
0304  * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes
0305  * @plane: drm plane
0306  *
0307  * Resets the atomic state for @plane by freeing the state pointer (which might
0308  * be NULL, e.g. at driver load time) and allocating a new empty state object.
0309  */
0310 void drm_atomic_helper_plane_reset(struct drm_plane *plane)
0311 {
0312     if (plane->state)
0313         __drm_atomic_helper_plane_destroy_state(plane->state);
0314 
0315     kfree(plane->state);
0316     plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
0317     if (plane->state)
0318         __drm_atomic_helper_plane_reset(plane, plane->state);
0319 }
0320 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
0321 
0322 /**
0323  * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
0324  * @plane: plane object
0325  * @state: atomic plane state
0326  *
0327  * Copies atomic state from a plane's current state. This is useful for
0328  * drivers that subclass the plane state.
0329  */
0330 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
0331                            struct drm_plane_state *state)
0332 {
0333     memcpy(state, plane->state, sizeof(*state));
0334 
0335     if (state->fb)
0336         drm_framebuffer_get(state->fb);
0337 
0338     state->fence = NULL;
0339     state->commit = NULL;
0340     state->fb_damage_clips = NULL;
0341 }
0342 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
0343 
0344 /**
0345  * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
0346  * @plane: drm plane
0347  *
0348  * Default plane state duplicate hook for drivers which don't have their own
0349  * subclassed plane state structure.
0350  */
0351 struct drm_plane_state *
0352 drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
0353 {
0354     struct drm_plane_state *state;
0355 
0356     if (WARN_ON(!plane->state))
0357         return NULL;
0358 
0359     state = kmalloc(sizeof(*state), GFP_KERNEL);
0360     if (state)
0361         __drm_atomic_helper_plane_duplicate_state(plane, state);
0362 
0363     return state;
0364 }
0365 EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
0366 
0367 /**
0368  * __drm_atomic_helper_plane_destroy_state - release plane state
0369  * @state: plane state object to release
0370  *
0371  * Releases all resources stored in the plane state without actually freeing
0372  * the memory of the plane state. This is useful for drivers that subclass the
0373  * plane state.
0374  */
0375 void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
0376 {
0377     if (state->fb)
0378         drm_framebuffer_put(state->fb);
0379 
0380     if (state->fence)
0381         dma_fence_put(state->fence);
0382 
0383     if (state->commit)
0384         drm_crtc_commit_put(state->commit);
0385 
0386     drm_property_blob_put(state->fb_damage_clips);
0387 }
0388 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
0389 
0390 /**
0391  * drm_atomic_helper_plane_destroy_state - default state destroy hook
0392  * @plane: drm plane
0393  * @state: plane state object to release
0394  *
0395  * Default plane state destroy hook for drivers which don't have their own
0396  * subclassed plane state structure.
0397  */
0398 void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
0399                        struct drm_plane_state *state)
0400 {
0401     __drm_atomic_helper_plane_destroy_state(state);
0402     kfree(state);
0403 }
0404 EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
0405 
0406 /**
0407  * __drm_atomic_helper_connector_state_reset - reset the connector state
0408  * @conn_state: atomic connector state, must not be NULL
0409  * @connector: connectotr object, must not be NULL
0410  *
0411  * Initializes the newly allocated @conn_state with default
0412  * values. This is useful for drivers that subclass the connector state.
0413  */
0414 void
0415 __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state,
0416                       struct drm_connector *connector)
0417 {
0418     conn_state->connector = connector;
0419 }
0420 EXPORT_SYMBOL(__drm_atomic_helper_connector_state_reset);
0421 
0422 /**
0423  * __drm_atomic_helper_connector_reset - reset state on connector
0424  * @connector: drm connector
0425  * @conn_state: connector state to assign
0426  *
0427  * Initializes the newly allocated @conn_state and assigns it to
0428  * the &drm_connector->state pointer of @connector, usually required when
0429  * initializing the drivers or when called from the &drm_connector_funcs.reset
0430  * hook.
0431  *
0432  * This is useful for drivers that subclass the connector state.
0433  */
0434 void
0435 __drm_atomic_helper_connector_reset(struct drm_connector *connector,
0436                     struct drm_connector_state *conn_state)
0437 {
0438     if (conn_state)
0439         __drm_atomic_helper_connector_state_reset(conn_state, connector);
0440 
0441     connector->state = conn_state;
0442 }
0443 EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
0444 
0445 /**
0446  * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors
0447  * @connector: drm connector
0448  *
0449  * Resets the atomic state for @connector by freeing the state pointer (which
0450  * might be NULL, e.g. at driver load time) and allocating a new empty state
0451  * object.
0452  */
0453 void drm_atomic_helper_connector_reset(struct drm_connector *connector)
0454 {
0455     struct drm_connector_state *conn_state =
0456         kzalloc(sizeof(*conn_state), GFP_KERNEL);
0457 
0458     if (connector->state)
0459         __drm_atomic_helper_connector_destroy_state(connector->state);
0460 
0461     kfree(connector->state);
0462     __drm_atomic_helper_connector_reset(connector, conn_state);
0463 }
0464 EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
0465 
0466 /**
0467  * drm_atomic_helper_connector_tv_reset - Resets TV connector properties
0468  * @connector: DRM connector
0469  *
0470  * Resets the TV-related properties attached to a connector.
0471  */
0472 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
0473 {
0474     struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
0475     struct drm_connector_state *state = connector->state;
0476 
0477     state->tv.margins.left = cmdline->tv_margins.left;
0478     state->tv.margins.right = cmdline->tv_margins.right;
0479     state->tv.margins.top = cmdline->tv_margins.top;
0480     state->tv.margins.bottom = cmdline->tv_margins.bottom;
0481 }
0482 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
0483 
0484 /**
0485  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
0486  * @connector: connector object
0487  * @state: atomic connector state
0488  *
0489  * Copies atomic state from a connector's current state. This is useful for
0490  * drivers that subclass the connector state.
0491  */
0492 void
0493 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
0494                         struct drm_connector_state *state)
0495 {
0496     memcpy(state, connector->state, sizeof(*state));
0497     if (state->crtc)
0498         drm_connector_get(connector);
0499     state->commit = NULL;
0500 
0501     if (state->hdr_output_metadata)
0502         drm_property_blob_get(state->hdr_output_metadata);
0503 
0504     /* Don't copy over a writeback job, they are used only once */
0505     state->writeback_job = NULL;
0506 }
0507 EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
0508 
0509 /**
0510  * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
0511  * @connector: drm connector
0512  *
0513  * Default connector state duplicate hook for drivers which don't have their own
0514  * subclassed connector state structure.
0515  */
0516 struct drm_connector_state *
0517 drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
0518 {
0519     struct drm_connector_state *state;
0520 
0521     if (WARN_ON(!connector->state))
0522         return NULL;
0523 
0524     state = kmalloc(sizeof(*state), GFP_KERNEL);
0525     if (state)
0526         __drm_atomic_helper_connector_duplicate_state(connector, state);
0527 
0528     return state;
0529 }
0530 EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
0531 
0532 /**
0533  * __drm_atomic_helper_connector_destroy_state - release connector state
0534  * @state: connector state object to release
0535  *
0536  * Releases all resources stored in the connector state without actually
0537  * freeing the memory of the connector state. This is useful for drivers that
0538  * subclass the connector state.
0539  */
0540 void
0541 __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
0542 {
0543     if (state->crtc)
0544         drm_connector_put(state->connector);
0545 
0546     if (state->commit)
0547         drm_crtc_commit_put(state->commit);
0548 
0549     if (state->writeback_job)
0550         drm_writeback_cleanup_job(state->writeback_job);
0551 
0552     drm_property_blob_put(state->hdr_output_metadata);
0553 }
0554 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
0555 
0556 /**
0557  * drm_atomic_helper_connector_destroy_state - default state destroy hook
0558  * @connector: drm connector
0559  * @state: connector state object to release
0560  *
0561  * Default connector state destroy hook for drivers which don't have their own
0562  * subclassed connector state structure.
0563  */
0564 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
0565                       struct drm_connector_state *state)
0566 {
0567     __drm_atomic_helper_connector_destroy_state(state);
0568     kfree(state);
0569 }
0570 EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
0571 
0572 /**
0573  * __drm_atomic_helper_private_obj_duplicate_state - copy atomic private state
0574  * @obj: CRTC object
0575  * @state: new private object state
0576  *
0577  * Copies atomic state from a private objects's current state and resets inferred values.
0578  * This is useful for drivers that subclass the private state.
0579  */
0580 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
0581                              struct drm_private_state *state)
0582 {
0583     memcpy(state, obj->state, sizeof(*state));
0584 }
0585 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
0586 
0587 /**
0588  * __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state
0589  * @bridge: bridge object
0590  * @state: atomic bridge state
0591  *
0592  * Copies atomic state from a bridge's current state and resets inferred values.
0593  * This is useful for drivers that subclass the bridge state.
0594  */
0595 void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
0596                         struct drm_bridge_state *state)
0597 {
0598     __drm_atomic_helper_private_obj_duplicate_state(&bridge->base,
0599                             &state->base);
0600     state->bridge = bridge;
0601 }
0602 EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state);
0603 
0604 /**
0605  * drm_atomic_helper_bridge_duplicate_state() - Duplicate a bridge state object
0606  * @bridge: bridge object
0607  *
0608  * Allocates a new bridge state and initializes it with the current bridge
0609  * state values. This helper is meant to be used as a bridge
0610  * &drm_bridge_funcs.atomic_duplicate_state hook for bridges that don't
0611  * subclass the bridge state.
0612  */
0613 struct drm_bridge_state *
0614 drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge)
0615 {
0616     struct drm_bridge_state *new;
0617 
0618     if (WARN_ON(!bridge->base.state))
0619         return NULL;
0620 
0621     new = kzalloc(sizeof(*new), GFP_KERNEL);
0622     if (new)
0623         __drm_atomic_helper_bridge_duplicate_state(bridge, new);
0624 
0625     return new;
0626 }
0627 EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state);
0628 
0629 /**
0630  * drm_atomic_helper_bridge_destroy_state() - Destroy a bridge state object
0631  * @bridge: the bridge this state refers to
0632  * @state: bridge state to destroy
0633  *
0634  * Destroys a bridge state previously created by
0635  * &drm_atomic_helper_bridge_reset() or
0636  * &drm_atomic_helper_bridge_duplicate_state(). This helper is meant to be
0637  * used as a bridge &drm_bridge_funcs.atomic_destroy_state hook for bridges
0638  * that don't subclass the bridge state.
0639  */
0640 void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge,
0641                         struct drm_bridge_state *state)
0642 {
0643     kfree(state);
0644 }
0645 EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state);
0646 
0647 /**
0648  * __drm_atomic_helper_bridge_reset() - Initialize a bridge state to its
0649  *                  default
0650  * @bridge: the bridge this state refers to
0651  * @state: bridge state to initialize
0652  *
0653  * Initializes the bridge state to default values. This is meant to be called
0654  * by the bridge &drm_bridge_funcs.atomic_reset hook for bridges that subclass
0655  * the bridge state.
0656  */
0657 void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge,
0658                       struct drm_bridge_state *state)
0659 {
0660     memset(state, 0, sizeof(*state));
0661     state->bridge = bridge;
0662 }
0663 EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset);
0664 
0665 /**
0666  * drm_atomic_helper_bridge_reset() - Allocate and initialize a bridge state
0667  *                    to its default
0668  * @bridge: the bridge this state refers to
0669  *
0670  * Allocates the bridge state and initializes it to default values. This helper
0671  * is meant to be used as a bridge &drm_bridge_funcs.atomic_reset hook for
0672  * bridges that don't subclass the bridge state.
0673  */
0674 struct drm_bridge_state *
0675 drm_atomic_helper_bridge_reset(struct drm_bridge *bridge)
0676 {
0677     struct drm_bridge_state *bridge_state;
0678 
0679     bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL);
0680     if (!bridge_state)
0681         return ERR_PTR(-ENOMEM);
0682 
0683     __drm_atomic_helper_bridge_reset(bridge, bridge_state);
0684     return bridge_state;
0685 }
0686 EXPORT_SYMBOL(drm_atomic_helper_bridge_reset);