1 /* 2 * Copyright (C) 2018 Intel Corp. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: 23 * Rob Clark <robdclark@gmail.com> 24 * Daniel Vetter <daniel.vetter@ffwll.ch> 25 */ 26 27 #include <drm/drm_atomic.h> 28 #include <drm/drm_atomic_state_helper.h> 29 #include <drm/drm_bridge.h> 30 #include <drm/drm_connector.h> 31 #include <drm/drm_crtc.h> 32 #include <drm/drm_device.h> 33 #include <drm/drm_framebuffer.h> 34 #include <drm/drm_plane.h> 35 #include <drm/drm_print.h> 36 #include <drm/drm_vblank.h> 37 #include <drm/drm_writeback.h> 38 39 #include <linux/slab.h> 40 #include <linux/dma-fence.h> 41 42 /** 43 * DOC: atomic state reset and initialization 44 * 45 * Both the drm core and the atomic helpers assume that there is always the full 46 * and correct atomic software state for all connectors, CRTCs and planes 47 * available. Which is a bit a problem on driver load and also after system 48 * suspend. One way to solve this is to have a hardware state read-out 49 * infrastructure which reconstructs the full software state (e.g. the i915 50 * driver). 51 * 52 * The simpler solution is to just reset the software state to everything off, 53 * which is easiest to do by calling drm_mode_config_reset(). To facilitate this 54 * the atomic helpers provide default reset implementations for all hooks. 55 * 56 * On the upside the precise state tracking of atomic simplifies system suspend 57 * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe 58 * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume(). 59 * For other drivers the building blocks are split out, see the documentation 60 * for these functions. 61 */ 62 63 /** 64 * __drm_atomic_helper_crtc_state_reset - reset the CRTC state 65 * @crtc_state: atomic CRTC state, must not be NULL 66 * @crtc: CRTC object, must not be NULL 67 * 68 * Initializes the newly allocated @crtc_state with default 69 * values. This is useful for drivers that subclass the CRTC state. 70 */ 71 void 72 __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state, 73 struct drm_crtc *crtc) 74 { 75 crtc_state->crtc = crtc; 76 } 77 EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset); 78 79 /** 80 * __drm_atomic_helper_crtc_reset - reset state on CRTC 81 * @crtc: drm CRTC 82 * @crtc_state: CRTC state to assign 83 * 84 * Initializes the newly allocated @crtc_state and assigns it to 85 * the &drm_crtc->state pointer of @crtc, usually required when 86 * initializing the drivers or when called from the &drm_crtc_funcs.reset 87 * hook. 88 * 89 * This is useful for drivers that subclass the CRTC state. 90 */ 91 void 92 __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, 93 struct drm_crtc_state *crtc_state) 94 { 95 if (crtc_state) 96 __drm_atomic_helper_crtc_state_reset(crtc_state, crtc); 97 98 if (drm_dev_has_vblank(crtc->dev)) 99 drm_crtc_vblank_reset(crtc); 100 101 crtc->state = crtc_state; 102 } 103 EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset); 104 105 /** 106 * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs 107 * @crtc: drm CRTC 108 * 109 * Resets the atomic state for @crtc by freeing the state pointer (which might 110 * be NULL, e.g. at driver load time) and allocating a new empty state object. 111 */ 112 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) 113 { 114 struct drm_crtc_state *crtc_state = 115 kzalloc(sizeof(*crtc->state), GFP_KERNEL); 116 117 if (crtc->state) 118 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 119 120 __drm_atomic_helper_crtc_reset(crtc, crtc_state); 121 } 122 EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); 123 124 /** 125 * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state 126 * @crtc: CRTC object 127 * @state: atomic CRTC state 128 * 129 * Copies atomic state from a CRTC's current state and resets inferred values. 130 * This is useful for drivers that subclass the CRTC state. 131 */ 132 void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, 133 struct drm_crtc_state *state) 134 { 135 memcpy(state, crtc->state, sizeof(*state)); 136 137 if (state->mode_blob) 138 drm_property_blob_get(state->mode_blob); 139 if (state->degamma_lut) 140 drm_property_blob_get(state->degamma_lut); 141 if (state->ctm) 142 drm_property_blob_get(state->ctm); 143 if (state->gamma_lut) 144 drm_property_blob_get(state->gamma_lut); 145 state->mode_changed = false; 146 state->active_changed = false; 147 state->planes_changed = false; 148 state->connectors_changed = false; 149 state->color_mgmt_changed = false; 150 state->zpos_changed = false; 151 state->commit = NULL; 152 state->event = NULL; 153 state->async_flip = false; 154 155 /* Self refresh should be canceled when a new update is available */ 156 state->active = drm_atomic_crtc_effectively_active(state); 157 state->self_refresh_active = false; 158 } 159 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); 160 161 /** 162 * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook 163 * @crtc: drm CRTC 164 * 165 * Default CRTC state duplicate hook for drivers which don't have their own 166 * subclassed CRTC state structure. 167 */ 168 struct drm_crtc_state * 169 drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc) 170 { 171 struct drm_crtc_state *state; 172 173 if (WARN_ON(!crtc->state)) 174 return NULL; 175 176 state = kmalloc(sizeof(*state), GFP_KERNEL); 177 if (state) 178 __drm_atomic_helper_crtc_duplicate_state(crtc, state); 179 180 return state; 181 } 182 EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state); 183 184 /** 185 * __drm_atomic_helper_crtc_destroy_state - release CRTC state 186 * @state: CRTC state object to release 187 * 188 * Releases all resources stored in the CRTC state without actually freeing 189 * the memory of the CRTC state. This is useful for drivers that subclass the 190 * CRTC state. 191 */ 192 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) 193 { 194 if (state->commit) { 195 /* 196 * In the event that a non-blocking commit returns 197 * -ERESTARTSYS before the commit_tail work is queued, we will 198 * have an extra reference to the commit object. Release it, if 199 * the event has not been consumed by the worker. 200 * 201 * state->event may be freed, so we can't directly look at 202 * state->event->base.completion. 203 */ 204 if (state->event && state->commit->abort_completion) 205 drm_crtc_commit_put(state->commit); 206 207 kfree(state->commit->event); 208 state->commit->event = NULL; 209 210 drm_crtc_commit_put(state->commit); 211 } 212 213 drm_property_blob_put(state->mode_blob); 214 drm_property_blob_put(state->degamma_lut); 215 drm_property_blob_put(state->ctm); 216 drm_property_blob_put(state->gamma_lut); 217 } 218 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); 219 220 /** 221 * drm_atomic_helper_crtc_destroy_state - default state destroy hook 222 * @crtc: drm CRTC 223 * @state: CRTC state object to release 224 * 225 * Default CRTC state destroy hook for drivers which don't have their own 226 * subclassed CRTC state structure. 227 */ 228 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, 229 struct drm_crtc_state *state) 230 { 231 __drm_atomic_helper_crtc_destroy_state(state); 232 kfree(state); 233 } 234 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); 235 236 /** 237 * __drm_atomic_helper_plane_state_reset - resets plane state to default values 238 * @plane_state: atomic plane state, must not be NULL 239 * @plane: plane object, must not be NULL 240 * 241 * Initializes the newly allocated @plane_state with default 242 * values. This is useful for drivers that subclass the CRTC state. 243 */ 244 void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, 245 struct drm_plane *plane) 246 { 247 u64 val; 248 249 plane_state->plane = plane; 250 plane_state->rotation = DRM_MODE_ROTATE_0; 251 252 plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE; 253 plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; 254 255 if (plane->color_encoding_property) { 256 if (!drm_object_property_get_default_value(&plane->base, 257 plane->color_encoding_property, 258 &val)) 259 plane_state->color_encoding = val; 260 } 261 262 if (plane->color_range_property) { 263 if (!drm_object_property_get_default_value(&plane->base, 264 plane->color_range_property, 265 &val)) 266 plane_state->color_range = val; 267 } 268 269 if (plane->zpos_property) { 270 if (!drm_object_property_get_default_value(&plane->base, 271 plane->zpos_property, 272 &val)) { 273 plane_state->zpos = val; 274 plane_state->normalized_zpos = val; 275 } 276 } 277 } 278 EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset); 279 280 /** 281 * __drm_atomic_helper_plane_reset - reset state on plane 282 * @plane: drm plane 283 * @plane_state: plane state to assign 284 * 285 * Initializes the newly allocated @plane_state and assigns it to 286 * the &drm_crtc->state pointer of @plane, usually required when 287 * initializing the drivers or when called from the &drm_plane_funcs.reset 288 * hook. 289 * 290 * This is useful for drivers that subclass the plane state. 291 */ 292 void __drm_atomic_helper_plane_reset(struct drm_plane *plane, 293 struct drm_plane_state *plane_state) 294 { 295 if (plane_state) 296 __drm_atomic_helper_plane_state_reset(plane_state, plane); 297 298 plane->state = plane_state; 299 } 300 EXPORT_SYMBOL(__drm_atomic_helper_plane_reset); 301 302 /** 303 * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes 304 * @plane: drm plane 305 * 306 * Resets the atomic state for @plane by freeing the state pointer (which might 307 * be NULL, e.g. at driver load time) and allocating a new empty state object. 308 */ 309 void drm_atomic_helper_plane_reset(struct drm_plane *plane) 310 { 311 if (plane->state) 312 __drm_atomic_helper_plane_destroy_state(plane->state); 313 314 kfree(plane->state); 315 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); 316 if (plane->state) 317 __drm_atomic_helper_plane_reset(plane, plane->state); 318 } 319 EXPORT_SYMBOL(drm_atomic_helper_plane_reset); 320 321 /** 322 * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state 323 * @plane: plane object 324 * @state: atomic plane state 325 * 326 * Copies atomic state from a plane's current state. This is useful for 327 * drivers that subclass the plane state. 328 */ 329 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, 330 struct drm_plane_state *state) 331 { 332 memcpy(state, plane->state, sizeof(*state)); 333 334 if (state->fb) 335 drm_framebuffer_get(state->fb); 336 337 state->fence = NULL; 338 state->commit = NULL; 339 state->fb_damage_clips = NULL; 340 } 341 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); 342 343 /** 344 * drm_atomic_helper_plane_duplicate_state - default state duplicate hook 345 * @plane: drm plane 346 * 347 * Default plane state duplicate hook for drivers which don't have their own 348 * subclassed plane state structure. 349 */ 350 struct drm_plane_state * 351 drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane) 352 { 353 struct drm_plane_state *state; 354 355 if (WARN_ON(!plane->state)) 356 return NULL; 357 358 state = kmalloc(sizeof(*state), GFP_KERNEL); 359 if (state) 360 __drm_atomic_helper_plane_duplicate_state(plane, state); 361 362 return state; 363 } 364 EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); 365 366 /** 367 * __drm_atomic_helper_plane_destroy_state - release plane state 368 * @state: plane state object to release 369 * 370 * Releases all resources stored in the plane state without actually freeing 371 * the memory of the plane state. This is useful for drivers that subclass the 372 * plane state. 373 */ 374 void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) 375 { 376 if (state->fb) 377 drm_framebuffer_put(state->fb); 378 379 if (state->fence) 380 dma_fence_put(state->fence); 381 382 if (state->commit) 383 drm_crtc_commit_put(state->commit); 384 385 drm_property_blob_put(state->fb_damage_clips); 386 } 387 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); 388 389 /** 390 * drm_atomic_helper_plane_destroy_state - default state destroy hook 391 * @plane: drm plane 392 * @state: plane state object to release 393 * 394 * Default plane state destroy hook for drivers which don't have their own 395 * subclassed plane state structure. 396 */ 397 void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, 398 struct drm_plane_state *state) 399 { 400 __drm_atomic_helper_plane_destroy_state(state); 401 kfree(state); 402 } 403 EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); 404 405 /** 406 * __drm_atomic_helper_connector_state_reset - reset the connector state 407 * @conn_state: atomic connector state, must not be NULL 408 * @connector: connectotr object, must not be NULL 409 * 410 * Initializes the newly allocated @conn_state with default 411 * values. This is useful for drivers that subclass the connector state. 412 */ 413 void 414 __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state, 415 struct drm_connector *connector) 416 { 417 conn_state->connector = connector; 418 } 419 EXPORT_SYMBOL(__drm_atomic_helper_connector_state_reset); 420 421 /** 422 * __drm_atomic_helper_connector_reset - reset state on connector 423 * @connector: drm connector 424 * @conn_state: connector state to assign 425 * 426 * Initializes the newly allocated @conn_state and assigns it to 427 * the &drm_connector->state pointer of @connector, usually required when 428 * initializing the drivers or when called from the &drm_connector_funcs.reset 429 * hook. 430 * 431 * This is useful for drivers that subclass the connector state. 432 */ 433 void 434 __drm_atomic_helper_connector_reset(struct drm_connector *connector, 435 struct drm_connector_state *conn_state) 436 { 437 if (conn_state) 438 __drm_atomic_helper_connector_state_reset(conn_state, connector); 439 440 connector->state = conn_state; 441 } 442 EXPORT_SYMBOL(__drm_atomic_helper_connector_reset); 443 444 /** 445 * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors 446 * @connector: drm connector 447 * 448 * Resets the atomic state for @connector by freeing the state pointer (which 449 * might be NULL, e.g. at driver load time) and allocating a new empty state 450 * object. 451 */ 452 void drm_atomic_helper_connector_reset(struct drm_connector *connector) 453 { 454 struct drm_connector_state *conn_state = 455 kzalloc(sizeof(*conn_state), GFP_KERNEL); 456 457 if (connector->state) 458 __drm_atomic_helper_connector_destroy_state(connector->state); 459 460 kfree(connector->state); 461 __drm_atomic_helper_connector_reset(connector, conn_state); 462 } 463 EXPORT_SYMBOL(drm_atomic_helper_connector_reset); 464 465 /** 466 * drm_atomic_helper_connector_tv_reset - Resets TV connector properties 467 * @connector: DRM connector 468 * 469 * Resets the TV-related properties attached to a connector. 470 */ 471 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector) 472 { 473 struct drm_cmdline_mode *cmdline = &connector->cmdline_mode; 474 struct drm_connector_state *state = connector->state; 475 476 state->tv.margins.left = cmdline->tv_margins.left; 477 state->tv.margins.right = cmdline->tv_margins.right; 478 state->tv.margins.top = cmdline->tv_margins.top; 479 state->tv.margins.bottom = cmdline->tv_margins.bottom; 480 } 481 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset); 482 483 /** 484 * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state 485 * @connector: connector object 486 * @state: atomic connector state 487 * 488 * Copies atomic state from a connector's current state. This is useful for 489 * drivers that subclass the connector state. 490 */ 491 void 492 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, 493 struct drm_connector_state *state) 494 { 495 memcpy(state, connector->state, sizeof(*state)); 496 if (state->crtc) 497 drm_connector_get(connector); 498 state->commit = NULL; 499 500 if (state->hdr_output_metadata) 501 drm_property_blob_get(state->hdr_output_metadata); 502 503 /* Don't copy over a writeback job, they are used only once */ 504 state->writeback_job = NULL; 505 } 506 EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state); 507 508 /** 509 * drm_atomic_helper_connector_duplicate_state - default state duplicate hook 510 * @connector: drm connector 511 * 512 * Default connector state duplicate hook for drivers which don't have their own 513 * subclassed connector state structure. 514 */ 515 struct drm_connector_state * 516 drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector) 517 { 518 struct drm_connector_state *state; 519 520 if (WARN_ON(!connector->state)) 521 return NULL; 522 523 state = kmalloc(sizeof(*state), GFP_KERNEL); 524 if (state) 525 __drm_atomic_helper_connector_duplicate_state(connector, state); 526 527 return state; 528 } 529 EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state); 530 531 /** 532 * __drm_atomic_helper_connector_destroy_state - release connector state 533 * @state: connector state object to release 534 * 535 * Releases all resources stored in the connector state without actually 536 * freeing the memory of the connector state. This is useful for drivers that 537 * subclass the connector state. 538 */ 539 void 540 __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state) 541 { 542 if (state->crtc) 543 drm_connector_put(state->connector); 544 545 if (state->commit) 546 drm_crtc_commit_put(state->commit); 547 548 if (state->writeback_job) 549 drm_writeback_cleanup_job(state->writeback_job); 550 551 drm_property_blob_put(state->hdr_output_metadata); 552 } 553 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state); 554 555 /** 556 * drm_atomic_helper_connector_destroy_state - default state destroy hook 557 * @connector: drm connector 558 * @state: connector state object to release 559 * 560 * Default connector state destroy hook for drivers which don't have their own 561 * subclassed connector state structure. 562 */ 563 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, 564 struct drm_connector_state *state) 565 { 566 __drm_atomic_helper_connector_destroy_state(state); 567 kfree(state); 568 } 569 EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); 570 571 /** 572 * __drm_atomic_helper_private_obj_duplicate_state - copy atomic private state 573 * @obj: CRTC object 574 * @state: new private object state 575 * 576 * Copies atomic state from a private objects's current state and resets inferred values. 577 * This is useful for drivers that subclass the private state. 578 */ 579 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, 580 struct drm_private_state *state) 581 { 582 memcpy(state, obj->state, sizeof(*state)); 583 } 584 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state); 585 586 /** 587 * __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state 588 * @bridge: bridge object 589 * @state: atomic bridge state 590 * 591 * Copies atomic state from a bridge's current state and resets inferred values. 592 * This is useful for drivers that subclass the bridge state. 593 */ 594 void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, 595 struct drm_bridge_state *state) 596 { 597 __drm_atomic_helper_private_obj_duplicate_state(&bridge->base, 598 &state->base); 599 state->bridge = bridge; 600 } 601 EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state); 602 603 /** 604 * drm_atomic_helper_bridge_duplicate_state() - Duplicate a bridge state object 605 * @bridge: bridge object 606 * 607 * Allocates a new bridge state and initializes it with the current bridge 608 * state values. This helper is meant to be used as a bridge 609 * &drm_bridge_funcs.atomic_duplicate_state hook for bridges that don't 610 * subclass the bridge state. 611 */ 612 struct drm_bridge_state * 613 drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge) 614 { 615 struct drm_bridge_state *new; 616 617 if (WARN_ON(!bridge->base.state)) 618 return NULL; 619 620 new = kzalloc(sizeof(*new), GFP_KERNEL); 621 if (new) 622 __drm_atomic_helper_bridge_duplicate_state(bridge, new); 623 624 return new; 625 } 626 EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state); 627 628 /** 629 * drm_atomic_helper_bridge_destroy_state() - Destroy a bridge state object 630 * @bridge: the bridge this state refers to 631 * @state: bridge state to destroy 632 * 633 * Destroys a bridge state previously created by 634 * &drm_atomic_helper_bridge_reset() or 635 * &drm_atomic_helper_bridge_duplicate_state(). This helper is meant to be 636 * used as a bridge &drm_bridge_funcs.atomic_destroy_state hook for bridges 637 * that don't subclass the bridge state. 638 */ 639 void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, 640 struct drm_bridge_state *state) 641 { 642 kfree(state); 643 } 644 EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state); 645 646 /** 647 * __drm_atomic_helper_bridge_reset() - Initialize a bridge state to its 648 * default 649 * @bridge: the bridge this state refers to 650 * @state: bridge state to initialize 651 * 652 * Initializes the bridge state to default values. This is meant to be called 653 * by the bridge &drm_bridge_funcs.atomic_reset hook for bridges that subclass 654 * the bridge state. 655 */ 656 void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, 657 struct drm_bridge_state *state) 658 { 659 memset(state, 0, sizeof(*state)); 660 state->bridge = bridge; 661 } 662 EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset); 663 664 /** 665 * drm_atomic_helper_bridge_reset() - Allocate and initialize a bridge state 666 * to its default 667 * @bridge: the bridge this state refers to 668 * 669 * Allocates the bridge state and initializes it to default values. This helper 670 * is meant to be used as a bridge &drm_bridge_funcs.atomic_reset hook for 671 * bridges that don't subclass the bridge state. 672 */ 673 struct drm_bridge_state * 674 drm_atomic_helper_bridge_reset(struct drm_bridge *bridge) 675 { 676 struct drm_bridge_state *bridge_state; 677 678 bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL); 679 if (!bridge_state) 680 return ERR_PTR(-ENOMEM); 681 682 __drm_atomic_helper_bridge_reset(bridge, bridge_state); 683 return bridge_state; 684 } 685 EXPORT_SYMBOL(drm_atomic_helper_bridge_reset); 686