Skip to content

Commit 1cd0a5e

Browse files
committed
drm/dp_mst: Factor out a helper to check the atomic state of a topology manager
Factor out a helper to check the atomic state for one MST topology manager, returning the MST port where the BW limit check has failed. This will be used in a follow-up patch by the i915 driver to improve the BW sharing between MST streams. Cc: Lyude Paul <lyude@redhat.com> Cc: dri-devel@lists.freedesktop.org Reviewed-by: Lyude Paul <lyude@redhat.com> Acked-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231030155843.2251023-5-imre.deak@intel.com
1 parent 9dcf67d commit 1cd0a5e

File tree

2 files changed

+78
-19
lines changed

2 files changed

+78
-19
lines changed

drivers/gpu/drm/display/drm_dp_mst_topology.c

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5180,11 +5180,13 @@ EXPORT_SYMBOL(drm_dp_mst_port_downstream_of_parent);
51805180

51815181
static int
51825182
drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
5183-
struct drm_dp_mst_topology_state *state);
5183+
struct drm_dp_mst_topology_state *state,
5184+
struct drm_dp_mst_port **failing_port);
51845185

51855186
static int
51865187
drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb,
5187-
struct drm_dp_mst_topology_state *state)
5188+
struct drm_dp_mst_topology_state *state,
5189+
struct drm_dp_mst_port **failing_port)
51885190
{
51895191
struct drm_dp_mst_atomic_payload *payload;
51905192
struct drm_dp_mst_port *port;
@@ -5213,7 +5215,7 @@ drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb,
52135215
drm_dbg_atomic(mstb->mgr->dev, "[MSTB:%p] Checking bandwidth limits\n", mstb);
52145216

52155217
list_for_each_entry(port, &mstb->ports, next) {
5216-
ret = drm_dp_mst_atomic_check_port_bw_limit(port, state);
5218+
ret = drm_dp_mst_atomic_check_port_bw_limit(port, state, failing_port);
52175219
if (ret < 0)
52185220
return ret;
52195221

@@ -5225,7 +5227,8 @@ drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb,
52255227

52265228
static int
52275229
drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
5228-
struct drm_dp_mst_topology_state *state)
5230+
struct drm_dp_mst_topology_state *state,
5231+
struct drm_dp_mst_port **failing_port)
52295232
{
52305233
struct drm_dp_mst_atomic_payload *payload;
52315234
int pbn_used = 0;
@@ -5246,13 +5249,15 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
52465249
drm_dbg_atomic(port->mgr->dev,
52475250
"[MSTB:%p] [MST PORT:%p] no BW available for the port\n",
52485251
port->parent, port);
5252+
*failing_port = port;
52495253
return -EINVAL;
52505254
}
52515255

52525256
pbn_used = payload->pbn;
52535257
} else {
52545258
pbn_used = drm_dp_mst_atomic_check_mstb_bw_limit(port->mstb,
5255-
state);
5259+
state,
5260+
failing_port);
52565261
if (pbn_used <= 0)
52575262
return pbn_used;
52585263
}
@@ -5261,6 +5266,7 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
52615266
drm_dbg_atomic(port->mgr->dev,
52625267
"[MSTB:%p] [MST PORT:%p] required PBN of %d exceeds port limit of %d\n",
52635268
port->parent, port, pbn_used, port->full_pbn);
5269+
*failing_port = port;
52645270
return -ENOSPC;
52655271
}
52665272

@@ -5438,20 +5444,79 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
54385444
}
54395445
EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc);
54405446

5447+
/**
5448+
* drm_dp_mst_atomic_check_mgr - Check the atomic state of an MST topology manager
5449+
* @state: The global atomic state
5450+
* @mgr: Manager to check
5451+
* @mst_state: The MST atomic state for @mgr
5452+
* @failing_port: Returns the port with a BW limitation
5453+
*
5454+
* Checks the given MST manager's topology state for an atomic update to ensure
5455+
* that it's valid. This includes checking whether there's enough bandwidth to
5456+
* support the new timeslot allocations in the atomic update.
5457+
*
5458+
* Any atomic drivers supporting DP MST must make sure to call this or
5459+
* the drm_dp_mst_atomic_check() function after checking the rest of their state
5460+
* in their &drm_mode_config_funcs.atomic_check() callback.
5461+
*
5462+
* See also:
5463+
* drm_dp_mst_atomic_check()
5464+
* drm_dp_atomic_find_time_slots()
5465+
* drm_dp_atomic_release_time_slots()
5466+
*
5467+
* Returns:
5468+
* - 0 if the new state is valid
5469+
* - %-ENOSPC, if the new state is invalid, because of BW limitation
5470+
* @failing_port is set to:
5471+
* - The non-root port where a BW limit check failed
5472+
* The returned port pointer is valid until at least
5473+
* one payload downstream of it exists.
5474+
* - %NULL if the BW limit check failed at the root port
5475+
* - %-EINVAL, if the new state is invalid, because the root port has
5476+
* too many payloads.
5477+
*/
5478+
int drm_dp_mst_atomic_check_mgr(struct drm_atomic_state *state,
5479+
struct drm_dp_mst_topology_mgr *mgr,
5480+
struct drm_dp_mst_topology_state *mst_state,
5481+
struct drm_dp_mst_port **failing_port)
5482+
{
5483+
int ret;
5484+
5485+
*failing_port = NULL;
5486+
5487+
if (!mgr->mst_state)
5488+
return 0;
5489+
5490+
ret = drm_dp_mst_atomic_check_payload_alloc_limits(mgr, mst_state);
5491+
if (ret)
5492+
return ret;
5493+
5494+
mutex_lock(&mgr->lock);
5495+
ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
5496+
mst_state,
5497+
failing_port);
5498+
mutex_unlock(&mgr->lock);
5499+
5500+
return ret < 0 ? ret : 0;
5501+
}
5502+
EXPORT_SYMBOL(drm_dp_mst_atomic_check_mgr);
5503+
54415504
/**
54425505
* drm_dp_mst_atomic_check - Check that the new state of an MST topology in an
54435506
* atomic update is valid
54445507
* @state: Pointer to the new &struct drm_dp_mst_topology_state
54455508
*
54465509
* Checks the given topology state for an atomic update to ensure that it's
5447-
* valid. This includes checking whether there's enough bandwidth to support
5448-
* the new timeslot allocations in the atomic update.
5510+
* valid, calling drm_dp_mst_atomic_check_mgr() for all MST manager in the
5511+
* atomic state. This includes checking whether there's enough bandwidth to
5512+
* support the new timeslot allocations in the atomic update.
54495513
*
54505514
* Any atomic drivers supporting DP MST must make sure to call this after
54515515
* checking the rest of their state in their
54525516
* &drm_mode_config_funcs.atomic_check() callback.
54535517
*
54545518
* See also:
5519+
* drm_dp_mst_atomic_check_mgr()
54555520
* drm_dp_atomic_find_time_slots()
54565521
* drm_dp_atomic_release_time_slots()
54575522
*
@@ -5466,21 +5531,11 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
54665531
int i, ret = 0;
54675532

54685533
for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
5469-
if (!mgr->mst_state)
5470-
continue;
5534+
struct drm_dp_mst_port *tmp_port;
54715535

5472-
ret = drm_dp_mst_atomic_check_payload_alloc_limits(mgr, mst_state);
5536+
ret = drm_dp_mst_atomic_check_mgr(state, mgr, mst_state, &tmp_port);
54735537
if (ret)
54745538
break;
5475-
5476-
mutex_lock(&mgr->lock);
5477-
ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
5478-
mst_state);
5479-
mutex_unlock(&mgr->lock);
5480-
if (ret < 0)
5481-
break;
5482-
else
5483-
ret = 0;
54845539
}
54855540

54865541
return ret;

include/drm/display/drm_dp_mst_helper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,10 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
916916
int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
917917
struct drm_dp_mst_port *port,
918918
struct drm_dp_query_stream_enc_status_ack_reply *status);
919+
int __must_check drm_dp_mst_atomic_check_mgr(struct drm_atomic_state *state,
920+
struct drm_dp_mst_topology_mgr *mgr,
921+
struct drm_dp_mst_topology_state *mst_state,
922+
struct drm_dp_mst_port **failing_port);
919923
int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
920924
int __must_check drm_dp_mst_root_conn_atomic_check(struct drm_connector_state *new_conn_state,
921925
struct drm_dp_mst_topology_mgr *mgr);

0 commit comments

Comments
 (0)