diff options
-rw-r--r-- | drivers/gpu/drm/drm_dp_mst_topology.c | 5 | ||||
-rw-r--r-- | include/drm/drm_dp_mst_helper.h | 96 |
2 files changed, 99 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index b5976f8c318c..e3497bc49494 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
@@ -3521,10 +3521,11 @@ static void drm_dp_mst_destroy_state(struct drm_private_obj *obj, | |||
3521 | kfree(mst_state); | 3521 | kfree(mst_state); |
3522 | } | 3522 | } |
3523 | 3523 | ||
3524 | static const struct drm_private_state_funcs mst_state_funcs = { | 3524 | const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs = { |
3525 | .atomic_duplicate_state = drm_dp_mst_duplicate_state, | 3525 | .atomic_duplicate_state = drm_dp_mst_duplicate_state, |
3526 | .atomic_destroy_state = drm_dp_mst_destroy_state, | 3526 | .atomic_destroy_state = drm_dp_mst_destroy_state, |
3527 | }; | 3527 | }; |
3528 | EXPORT_SYMBOL(drm_dp_mst_topology_state_funcs); | ||
3528 | 3529 | ||
3529 | /** | 3530 | /** |
3530 | * drm_atomic_get_mst_topology_state: get MST topology state | 3531 | * drm_atomic_get_mst_topology_state: get MST topology state |
@@ -3608,7 +3609,7 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, | |||
3608 | 3609 | ||
3609 | drm_atomic_private_obj_init(dev, &mgr->base, | 3610 | drm_atomic_private_obj_init(dev, &mgr->base, |
3610 | &mst_state->base, | 3611 | &mst_state->base, |
3611 | &mst_state_funcs); | 3612 | &drm_dp_mst_topology_state_funcs); |
3612 | 3613 | ||
3613 | return 0; | 3614 | return 0; |
3614 | } | 3615 | } |
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 8eca5f29242c..581163c8d7d7 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h | |||
@@ -650,4 +650,100 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, | |||
650 | void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port); | 650 | void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port); |
651 | void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port); | 651 | void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port); |
652 | 652 | ||
653 | extern const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs; | ||
654 | |||
655 | /** | ||
656 | * __drm_dp_mst_state_iter_get - private atomic state iterator function for | ||
657 | * macro-internal use | ||
658 | * @state: &struct drm_atomic_state pointer | ||
659 | * @mgr: pointer to the &struct drm_dp_mst_topology_mgr iteration cursor | ||
660 | * @old_state: optional pointer to the old &struct drm_dp_mst_topology_state | ||
661 | * iteration cursor | ||
662 | * @new_state: optional pointer to the new &struct drm_dp_mst_topology_state | ||
663 | * iteration cursor | ||
664 | * @i: int iteration cursor, for macro-internal use | ||
665 | * | ||
666 | * Used by for_each_oldnew_mst_mgr_in_state(), | ||
667 | * for_each_old_mst_mgr_in_state(), and for_each_new_mst_mgr_in_state(). Don't | ||
668 | * call this directly. | ||
669 | * | ||
670 | * Returns: | ||
671 | * True if the current &struct drm_private_obj is a &struct | ||
672 | * drm_dp_mst_topology_mgr, false otherwise. | ||
673 | */ | ||
674 | static inline bool | ||
675 | __drm_dp_mst_state_iter_get(struct drm_atomic_state *state, | ||
676 | struct drm_dp_mst_topology_mgr **mgr, | ||
677 | struct drm_dp_mst_topology_state **old_state, | ||
678 | struct drm_dp_mst_topology_state **new_state, | ||
679 | int i) | ||
680 | { | ||
681 | struct __drm_private_objs_state *objs_state = &state->private_objs[i]; | ||
682 | |||
683 | if (objs_state->ptr->funcs != &drm_dp_mst_topology_state_funcs) | ||
684 | return false; | ||
685 | |||
686 | *mgr = to_dp_mst_topology_mgr(objs_state->ptr); | ||
687 | if (old_state) | ||
688 | *old_state = to_dp_mst_topology_state(objs_state->old_state); | ||
689 | if (new_state) | ||
690 | *new_state = to_dp_mst_topology_state(objs_state->new_state); | ||
691 | |||
692 | return true; | ||
693 | } | ||
694 | |||
695 | /** | ||
696 | * for_each_oldnew_mst_mgr_in_state - iterate over all DP MST topology | ||
697 | * managers in an atomic update | ||
698 | * @__state: &struct drm_atomic_state pointer | ||
699 | * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor | ||
700 | * @old_state: &struct drm_dp_mst_topology_state iteration cursor for the old | ||
701 | * state | ||
702 | * @new_state: &struct drm_dp_mst_topology_state iteration cursor for the new | ||
703 | * state | ||
704 | * @__i: int iteration cursor, for macro-internal use | ||
705 | * | ||
706 | * This iterates over all DRM DP MST topology managers in an atomic update, | ||
707 | * tracking both old and new state. This is useful in places where the state | ||
708 | * delta needs to be considered, for example in atomic check functions. | ||
709 | */ | ||
710 | #define for_each_oldnew_mst_mgr_in_state(__state, mgr, old_state, new_state, __i) \ | ||
711 | for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \ | ||
712 | for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), &(old_state), &(new_state), (__i))) | ||
713 | |||
714 | /** | ||
715 | * for_each_old_mst_mgr_in_state - iterate over all DP MST topology managers | ||
716 | * in an atomic update | ||
717 | * @__state: &struct drm_atomic_state pointer | ||
718 | * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor | ||
719 | * @old_state: &struct drm_dp_mst_topology_state iteration cursor for the old | ||
720 | * state | ||
721 | * @__i: int iteration cursor, for macro-internal use | ||
722 | * | ||
723 | * This iterates over all DRM DP MST topology managers in an atomic update, | ||
724 | * tracking only the old state. This is useful in disable functions, where we | ||
725 | * need the old state the hardware is still in. | ||
726 | */ | ||
727 | #define for_each_old_mst_mgr_in_state(__state, mgr, old_state, __i) \ | ||
728 | for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \ | ||
729 | for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), &(old_state), NULL, (__i))) | ||
730 | |||
731 | /** | ||
732 | * for_each_new_mst_mgr_in_state - iterate over all DP MST topology managers | ||
733 | * in an atomic update | ||
734 | * @__state: &struct drm_atomic_state pointer | ||
735 | * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor | ||
736 | * @new_state: &struct drm_dp_mst_topology_state iteration cursor for the new | ||
737 | * state | ||
738 | * @__i: int iteration cursor, for macro-internal use | ||
739 | * | ||
740 | * This iterates over all DRM DP MST topology managers in an atomic update, | ||
741 | * tracking only the new state. This is useful in enable functions, where we | ||
742 | * need the new state the hardware should be in when the atomic commit | ||
743 | * operation has completed. | ||
744 | */ | ||
745 | #define for_each_new_mst_mgr_in_state(__state, mgr, new_state, __i) \ | ||
746 | for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \ | ||
747 | for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), NULL, &(new_state), (__i))) | ||
748 | |||
653 | #endif | 749 | #endif |