aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c247
-rw-r--r--drivers/gpu/drm/i915/intel_display.c4
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c54
-rw-r--r--include/drm/drm_dp_mst_helper.h23
4 files changed, 266 insertions, 62 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index e3497bc49494..88db6d7e1a36 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3011,21 +3011,42 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
3011} 3011}
3012 3012
3013/** 3013/**
3014 * drm_dp_atomic_find_vcpi_slots() - Find and add vcpi slots to the state 3014 * drm_dp_atomic_find_vcpi_slots() - Find and add VCPI slots to the state
3015 * @state: global atomic state 3015 * @state: global atomic state
3016 * @mgr: MST topology manager for the port 3016 * @mgr: MST topology manager for the port
3017 * @port: port to find vcpi slots for 3017 * @port: port to find vcpi slots for
3018 * @pbn: bandwidth required for the mode in PBN 3018 * @pbn: bandwidth required for the mode in PBN
3019 * 3019 *
3020 * RETURNS: 3020 * Allocates VCPI slots to @port, replacing any previous VCPI allocations it
3021 * Total slots in the atomic state assigned for this port or error 3021 * may have had. Any atomic drivers which support MST must call this function
3022 * in their &drm_encoder_helper_funcs.atomic_check() callback to change the
3023 * current VCPI allocation for the new state, but only when
3024 * &drm_crtc_state.mode_changed or &drm_crtc_state.connectors_changed is set
3025 * to ensure compatibility with userspace applications that still use the
3026 * legacy modesetting UAPI.
3027 *
3028 * Allocations set by this function are not checked against the bandwidth
3029 * restraints of @mgr until the driver calls drm_dp_mst_atomic_check().
3030 *
3031 * Additionally, it is OK to call this function multiple times on the same
3032 * @port as needed. It is not OK however, to call this function and
3033 * drm_dp_atomic_release_vcpi_slots() in the same atomic check phase.
3034 *
3035 * See also:
3036 * drm_dp_atomic_release_vcpi_slots()
3037 * drm_dp_mst_atomic_check()
3038 *
3039 * Returns:
3040 * Total slots in the atomic state assigned for this port, or a negative error
3041 * code if the port no longer exists
3022 */ 3042 */
3023int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, 3043int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
3024 struct drm_dp_mst_topology_mgr *mgr, 3044 struct drm_dp_mst_topology_mgr *mgr,
3025 struct drm_dp_mst_port *port, int pbn) 3045 struct drm_dp_mst_port *port, int pbn)
3026{ 3046{
3027 struct drm_dp_mst_topology_state *topology_state; 3047 struct drm_dp_mst_topology_state *topology_state;
3028 int req_slots; 3048 struct drm_dp_vcpi_allocation *pos, *vcpi = NULL;
3049 int prev_slots, req_slots, ret;
3029 3050
3030 topology_state = drm_atomic_get_mst_topology_state(state, mgr); 3051 topology_state = drm_atomic_get_mst_topology_state(state, mgr);
3031 if (IS_ERR(topology_state)) 3052 if (IS_ERR(topology_state))
@@ -3034,20 +3055,54 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
3034 port = drm_dp_mst_topology_get_port_validated(mgr, port); 3055 port = drm_dp_mst_topology_get_port_validated(mgr, port);
3035 if (port == NULL) 3056 if (port == NULL)
3036 return -EINVAL; 3057 return -EINVAL;
3037 req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
3038 DRM_DEBUG_KMS("vcpi slots req=%d, avail=%d\n",
3039 req_slots, topology_state->avail_slots);
3040 3058
3041 if (req_slots > topology_state->avail_slots) { 3059 /* Find the current allocation for this port, if any */
3042 drm_dp_mst_topology_put_port(port); 3060 list_for_each_entry(pos, &topology_state->vcpis, next) {
3043 return -ENOSPC; 3061 if (pos->port == port) {
3062 vcpi = pos;
3063 prev_slots = vcpi->vcpi;
3064
3065 /*
3066 * This should never happen, unless the driver tries
3067 * releasing and allocating the same VCPI allocation,
3068 * which is an error
3069 */
3070 if (WARN_ON(!prev_slots)) {
3071 DRM_ERROR("cannot allocate and release VCPI on [MST PORT:%p] in the same state\n",
3072 port);
3073 return -EINVAL;
3074 }
3075
3076 break;
3077 }
3044 } 3078 }
3079 if (!vcpi)
3080 prev_slots = 0;
3081
3082 req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
3083
3084 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] [MST PORT:%p] VCPI %d -> %d\n",
3085 port->connector->base.id, port->connector->name,
3086 port, prev_slots, req_slots);
3087
3088 /* Add the new allocation to the state */
3089 if (!vcpi) {
3090 vcpi = kzalloc(sizeof(*vcpi), GFP_KERNEL);
3091 if (!vcpi) {
3092 ret = -ENOMEM;
3093 goto out;
3094 }
3045 3095
3046 topology_state->avail_slots -= req_slots; 3096 drm_dp_mst_get_port_malloc(port);
3047 DRM_DEBUG_KMS("vcpi slots avail=%d", topology_state->avail_slots); 3097 vcpi->port = port;
3098 list_add(&vcpi->next, &topology_state->vcpis);
3099 }
3100 vcpi->vcpi = req_slots;
3048 3101
3102 ret = req_slots;
3103out:
3049 drm_dp_mst_topology_put_port(port); 3104 drm_dp_mst_topology_put_port(port);
3050 return req_slots; 3105 return ret;
3051} 3106}
3052EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots); 3107EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots);
3053 3108
@@ -3055,31 +3110,57 @@ EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots);
3055 * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots 3110 * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots
3056 * @state: global atomic state 3111 * @state: global atomic state
3057 * @mgr: MST topology manager for the port 3112 * @mgr: MST topology manager for the port
3058 * @slots: number of vcpi slots to release 3113 * @port: The port to release the VCPI slots from
3059 * 3114 *
3060 * RETURNS: 3115 * Releases any VCPI slots that have been allocated to a port in the atomic
3061 * 0 if @slots were added back to &drm_dp_mst_topology_state->avail_slots or 3116 * state. Any atomic drivers which support MST must call this function in
3062 * negative error code 3117 * their &drm_connector_helper_funcs.atomic_check() callback when the
3118 * connector will no longer have VCPI allocated (e.g. because it's CRTC was
3119 * removed) when it had VCPI allocated in the previous atomic state.
3120 *
3121 * It is OK to call this even if @port has been removed from the system.
3122 * Additionally, it is OK to call this function multiple times on the same
3123 * @port as needed. It is not OK however, to call this function and
3124 * drm_dp_atomic_find_vcpi_slots() on the same @port in a single atomic check
3125 * phase.
3126 *
3127 * See also:
3128 * drm_dp_atomic_find_vcpi_slots()
3129 * drm_dp_mst_atomic_check()
3130 *
3131 * Returns:
3132 * 0 if all slots for this port were added back to
3133 * &drm_dp_mst_topology_state.avail_slots or negative error code
3063 */ 3134 */
3064int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, 3135int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
3065 struct drm_dp_mst_topology_mgr *mgr, 3136 struct drm_dp_mst_topology_mgr *mgr,
3066 int slots) 3137 struct drm_dp_mst_port *port)
3067{ 3138{
3068 struct drm_dp_mst_topology_state *topology_state; 3139 struct drm_dp_mst_topology_state *topology_state;
3140 struct drm_dp_vcpi_allocation *pos;
3141 bool found = false;
3069 3142
3070 topology_state = drm_atomic_get_mst_topology_state(state, mgr); 3143 topology_state = drm_atomic_get_mst_topology_state(state, mgr);
3071 if (IS_ERR(topology_state)) 3144 if (IS_ERR(topology_state))
3072 return PTR_ERR(topology_state); 3145 return PTR_ERR(topology_state);
3073 3146
3074 /* We cannot rely on port->vcpi.num_slots to update 3147 list_for_each_entry(pos, &topology_state->vcpis, next) {
3075 * topology_state->avail_slots as the port may not exist if the parent 3148 if (pos->port == port) {
3076 * branch device was unplugged. This should be fixed by tracking 3149 found = true;
3077 * per-port slot allocation in drm_dp_mst_topology_state instead of 3150 break;
3078 * depending on the caller to tell us how many slots to release. 3151 }
3079 */ 3152 }
3080 topology_state->avail_slots += slots; 3153 if (WARN_ON(!found)) {
3081 DRM_DEBUG_KMS("vcpi slots released=%d, avail=%d\n", 3154 DRM_ERROR("no VCPI for [MST PORT:%p] found in mst state %p\n",
3082 slots, topology_state->avail_slots); 3155 port, &topology_state->base);
3156 return -EINVAL;
3157 }
3158
3159 DRM_DEBUG_ATOMIC("[MST PORT:%p] VCPI %d -> 0\n", port, pos->vcpi);
3160 if (pos->vcpi) {
3161 drm_dp_mst_put_port_malloc(port);
3162 pos->vcpi = 0;
3163 }
3083 3164
3084 return 0; 3165 return 0;
3085} 3166}
@@ -3501,15 +3582,41 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
3501static struct drm_private_state * 3582static struct drm_private_state *
3502drm_dp_mst_duplicate_state(struct drm_private_obj *obj) 3583drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
3503{ 3584{
3504 struct drm_dp_mst_topology_state *state; 3585 struct drm_dp_mst_topology_state *state, *old_state =
3586 to_dp_mst_topology_state(obj->state);
3587 struct drm_dp_vcpi_allocation *pos, *vcpi;
3505 3588
3506 state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); 3589 state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
3507 if (!state) 3590 if (!state)
3508 return NULL; 3591 return NULL;
3509 3592
3510 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); 3593 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
3511 3594
3595 INIT_LIST_HEAD(&state->vcpis);
3596
3597 list_for_each_entry(pos, &old_state->vcpis, next) {
3598 /* Prune leftover freed VCPI allocations */
3599 if (!pos->vcpi)
3600 continue;
3601
3602 vcpi = kmemdup(pos, sizeof(*vcpi), GFP_KERNEL);
3603 if (!vcpi)
3604 goto fail;
3605
3606 drm_dp_mst_get_port_malloc(vcpi->port);
3607 list_add(&vcpi->next, &state->vcpis);
3608 }
3609
3512 return &state->base; 3610 return &state->base;
3611
3612fail:
3613 list_for_each_entry_safe(pos, vcpi, &state->vcpis, next) {
3614 drm_dp_mst_put_port_malloc(pos->port);
3615 kfree(pos);
3616 }
3617 kfree(state);
3618
3619 return NULL;
3513} 3620}
3514 3621
3515static void drm_dp_mst_destroy_state(struct drm_private_obj *obj, 3622static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
@@ -3517,10 +3624,88 @@ static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
3517{ 3624{
3518 struct drm_dp_mst_topology_state *mst_state = 3625 struct drm_dp_mst_topology_state *mst_state =
3519 to_dp_mst_topology_state(state); 3626 to_dp_mst_topology_state(state);
3627 struct drm_dp_vcpi_allocation *pos, *tmp;
3628
3629 list_for_each_entry_safe(pos, tmp, &mst_state->vcpis, next) {
3630 /* We only keep references to ports with non-zero VCPIs */
3631 if (pos->vcpi)
3632 drm_dp_mst_put_port_malloc(pos->port);
3633 kfree(pos);
3634 }
3520 3635
3521 kfree(mst_state); 3636 kfree(mst_state);
3522} 3637}
3523 3638
3639static inline int
3640drm_dp_mst_atomic_check_topology_state(struct drm_dp_mst_topology_mgr *mgr,
3641 struct drm_dp_mst_topology_state *mst_state)
3642{
3643 struct drm_dp_vcpi_allocation *vcpi;
3644 int avail_slots = 63;
3645
3646 list_for_each_entry(vcpi, &mst_state->vcpis, next) {
3647 /* Releasing VCPI is always OK-even if the port is gone */
3648 if (!vcpi->vcpi) {
3649 DRM_DEBUG_ATOMIC("[MST PORT:%p] releases all VCPI slots\n",
3650 vcpi->port);
3651 continue;
3652 }
3653
3654 DRM_DEBUG_ATOMIC("[MST PORT:%p] requires %d vcpi slots\n",
3655 vcpi->port, vcpi->vcpi);
3656
3657 avail_slots -= vcpi->vcpi;
3658 if (avail_slots < 0) {
3659 DRM_DEBUG_ATOMIC("[MST PORT:%p] not enough VCPI slots in mst state %p (avail=%d)\n",
3660 vcpi->port, mst_state,
3661 avail_slots + vcpi->vcpi);
3662 return -ENOSPC;
3663 }
3664 }
3665 DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
3666 mgr, mst_state, avail_slots,
3667 63 - avail_slots);
3668
3669 return 0;
3670}
3671
3672/**
3673 * drm_dp_mst_atomic_check - Check that the new state of an MST topology in an
3674 * atomic update is valid
3675 * @state: Pointer to the new &struct drm_dp_mst_topology_state
3676 *
3677 * Checks the given topology state for an atomic update to ensure that it's
3678 * valid. This includes checking whether there's enough bandwidth to support
3679 * the new VCPI allocations in the atomic update.
3680 *
3681 * Any atomic drivers supporting DP MST must make sure to call this after
3682 * checking the rest of their state in their
3683 * &drm_mode_config_funcs.atomic_check() callback.
3684 *
3685 * See also:
3686 * drm_dp_atomic_find_vcpi_slots()
3687 * drm_dp_atomic_release_vcpi_slots()
3688 *
3689 * Returns:
3690 *
3691 * 0 if the new state is valid, negative error code otherwise.
3692 */
3693int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
3694{
3695 struct drm_dp_mst_topology_mgr *mgr;
3696 struct drm_dp_mst_topology_state *mst_state;
3697 int i, ret = 0;
3698
3699 for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
3700 ret = drm_dp_mst_atomic_check_topology_state(mgr, mst_state);
3701 if (ret)
3702 break;
3703 }
3704
3705 return ret;
3706}
3707EXPORT_SYMBOL(drm_dp_mst_atomic_check);
3708
3524const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs = { 3709const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs = {
3525 .atomic_duplicate_state = drm_dp_mst_duplicate_state, 3710 .atomic_duplicate_state = drm_dp_mst_duplicate_state,
3526 .atomic_destroy_state = drm_dp_mst_destroy_state, 3711 .atomic_destroy_state = drm_dp_mst_destroy_state,
@@ -3603,9 +3788,7 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
3603 return -ENOMEM; 3788 return -ENOMEM;
3604 3789
3605 mst_state->mgr = mgr; 3790 mst_state->mgr = mgr;
3606 3791 INIT_LIST_HEAD(&mst_state->vcpis);
3607 /* max. time slots - one slot for MTP header */
3608 mst_state->avail_slots = 63;
3609 3792
3610 drm_atomic_private_obj_init(dev, &mgr->base, 3793 drm_atomic_private_obj_init(dev, &mgr->base,
3611 &mst_state->base, 3794 &mst_state->base,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 812ec5ae5c7b..5a679af03a04 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12623,6 +12623,10 @@ static int intel_atomic_check(struct drm_device *dev,
12623 "[modeset]" : "[fastset]"); 12623 "[modeset]" : "[fastset]");
12624 } 12624 }
12625 12625
12626 ret = drm_dp_mst_atomic_check(state);
12627 if (ret)
12628 return ret;
12629
12626 if (any_ms) { 12630 if (any_ms) {
12627 ret = intel_modeset_checks(state); 12631 ret = intel_modeset_checks(state);
12628 12632
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 631fd1537252..c8e2215628e6 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -41,8 +41,12 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
41 struct drm_connector *connector = conn_state->connector; 41 struct drm_connector *connector = conn_state->connector;
42 void *port = to_intel_connector(connector)->port; 42 void *port = to_intel_connector(connector)->port;
43 struct drm_atomic_state *state = pipe_config->base.state; 43 struct drm_atomic_state *state = pipe_config->base.state;
44 struct drm_crtc *crtc = pipe_config->base.crtc;
45 struct drm_crtc_state *old_crtc_state =
46 drm_atomic_get_old_crtc_state(state, crtc);
44 int bpp; 47 int bpp;
45 int lane_count, slots = 0; 48 int lane_count, slots =
49 to_intel_crtc_state(old_crtc_state)->dp_m_n.tu;
46 const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 50 const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
47 int mst_pbn; 51 int mst_pbn;
48 bool constant_n = drm_dp_has_quirk(&intel_dp->desc, 52 bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
@@ -107,35 +111,39 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
107 return true; 111 return true;
108} 112}
109 113
110static int intel_dp_mst_atomic_check(struct drm_connector *connector, 114static int
111 struct drm_connector_state *new_conn_state) 115intel_dp_mst_atomic_check(struct drm_connector *connector,
116 struct drm_connector_state *new_conn_state)
112{ 117{
113 struct drm_atomic_state *state = new_conn_state->state; 118 struct drm_atomic_state *state = new_conn_state->state;
114 struct drm_connector_state *old_conn_state; 119 struct drm_connector_state *old_conn_state =
115 struct drm_crtc *old_crtc; 120 drm_atomic_get_old_connector_state(state, connector);
121 struct intel_connector *intel_connector =
122 to_intel_connector(connector);
123 struct drm_crtc *new_crtc = new_conn_state->crtc;
116 struct drm_crtc_state *crtc_state; 124 struct drm_crtc_state *crtc_state;
117 int slots, ret = 0; 125 struct drm_dp_mst_topology_mgr *mgr;
126 int ret = 0;
118 127
119 old_conn_state = drm_atomic_get_old_connector_state(state, connector); 128 if (!old_conn_state->crtc)
120 old_crtc = old_conn_state->crtc; 129 return 0;
121 if (!old_crtc)
122 return ret;
123
124 crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc);
125 slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu;
126 if (drm_atomic_crtc_needs_modeset(crtc_state) && slots > 0) {
127 struct drm_dp_mst_topology_mgr *mgr;
128 struct drm_encoder *old_encoder;
129 130
130 old_encoder = old_conn_state->best_encoder; 131 /* We only want to free VCPI if this state disables the CRTC on this
131 mgr = &enc_to_mst(old_encoder)->primary->dp.mst_mgr; 132 * connector
133 */
134 if (new_crtc) {
135 crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
132 136
133 ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots); 137 if (!crtc_state ||
134 if (ret) 138 !drm_atomic_crtc_needs_modeset(crtc_state) ||
135 DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n", slots, ret); 139 crtc_state->enable)
136 else 140 return 0;
137 to_intel_crtc_state(crtc_state)->dp_m_n.tu = 0;
138 } 141 }
142
143 mgr = &enc_to_mst(old_conn_state->best_encoder)->primary->dp.mst_mgr;
144 ret = drm_dp_atomic_release_vcpi_slots(state, mgr,
145 intel_connector->port);
146
139 return ret; 147 return ret;
140} 148}
141 149
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 581163c8d7d7..451d020f0137 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -425,9 +425,15 @@ struct drm_dp_payload {
425 425
426#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)
427 427
428struct drm_dp_vcpi_allocation {
429 struct drm_dp_mst_port *port;
430 int vcpi;
431 struct list_head next;
432};
433
428struct drm_dp_mst_topology_state { 434struct drm_dp_mst_topology_state {
429 struct drm_private_state base; 435 struct drm_private_state base;
430 int avail_slots; 436 struct list_head vcpis;
431 struct drm_dp_mst_topology_mgr *mgr; 437 struct drm_dp_mst_topology_mgr *mgr;
432}; 438};
433 439
@@ -638,14 +644,17 @@ void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
638int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr); 644int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
639struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, 645struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
640 struct drm_dp_mst_topology_mgr *mgr); 646 struct drm_dp_mst_topology_mgr *mgr);
641int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, 647int __must_check
642 struct drm_dp_mst_topology_mgr *mgr, 648drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
643 struct drm_dp_mst_port *port, int pbn); 649 struct drm_dp_mst_topology_mgr *mgr,
644int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, 650 struct drm_dp_mst_port *port, int pbn);
645 struct drm_dp_mst_topology_mgr *mgr, 651int __must_check
646 int slots); 652drm_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);
647int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, 655int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
648 struct drm_dp_mst_port *port, bool power_up); 656 struct drm_dp_mst_port *port, bool power_up);
657int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
649 658
650void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port); 659void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
651void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port); 660void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port);