diff options
Diffstat (limited to 'include/drm/drm_dp_mst_helper.h')
-rw-r--r-- | include/drm/drm_dp_mst_helper.h | 151 |
1 files changed, 140 insertions, 11 deletions
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 371cc2816477..451d020f0137 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h | |||
@@ -44,7 +44,6 @@ struct drm_dp_vcpi { | |||
44 | 44 | ||
45 | /** | 45 | /** |
46 | * struct drm_dp_mst_port - MST port | 46 | * struct drm_dp_mst_port - MST port |
47 | * @kref: reference count for this port. | ||
48 | * @port_num: port number | 47 | * @port_num: port number |
49 | * @input: if this port is an input port. | 48 | * @input: if this port is an input port. |
50 | * @mcs: message capability status - DP 1.2 spec. | 49 | * @mcs: message capability status - DP 1.2 spec. |
@@ -67,7 +66,18 @@ struct drm_dp_vcpi { | |||
67 | * in the MST topology. | 66 | * in the MST topology. |
68 | */ | 67 | */ |
69 | struct drm_dp_mst_port { | 68 | struct drm_dp_mst_port { |
70 | struct kref kref; | 69 | /** |
70 | * @topology_kref: refcount for this port's lifetime in the topology, | ||
71 | * only the DP MST helpers should need to touch this | ||
72 | */ | ||
73 | struct kref topology_kref; | ||
74 | |||
75 | /** | ||
76 | * @malloc_kref: refcount for the memory allocation containing this | ||
77 | * structure. See drm_dp_mst_get_port_malloc() and | ||
78 | * drm_dp_mst_put_port_malloc(). | ||
79 | */ | ||
80 | struct kref malloc_kref; | ||
71 | 81 | ||
72 | u8 port_num; | 82 | u8 port_num; |
73 | bool input; | 83 | bool input; |
@@ -102,7 +112,6 @@ struct drm_dp_mst_port { | |||
102 | 112 | ||
103 | /** | 113 | /** |
104 | * struct drm_dp_mst_branch - MST branch device. | 114 | * struct drm_dp_mst_branch - MST branch device. |
105 | * @kref: reference count for this port. | ||
106 | * @rad: Relative Address to talk to this branch device. | 115 | * @rad: Relative Address to talk to this branch device. |
107 | * @lct: Link count total to talk to this branch device. | 116 | * @lct: Link count total to talk to this branch device. |
108 | * @num_ports: number of ports on the branch. | 117 | * @num_ports: number of ports on the branch. |
@@ -121,7 +130,19 @@ struct drm_dp_mst_port { | |||
121 | * to downstream port of parent branches. | 130 | * to downstream port of parent branches. |
122 | */ | 131 | */ |
123 | struct drm_dp_mst_branch { | 132 | struct drm_dp_mst_branch { |
124 | struct kref kref; | 133 | /** |
134 | * @topology_kref: refcount for this branch device's lifetime in the | ||
135 | * topology, only the DP MST helpers should need to touch this | ||
136 | */ | ||
137 | struct kref topology_kref; | ||
138 | |||
139 | /** | ||
140 | * @malloc_kref: refcount for the memory allocation containing this | ||
141 | * structure. See drm_dp_mst_get_mstb_malloc() and | ||
142 | * drm_dp_mst_put_mstb_malloc(). | ||
143 | */ | ||
144 | struct kref malloc_kref; | ||
145 | |||
125 | u8 rad[8]; | 146 | u8 rad[8]; |
126 | u8 lct; | 147 | u8 lct; |
127 | int num_ports; | 148 | int num_ports; |
@@ -404,9 +425,15 @@ struct drm_dp_payload { | |||
404 | 425 | ||
405 | #define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base) | 426 | #define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base) |
406 | 427 | ||
428 | struct drm_dp_vcpi_allocation { | ||
429 | struct drm_dp_mst_port *port; | ||
430 | int vcpi; | ||
431 | struct list_head next; | ||
432 | }; | ||
433 | |||
407 | struct drm_dp_mst_topology_state { | 434 | struct drm_dp_mst_topology_state { |
408 | struct drm_private_state base; | 435 | struct drm_private_state base; |
409 | int avail_slots; | 436 | struct list_head vcpis; |
410 | struct drm_dp_mst_topology_mgr *mgr; | 437 | struct drm_dp_mst_topology_mgr *mgr; |
411 | }; | 438 | }; |
412 | 439 | ||
@@ -617,13 +644,115 @@ void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr); | |||
617 | int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr); | 644 | int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr); |
618 | struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, | 645 | struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, |
619 | struct drm_dp_mst_topology_mgr *mgr); | 646 | struct drm_dp_mst_topology_mgr *mgr); |
620 | int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, | 647 | int __must_check |
621 | struct drm_dp_mst_topology_mgr *mgr, | 648 | drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, |
622 | struct drm_dp_mst_port *port, int pbn); | 649 | struct drm_dp_mst_topology_mgr *mgr, |
623 | int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, | 650 | struct drm_dp_mst_port *port, int pbn); |
624 | struct drm_dp_mst_topology_mgr *mgr, | 651 | int __must_check |
625 | int slots); | 652 | drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, |
653 | struct drm_dp_mst_topology_mgr *mgr, | ||
654 | struct drm_dp_mst_port *port); | ||
626 | int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, | 655 | int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, |
627 | struct drm_dp_mst_port *port, bool power_up); | 656 | struct drm_dp_mst_port *port, bool power_up); |
657 | int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state); | ||
658 | |||
659 | void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port); | ||
660 | void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port); | ||
661 | |||
662 | extern const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs; | ||
663 | |||
664 | /** | ||
665 | * __drm_dp_mst_state_iter_get - private atomic state iterator function for | ||
666 | * macro-internal use | ||
667 | * @state: &struct drm_atomic_state pointer | ||
668 | * @mgr: pointer to the &struct drm_dp_mst_topology_mgr iteration cursor | ||
669 | * @old_state: optional pointer to the old &struct drm_dp_mst_topology_state | ||
670 | * iteration cursor | ||
671 | * @new_state: optional pointer to the new &struct drm_dp_mst_topology_state | ||
672 | * iteration cursor | ||
673 | * @i: int iteration cursor, for macro-internal use | ||
674 | * | ||
675 | * Used by for_each_oldnew_mst_mgr_in_state(), | ||
676 | * for_each_old_mst_mgr_in_state(), and for_each_new_mst_mgr_in_state(). Don't | ||
677 | * call this directly. | ||
678 | * | ||
679 | * Returns: | ||
680 | * True if the current &struct drm_private_obj is a &struct | ||
681 | * drm_dp_mst_topology_mgr, false otherwise. | ||
682 | */ | ||
683 | static inline bool | ||
684 | __drm_dp_mst_state_iter_get(struct drm_atomic_state *state, | ||
685 | struct drm_dp_mst_topology_mgr **mgr, | ||
686 | struct drm_dp_mst_topology_state **old_state, | ||
687 | struct drm_dp_mst_topology_state **new_state, | ||
688 | int i) | ||
689 | { | ||
690 | struct __drm_private_objs_state *objs_state = &state->private_objs[i]; | ||
691 | |||
692 | if (objs_state->ptr->funcs != &drm_dp_mst_topology_state_funcs) | ||
693 | return false; | ||
694 | |||
695 | *mgr = to_dp_mst_topology_mgr(objs_state->ptr); | ||
696 | if (old_state) | ||
697 | *old_state = to_dp_mst_topology_state(objs_state->old_state); | ||
698 | if (new_state) | ||
699 | *new_state = to_dp_mst_topology_state(objs_state->new_state); | ||
700 | |||
701 | return true; | ||
702 | } | ||
703 | |||
704 | /** | ||
705 | * for_each_oldnew_mst_mgr_in_state - iterate over all DP MST topology | ||
706 | * managers in an atomic update | ||
707 | * @__state: &struct drm_atomic_state pointer | ||
708 | * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor | ||
709 | * @old_state: &struct drm_dp_mst_topology_state iteration cursor for the old | ||
710 | * state | ||
711 | * @new_state: &struct drm_dp_mst_topology_state iteration cursor for the new | ||
712 | * state | ||
713 | * @__i: int iteration cursor, for macro-internal use | ||
714 | * | ||
715 | * This iterates over all DRM DP MST topology managers in an atomic update, | ||
716 | * tracking both old and new state. This is useful in places where the state | ||
717 | * delta needs to be considered, for example in atomic check functions. | ||
718 | */ | ||
719 | #define for_each_oldnew_mst_mgr_in_state(__state, mgr, old_state, new_state, __i) \ | ||
720 | for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \ | ||
721 | for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), &(old_state), &(new_state), (__i))) | ||
722 | |||
723 | /** | ||
724 | * for_each_old_mst_mgr_in_state - iterate over all DP MST topology managers | ||
725 | * in an atomic update | ||
726 | * @__state: &struct drm_atomic_state pointer | ||
727 | * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor | ||
728 | * @old_state: &struct drm_dp_mst_topology_state iteration cursor for the old | ||
729 | * state | ||
730 | * @__i: int iteration cursor, for macro-internal use | ||
731 | * | ||
732 | * This iterates over all DRM DP MST topology managers in an atomic update, | ||
733 | * tracking only the old state. This is useful in disable functions, where we | ||
734 | * need the old state the hardware is still in. | ||
735 | */ | ||
736 | #define for_each_old_mst_mgr_in_state(__state, mgr, old_state, __i) \ | ||
737 | for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \ | ||
738 | for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), &(old_state), NULL, (__i))) | ||
739 | |||
740 | /** | ||
741 | * for_each_new_mst_mgr_in_state - iterate over all DP MST topology managers | ||
742 | * in an atomic update | ||
743 | * @__state: &struct drm_atomic_state pointer | ||
744 | * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor | ||
745 | * @new_state: &struct drm_dp_mst_topology_state iteration cursor for the new | ||
746 | * state | ||
747 | * @__i: int iteration cursor, for macro-internal use | ||
748 | * | ||
749 | * This iterates over all DRM DP MST topology managers in an atomic update, | ||
750 | * tracking only the new state. This is useful in enable functions, where we | ||
751 | * need the new state the hardware should be in when the atomic commit | ||
752 | * operation has completed. | ||
753 | */ | ||
754 | #define for_each_new_mst_mgr_in_state(__state, mgr, new_state, __i) \ | ||
755 | for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \ | ||
756 | for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), NULL, &(new_state), (__i))) | ||
628 | 757 | ||
629 | #endif | 758 | #endif |