Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/bridge: Add a drm_bridge_state object

One of the last remaining objects to not have its atomic state.

This is being motivated by our attempt to support runtime bus-format
negotiation between elements of the bridge chain.
This patch just paves the road for such a feature by adding a new
drm_bridge_state object inheriting from drm_private_obj so we can
re-use some of the existing state initialization/tracking logic.

v10:
* Add changelog to the commit message

v9:
* Clarify the fact that the bridge->atomic_reset() and
{connector,plane,crtc,...}->reset() semantics are different
* Move the drm_atomic_private_obj_init() call back to
drm_bridge_attach()
* Check the presence of ->atomic_duplicate_state instead of
->atomic_reset in drm_atomic_add_encoder_bridges()
* Fix copy&paste errors in the atomic bridge state helpers doc
* Add A-b/R-b tags

v8:
* Move bridge state helpers out of the CONFIG_DEBUGFS section

v7:
* Move helpers, struct-defs, ... to atomic helper files to avoid the
drm -> drm_kms_helper -> drm circular dep
* Stop providing default implementation for atomic state reset,
duplicate and destroy hooks (has to do with the helper/core split)
* Drop all R-b/T-b as helpers have now be moved to other places

v6:
* Made helpers private, removed doc and moved them to satisfy dependencies
* Renamed helpers to _default_

v5:
* Re-introduced the helpers from v4

v4:
* Fix the doc
* Kill default helpers (inlined)
* Fix drm_atomic_get_bridge_state() to check for an ERR_PTR()
* Add Neil's R-b

v3:
* No changes

v2:
* Use drm_for_each_bridge_in_chain()
* Rename helpers to be more consistent with the rest of the DRM API
* Improve/fix the doc

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-2-boris.brezillon@collabora.com

+400 -5
+116
drivers/gpu/drm/drm_atomic.c
··· 30 30 31 31 #include <drm/drm_atomic.h> 32 32 #include <drm/drm_atomic_uapi.h> 33 + #include <drm/drm_bridge.h> 33 34 #include <drm/drm_debugfs.h> 34 35 #include <drm/drm_device.h> 35 36 #include <drm/drm_drv.h> ··· 1017 1016 if (connector->funcs->atomic_print_state) 1018 1017 connector->funcs->atomic_print_state(p, state); 1019 1018 } 1019 + 1020 + /** 1021 + * drm_atomic_get_bridge_state - get bridge state 1022 + * @state: global atomic state object 1023 + * @bridge: bridge to get state object for 1024 + * 1025 + * This function returns the bridge state for the given bridge, allocating it 1026 + * if needed. It will also grab the relevant bridge lock to make sure that the 1027 + * state is consistent. 1028 + * 1029 + * Returns: 1030 + * 1031 + * Either the allocated state or the error code encoded into the pointer. When 1032 + * the error is EDEADLK then the w/w mutex code has detected a deadlock and the 1033 + * entire atomic sequence must be restarted. 1034 + */ 1035 + struct drm_bridge_state * 1036 + drm_atomic_get_bridge_state(struct drm_atomic_state *state, 1037 + struct drm_bridge *bridge) 1038 + { 1039 + struct drm_private_state *obj_state; 1040 + 1041 + obj_state = drm_atomic_get_private_obj_state(state, &bridge->base); 1042 + if (IS_ERR(obj_state)) 1043 + return ERR_CAST(obj_state); 1044 + 1045 + return drm_priv_to_bridge_state(obj_state); 1046 + } 1047 + EXPORT_SYMBOL(drm_atomic_get_bridge_state); 1048 + 1049 + /** 1050 + * drm_atomic_get_old_bridge_state - get old bridge state, if it exists 1051 + * @state: global atomic state object 1052 + * @bridge: bridge to grab 1053 + * 1054 + * This function returns the old bridge state for the given bridge, or NULL if 1055 + * the bridge is not part of the global atomic state. 1056 + */ 1057 + struct drm_bridge_state * 1058 + drm_atomic_get_old_bridge_state(struct drm_atomic_state *state, 1059 + struct drm_bridge *bridge) 1060 + { 1061 + struct drm_private_state *obj_state; 1062 + 1063 + obj_state = drm_atomic_get_old_private_obj_state(state, &bridge->base); 1064 + if (!obj_state) 1065 + return NULL; 1066 + 1067 + return drm_priv_to_bridge_state(obj_state); 1068 + } 1069 + EXPORT_SYMBOL(drm_atomic_get_old_bridge_state); 1070 + 1071 + /** 1072 + * drm_atomic_get_new_bridge_state - get new bridge state, if it exists 1073 + * @state: global atomic state object 1074 + * @bridge: bridge to grab 1075 + * 1076 + * This function returns the new bridge state for the given bridge, or NULL if 1077 + * the bridge is not part of the global atomic state. 1078 + */ 1079 + struct drm_bridge_state * 1080 + drm_atomic_get_new_bridge_state(struct drm_atomic_state *state, 1081 + struct drm_bridge *bridge) 1082 + { 1083 + struct drm_private_state *obj_state; 1084 + 1085 + obj_state = drm_atomic_get_new_private_obj_state(state, &bridge->base); 1086 + if (!obj_state) 1087 + return NULL; 1088 + 1089 + return drm_priv_to_bridge_state(obj_state); 1090 + } 1091 + EXPORT_SYMBOL(drm_atomic_get_new_bridge_state); 1092 + 1093 + /** 1094 + * drm_atomic_add_encoder_bridges - add bridges attached to an encoder 1095 + * @state: atomic state 1096 + * @encoder: DRM encoder 1097 + * 1098 + * This function adds all bridges attached to @encoder. This is needed to add 1099 + * bridge states to @state and make them available when 1100 + * &bridge_funcs.atomic_{check,pre_enable,enable,disable_post_disable}() are 1101 + * called 1102 + * 1103 + * Returns: 1104 + * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK 1105 + * then the w/w mutex code has detected a deadlock and the entire atomic 1106 + * sequence must be restarted. All other errors are fatal. 1107 + */ 1108 + int 1109 + drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, 1110 + struct drm_encoder *encoder) 1111 + { 1112 + struct drm_bridge_state *bridge_state; 1113 + struct drm_bridge *bridge; 1114 + 1115 + if (!encoder) 1116 + return 0; 1117 + 1118 + DRM_DEBUG_ATOMIC("Adding all bridges for [encoder:%d:%s] to %p\n", 1119 + encoder->base.id, encoder->name, state); 1120 + 1121 + drm_for_each_bridge_in_chain(encoder, bridge) { 1122 + /* Skip bridges that don't implement the atomic state hooks. */ 1123 + if (!bridge->funcs->atomic_duplicate_state) 1124 + continue; 1125 + 1126 + bridge_state = drm_atomic_get_bridge_state(state, bridge); 1127 + if (IS_ERR(bridge_state)) 1128 + return PTR_ERR(bridge_state); 1129 + } 1130 + 1131 + return 0; 1132 + } 1133 + EXPORT_SYMBOL(drm_atomic_add_encoder_bridges); 1020 1134 1021 1135 /** 1022 1136 * drm_atomic_add_affected_connectors - add connectors for CRTC
+20
drivers/gpu/drm/drm_atomic_helper.c
··· 736 736 return ret; 737 737 } 738 738 739 + /* 740 + * Iterate over all connectors again, and add all affected bridges to 741 + * the state. 742 + */ 743 + for_each_oldnew_connector_in_state(state, connector, 744 + old_connector_state, 745 + new_connector_state, i) { 746 + struct drm_encoder *encoder; 747 + 748 + encoder = old_connector_state->best_encoder; 749 + ret = drm_atomic_add_encoder_bridges(state, encoder); 750 + if (ret) 751 + return ret; 752 + 753 + encoder = new_connector_state->best_encoder; 754 + ret = drm_atomic_add_encoder_bridges(state, encoder); 755 + if (ret) 756 + return ret; 757 + } 758 + 739 759 ret = mode_valid(state); 740 760 if (ret) 741 761 return ret;
+103
drivers/gpu/drm/drm_atomic_state_helper.c
··· 26 26 27 27 #include <drm/drm_atomic.h> 28 28 #include <drm/drm_atomic_state_helper.h> 29 + #include <drm/drm_bridge.h> 29 30 #include <drm/drm_connector.h> 30 31 #include <drm/drm_crtc.h> 31 32 #include <drm/drm_device.h> ··· 552 551 memcpy(state, obj->state, sizeof(*state)); 553 552 } 554 553 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state); 554 + 555 + /** 556 + * __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state 557 + * @bridge: bridge object 558 + * @state: atomic bridge state 559 + * 560 + * Copies atomic state from a bridge's current state and resets inferred values. 561 + * This is useful for drivers that subclass the bridge state. 562 + */ 563 + void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, 564 + struct drm_bridge_state *state) 565 + { 566 + __drm_atomic_helper_private_obj_duplicate_state(&bridge->base, 567 + &state->base); 568 + state->bridge = bridge; 569 + } 570 + EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state); 571 + 572 + /** 573 + * drm_atomic_helper_bridge_duplicate_state() - Duplicate a bridge state object 574 + * @bridge: bridge object 575 + * 576 + * Allocates a new bridge state and initializes it with the current bridge 577 + * state values. This helper is meant to be used as a bridge 578 + * &drm_bridge_funcs.atomic_duplicate_state hook for bridges that don't 579 + * subclass the bridge state. 580 + */ 581 + struct drm_bridge_state * 582 + drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge) 583 + { 584 + struct drm_bridge_state *new; 585 + 586 + if (WARN_ON(!bridge->base.state)) 587 + return NULL; 588 + 589 + new = kzalloc(sizeof(*new), GFP_KERNEL); 590 + if (new) 591 + __drm_atomic_helper_bridge_duplicate_state(bridge, new); 592 + 593 + return new; 594 + } 595 + EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state); 596 + 597 + /** 598 + * drm_atomic_helper_bridge_destroy_state() - Destroy a bridge state object 599 + * @bridge: the bridge this state refers to 600 + * @state: bridge state to destroy 601 + * 602 + * Destroys a bridge state previously created by 603 + * &drm_atomic_helper_bridge_reset() or 604 + * &drm_atomic_helper_bridge_duplicate_state(). This helper is meant to be 605 + * used as a bridge &drm_bridge_funcs.atomic_destroy_state hook for bridges 606 + * that don't subclass the bridge state. 607 + */ 608 + void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, 609 + struct drm_bridge_state *state) 610 + { 611 + kfree(state); 612 + } 613 + EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state); 614 + 615 + /** 616 + * __drm_atomic_helper_bridge_reset() - Initialize a bridge state to its 617 + * default 618 + * @bridge: the bridge this state refers to 619 + * @state: bridge state to initialize 620 + * 621 + * Initializes the bridge state to default values. This is meant to be called 622 + * by the bridge &drm_bridge_funcs.atomic_reset hook for bridges that subclass 623 + * the bridge state. 624 + */ 625 + void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, 626 + struct drm_bridge_state *state) 627 + { 628 + memset(state, 0, sizeof(*state)); 629 + state->bridge = bridge; 630 + } 631 + EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset); 632 + 633 + /** 634 + * drm_atomic_helper_bridge_reset() - Allocate and initialize a bridge state 635 + * to its default 636 + * @bridge: the bridge this state refers to 637 + * @state: bridge state to initialize 638 + * 639 + * Allocates the bridge state and initializes it to default values. This helper 640 + * is meant to be used as a bridge &drm_bridge_funcs.atomic_reset hook for 641 + * bridges that don't subclass the bridge state. 642 + */ 643 + struct drm_bridge_state * 644 + drm_atomic_helper_bridge_reset(struct drm_bridge *bridge) 645 + { 646 + struct drm_bridge_state *bridge_state; 647 + 648 + bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL); 649 + if (!bridge_state) 650 + return ERR_PTR(-ENOMEM); 651 + 652 + __drm_atomic_helper_bridge_reset(bridge, bridge_state); 653 + return bridge_state; 654 + } 655 + EXPORT_SYMBOL(drm_atomic_helper_bridge_reset);
+54 -5
drivers/gpu/drm/drm_bridge.c
··· 25 25 #include <linux/module.h> 26 26 #include <linux/mutex.h> 27 27 28 + #include <drm/drm_atomic_state_helper.h> 28 29 #include <drm/drm_bridge.h> 29 30 #include <drm/drm_encoder.h> 30 31 ··· 90 89 } 91 90 EXPORT_SYMBOL(drm_bridge_remove); 92 91 92 + static struct drm_private_state * 93 + drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj) 94 + { 95 + struct drm_bridge *bridge = drm_priv_to_bridge(obj); 96 + struct drm_bridge_state *state; 97 + 98 + state = bridge->funcs->atomic_duplicate_state(bridge); 99 + return state ? &state->base : NULL; 100 + } 101 + 102 + static void 103 + drm_bridge_atomic_destroy_priv_state(struct drm_private_obj *obj, 104 + struct drm_private_state *s) 105 + { 106 + struct drm_bridge_state *state = drm_priv_to_bridge_state(s); 107 + struct drm_bridge *bridge = drm_priv_to_bridge(obj); 108 + 109 + bridge->funcs->atomic_destroy_state(bridge, state); 110 + } 111 + 112 + static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = { 113 + .atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state, 114 + .atomic_destroy_state = drm_bridge_atomic_destroy_priv_state, 115 + }; 116 + 93 117 /** 94 118 * drm_bridge_attach - attach the bridge to an encoder's chain 95 119 * ··· 161 135 162 136 if (bridge->funcs->attach) { 163 137 ret = bridge->funcs->attach(bridge); 164 - if (ret < 0) { 165 - list_del(&bridge->chain_node); 166 - bridge->dev = NULL; 167 - bridge->encoder = NULL; 168 - return ret; 138 + if (ret < 0) 139 + goto err_reset_bridge; 140 + } 141 + 142 + if (bridge->funcs->atomic_reset) { 143 + struct drm_bridge_state *state; 144 + 145 + state = bridge->funcs->atomic_reset(bridge); 146 + if (IS_ERR(state)) { 147 + ret = PTR_ERR(state); 148 + goto err_detach_bridge; 169 149 } 150 + 151 + drm_atomic_private_obj_init(bridge->dev, &bridge->base, 152 + &state->base, 153 + &drm_bridge_priv_state_funcs); 170 154 } 171 155 172 156 return 0; 157 + 158 + err_detach_bridge: 159 + if (bridge->funcs->detach) 160 + bridge->funcs->detach(bridge); 161 + 162 + err_reset_bridge: 163 + bridge->dev = NULL; 164 + bridge->encoder = NULL; 165 + list_del(&bridge->chain_node); 166 + return ret; 173 167 } 174 168 EXPORT_SYMBOL(drm_bridge_attach); 175 169 ··· 200 154 201 155 if (WARN_ON(!bridge->dev)) 202 156 return; 157 + 158 + if (bridge->funcs->atomic_reset) 159 + drm_atomic_private_obj_fini(&bridge->base); 203 160 204 161 if (bridge->funcs->detach) 205 162 bridge->funcs->detach(bridge);
+34
include/drm/drm_atomic.h
··· 670 670 } 671 671 672 672 int __must_check 673 + drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, 674 + struct drm_encoder *encoder); 675 + int __must_check 673 676 drm_atomic_add_affected_connectors(struct drm_atomic_state *state, 674 677 struct drm_crtc *crtc); 675 678 int __must_check ··· 994 991 { 995 992 return state->active || state->self_refresh_active; 996 993 } 994 + 995 + /** 996 + * struct drm_bridge_state - Atomic bridge state object 997 + */ 998 + struct drm_bridge_state { 999 + /** 1000 + * @base: inherit from &drm_private_state 1001 + */ 1002 + struct drm_private_state base; 1003 + 1004 + /** 1005 + * @bridge: the bridge this state refers to 1006 + */ 1007 + struct drm_bridge *bridge; 1008 + }; 1009 + 1010 + static inline struct drm_bridge_state * 1011 + drm_priv_to_bridge_state(struct drm_private_state *priv) 1012 + { 1013 + return container_of(priv, struct drm_bridge_state, base); 1014 + } 1015 + 1016 + struct drm_bridge_state * 1017 + drm_atomic_get_bridge_state(struct drm_atomic_state *state, 1018 + struct drm_bridge *bridge); 1019 + struct drm_bridge_state * 1020 + drm_atomic_get_old_bridge_state(struct drm_atomic_state *state, 1021 + struct drm_bridge *bridge); 1022 + struct drm_bridge_state * 1023 + drm_atomic_get_new_bridge_state(struct drm_atomic_state *state, 1024 + struct drm_bridge *bridge); 997 1025 998 1026 #endif /* DRM_ATOMIC_H_ */
+13
include/drm/drm_atomic_state_helper.h
··· 26 26 27 27 #include <linux/types.h> 28 28 29 + struct drm_bridge; 30 + struct drm_bridge_state; 29 31 struct drm_crtc; 30 32 struct drm_crtc_state; 31 33 struct drm_plane; ··· 82 80 struct drm_connector_state *state); 83 81 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, 84 82 struct drm_private_state *state); 83 + 84 + void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, 85 + struct drm_bridge_state *state); 86 + struct drm_bridge_state * 87 + drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge); 88 + void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, 89 + struct drm_bridge_state *state); 90 + void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, 91 + struct drm_bridge_state *state); 92 + struct drm_bridge_state * 93 + drm_atomic_helper_bridge_reset(struct drm_bridge *bridge);
+60
include/drm/drm_bridge.h
··· 25 25 26 26 #include <linux/list.h> 27 27 #include <linux/ctype.h> 28 + 29 + #include <drm/drm_atomic.h> 28 30 #include <drm/drm_encoder.h> 29 31 #include <drm/drm_mode_object.h> 30 32 #include <drm/drm_modes.h> ··· 340 338 */ 341 339 void (*atomic_post_disable)(struct drm_bridge *bridge, 342 340 struct drm_atomic_state *old_state); 341 + 342 + /** 343 + * @atomic_duplicate_state: 344 + * 345 + * Duplicate the current bridge state object (which is guaranteed to be 346 + * non-NULL). 347 + * 348 + * The atomic_duplicate_state() is optional. When not implemented the 349 + * core allocates a drm_bridge_state object and calls 350 + * &__drm_atomic_helper_bridge_duplicate_state() to initialize it. 351 + * 352 + * RETURNS: 353 + * A valid drm_bridge_state object or NULL if the allocation fails. 354 + */ 355 + struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge); 356 + 357 + /** 358 + * @atomic_destroy_state: 359 + * 360 + * Destroy a bridge state object previously allocated by 361 + * &drm_bridge_funcs.atomic_duplicate_state(). 362 + * 363 + * The atomic_destroy_state hook is optional. When not implemented the 364 + * core calls kfree() on the state. 365 + */ 366 + void (*atomic_destroy_state)(struct drm_bridge *bridge, 367 + struct drm_bridge_state *state); 368 + 369 + /** 370 + * @atomic_reset: 371 + * 372 + * Reset the bridge to a predefined state (or retrieve its current 373 + * state) and return a &drm_bridge_state object matching this state. 374 + * This function is called at attach time. 375 + * 376 + * The atomic_reset hook is mandatory if the bridge implements any of 377 + * the atomic hooks, and should be left unassigned otherwise. 378 + * 379 + * Note that the atomic_reset() semantics is not exactly matching the 380 + * reset() semantics found on other components (connector, plane, ...). 381 + * 1/ The reset operation happens when the bridge is attached, not when 382 + * drm_mode_config_reset() is called 383 + * 2/ It's meant to be used exclusively on bridges that have been 384 + * converted to the ATOMIC API 385 + * 386 + * RETURNS: 387 + * A valid drm_bridge_state object in case of success, an ERR_PTR() 388 + * giving the reason of the failure otherwise. 389 + */ 390 + struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge); 343 391 }; 344 392 345 393 /** ··· 432 380 * struct drm_bridge - central DRM bridge control structure 433 381 */ 434 382 struct drm_bridge { 383 + /** @base: inherit from &drm_private_object */ 384 + struct drm_private_obj base; 435 385 /** @dev: DRM device this bridge belongs to */ 436 386 struct drm_device *dev; 437 387 /** @encoder: encoder to which this bridge is connected */ ··· 457 403 /** @driver_private: pointer to the bridge driver's internal context */ 458 404 void *driver_private; 459 405 }; 406 + 407 + static inline struct drm_bridge * 408 + drm_priv_to_bridge(struct drm_private_obj *priv) 409 + { 410 + return container_of(priv, struct drm_bridge, base); 411 + } 460 412 461 413 void drm_bridge_add(struct drm_bridge *bridge); 462 414 void drm_bridge_remove(struct drm_bridge *bridge);