Add helper functions to query the virtual channel and time slots for a payload and the current payload count and total allocated time slots in an MST topology. These are needed by a follow-up i915 patch verifying the SW vs. HW state of the MST topology. Cc: Lyude Paul <lyude@xxxxxxxxxx> Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 36 +++++++++++++++++++ include/drm/display/drm_dp_mst_helper.h | 21 +++++++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index f2081f3fad0da..47605f67578ad 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -3448,6 +3448,42 @@ bool drm_dp_mst_has_payload_alloc_errors(const struct drm_dp_mst_topology_state } EXPORT_SYMBOL(drm_dp_mst_has_payload_alloc_errors); +/** + * drm_dp_mst_payload_vchannel - Return the DP virtual channel for a payload + * @mst_state: The MST atomic state containing @payload + * @payload: The payload to get the virtual channel for + * + * Return the DP virtual channel for @payload. The virtual channel is a + * contiguous range of MST Transmission Units on the DP main lanes between + * the source DPTX and the first downstream MST hub DPRX. Accordingly the + * channel is determined by the payload's position on the payload list + * ordered by VC start slot. + * + * Returns the 0-based virtual channel of @payload if it's in @mst_state with + * its time slots being allocated, or -1 otherwise. + */ +int drm_dp_mst_payload_vchannel(const struct drm_dp_mst_topology_state *mst_state, + const struct drm_dp_mst_atomic_payload *payload) +{ + struct drm_dp_mst_atomic_payload *pos; + int vc = 0; + bool found = false; + + list_for_each_entry(pos, &mst_state->payloads, next) { + if (pos->vc_start_slot == -1) + continue; + + if (pos == payload) + found = true; + + if (pos->vc_start_slot < payload->vc_start_slot) + vc++; + } + + return found ? vc : -1; +} +EXPORT_SYMBOL(drm_dp_mst_payload_vchannel); + static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int offset, int size, u8 *bytes) diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h index 53b251b264e89..bb7c595096fed 100644 --- a/include/drm/display/drm_dp_mst_helper.h +++ b/include/drm/display/drm_dp_mst_helper.h @@ -846,6 +846,27 @@ void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr, const struct drm_dp_mst_atomic_payload *old_payload, struct drm_dp_mst_atomic_payload *new_payload); bool drm_dp_mst_has_payload_alloc_errors(const struct drm_dp_mst_topology_state *mst_state); +int drm_dp_mst_payload_vchannel(const struct drm_dp_mst_topology_state *mst_state, + const struct drm_dp_mst_atomic_payload *payload); + +static inline int +drm_dp_mst_payload_count(const struct drm_dp_mst_topology_state *mst_state) +{ + return mst_state->mgr->payload_count; +} + +static inline int +drm_dp_mst_allocated_time_slots(const struct drm_dp_mst_topology_state *mst_state) +{ + return drm_dp_mst_payload_count(mst_state) ? + mst_state->mgr->next_start_slot - mst_state->start_slot : 0; +} + +static inline int +drm_dp_mst_payload_time_slots(const struct drm_dp_mst_atomic_payload *payload) +{ + return payload->time_slots; +} int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr); -- 2.37.1