Lyude Paul
2022-Jun-07 19:06 UTC
[Nouveau] [RFC 00/18] drm/display/dp_mst: Drop Radeon MST support, make MST atomic-only
For quite a while we've been carrying around a lot of legacy modesetting code in the MST helpers that has been rather annoying to keep around, and very often gets in the way of trying to implement additional functionality in MST such as fallback link rate retraining, dynamic BPC management and DSC support, etc. because of the fact that we can't rely on atomic for everything. Luckily, we only actually have one user of the legacy MST code in the kernel - radeon. Originally I was thinking of trying to maintain this code and keep it around in some form, but I'm pretty unconvinced anyone is actually using this. My reasoning for that is because I've seen nearly no issues regarding MST on radeon for quite a while now - despite the fact my local testing seems to indicate it's quite broken. This isn't too surprising either, as MST support in radeon.ko is gated behind a module parameter that isn't enabled by default. This isn't to say I wouldn't be open to alternative suggestions, but I'd rather not be the one to have to spend time on that if at all possible! Plus, I already floated the idea of dropping this code by AMD folks a few times and didn't get much resistance. As well, this series has some basic refactoring that I did along the way and some bugs I had to fix in order to get my atomic-only MST code working. Most of this is pretty straight forward and simply renaming things to more closely match the DisplayPort specification, as I think this will also make maintaining this code a lot easier in the long run (I've gotten myself confused way too many times because of this). So far I've tested this on all three MST drivers: amdgpu, i915 and nouveau, along with making sure that removing the radeon MST code doesn't break anything else. The one thing I very much could use help with regarding testing though is making sure that this works with amdgpu's DSC support on MST. So, with this we should be using the atomic state as much as possible with MST modesetting, hooray! Cc: Wayne Lin <Wayne.Lin at amd.com> Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com> Cc: Fangzhi Zuo <Jerry.Zuo at amd.com> Cc: Jani Nikula <jani.nikula at intel.com> Cc: Imre Deak <imre.deak at intel.com> Cc: Daniel Vetter <daniel.vetter at ffwll.ch> Cc: Sean Paul <sean at poorly.run> Lyude Paul (18): drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table) drm/amdgpu/dm/mst: Rename get_payload_table() drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation drm/display/dp_mst: Call them time slots, not VCPI slots drm/display/dp_mst: Fix confusing docs for drm_dp_atomic_release_time_slots() drm/display/dp_mst: Add some missing kdocs for atomic MST structs drm/display/dp_mst: Add helper for finding payloads in atomic MST state drm/display/dp_mst: Add nonblocking helpers for DP MST drm/display/dp_mst: Don't open code modeset checks for releasing time slots drm/display/dp_mst: Fix modeset tracking in drm_dp_atomic_release_vcpi_slots() drm/nouveau/kms: Cache DP encoders in nouveau_connector drm/nouveau/kms: Pull mst state in for all modesets drm/display/dp_mst: Add helpers for serializing SST <-> MST transitions drm/display/dp_mst: Drop all ports from topology on CSNs before queueing link address work drm/display/dp_mst: Skip releasing payloads if last connected port isn't connected drm/display/dp_mst: Maintain time slot allocations when deleting payloads drm/radeon: Drop legacy MST support drm/display/dp_mst: Move all payload info into the atomic state .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 72 +- .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 111 +- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 126 +- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 10 +- drivers/gpu/drm/amd/display/dc/dm_helpers.h | 4 +- .../amd/display/include/link_service_types.h | 18 +- drivers/gpu/drm/display/drm_dp_mst_topology.c | 1160 ++++++++--------- drivers/gpu/drm/i915/display/intel_display.c | 11 + drivers/gpu/drm/i915/display/intel_dp.c | 9 + drivers/gpu/drm/i915/display/intel_dp_mst.c | 91 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 24 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 202 ++- drivers/gpu/drm/nouveau/dispnv50/disp.h | 2 + drivers/gpu/drm/nouveau/nouveau_connector.c | 18 +- drivers/gpu/drm/nouveau/nouveau_connector.h | 3 + drivers/gpu/drm/radeon/Makefile | 2 +- drivers/gpu/drm/radeon/atombios_crtc.c | 11 +- drivers/gpu/drm/radeon/atombios_encoders.c | 59 - drivers/gpu/drm/radeon/radeon_atombios.c | 2 - drivers/gpu/drm/radeon/radeon_connectors.c | 61 +- drivers/gpu/drm/radeon/radeon_device.c | 1 - drivers/gpu/drm/radeon/radeon_dp_mst.c | 778 ----------- drivers/gpu/drm/radeon/radeon_drv.c | 4 - drivers/gpu/drm/radeon/radeon_encoders.c | 14 +- drivers/gpu/drm/radeon/radeon_irq_kms.c | 10 +- drivers/gpu/drm/radeon/radeon_mode.h | 40 - include/drm/display/drm_dp_mst_helper.h | 230 ++-- 27 files changed, 991 insertions(+), 2082 deletions(-) delete mode 100644 drivers/gpu/drm/radeon/radeon_dp_mst.c -- 2.35.3
Lyude Paul
2022-Jun-07 19:06 UTC
[Nouveau] [RFC 01/18] drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)
Just to make this more clear to outside contributors that these are DC-specific structs, as this also threw me into a loop a number of times before I figured out the purpose of this. Signed-off-by: Lyude Paul <lyude at redhat.com> Cc: Wayne Lin <Wayne.Lin at amd.com> Cc: Fangzhi Zuo <Jerry.Zuo at amd.com> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 9 ++++----- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 10 +++++----- drivers/gpu/drm/amd/display/dc/dm_helpers.h | 4 ++-- .../gpu/drm/amd/display/include/link_service_types.h | 11 ++++++++--- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 7c799ddc1d27..1bd70d306c22 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -153,9 +153,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps( return result; } -static void get_payload_table( - struct amdgpu_dm_connector *aconnector, - struct dp_mst_stream_allocation_table *proposed_table) +static void get_payload_table(struct amdgpu_dm_connector *aconnector, + struct dc_dp_mst_stream_allocation_table *proposed_table) { int i; struct drm_dp_mst_topology_mgr *mst_mgr @@ -177,7 +176,7 @@ static void get_payload_table( mst_mgr->payloads[i].payload_state = DP_PAYLOAD_REMOTE) { - struct dp_mst_stream_allocation *sa + struct dc_dp_mst_stream_allocation *sa &proposed_table->stream_allocations[ proposed_table->stream_count]; @@ -201,7 +200,7 @@ void dm_helpers_dp_update_branch_info( bool dm_helpers_dp_mst_write_payload_allocation_table( struct dc_context *ctx, const struct dc_stream_state *stream, - struct dp_mst_stream_allocation_table *proposed_table, + struct dc_dp_mst_stream_allocation_table *proposed_table, bool enable) { struct amdgpu_dm_connector *aconnector; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index a789ea8af27f..db0f5158a0c2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -3424,7 +3424,7 @@ static void update_mst_stream_alloc_table( struct dc_link *link, struct stream_encoder *stream_enc, struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc? - const struct dp_mst_stream_allocation_table *proposed_table) + const struct dc_dp_mst_stream_allocation_table *proposed_table) { struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 }; struct link_mst_stream_allocation *dc_alloc; @@ -3586,7 +3586,7 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx) { struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; - struct dp_mst_stream_allocation_table proposed_table = {0}; + struct dc_dp_mst_stream_allocation_table proposed_table = {0}; struct fixed31_32 avg_time_slots_per_mtp; struct fixed31_32 pbn; struct fixed31_32 pbn_per_slot; @@ -3691,7 +3691,7 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw struct fixed31_32 avg_time_slots_per_mtp; struct fixed31_32 pbn; struct fixed31_32 pbn_per_slot; - struct dp_mst_stream_allocation_table proposed_table = {0}; + struct dc_dp_mst_stream_allocation_table proposed_table = {0}; uint8_t i; enum act_return_status ret; const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); @@ -3779,7 +3779,7 @@ enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t struct fixed31_32 pbn; struct fixed31_32 pbn_per_slot; struct link_encoder *link_encoder = link->link_enc; - struct dp_mst_stream_allocation_table proposed_table = {0}; + struct dc_dp_mst_stream_allocation_table proposed_table = {0}; uint8_t i; enum act_return_status ret; const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); @@ -3855,7 +3855,7 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) { struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; - struct dp_mst_stream_allocation_table proposed_table = {0}; + struct dc_dp_mst_stream_allocation_table proposed_table = {0}; struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0); int i; bool mst_mode = (link->type == dc_connection_mst_branch); diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index fb6a2d7b6470..8173f4b80424 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -33,7 +33,7 @@ #include "dc_types.h" #include "dc.h" -struct dp_mst_stream_allocation_table; +struct dc_dp_mst_stream_allocation_table; struct aux_payload; enum aux_return_code_type; @@ -77,7 +77,7 @@ void dm_helpers_dp_update_branch_info( bool dm_helpers_dp_mst_write_payload_allocation_table( struct dc_context *ctx, const struct dc_stream_state *stream, - struct dp_mst_stream_allocation_table *proposed_table, + struct dc_dp_mst_stream_allocation_table *proposed_table, bool enable); /* diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h index 447a56286dd0..91bffc5bf52c 100644 --- a/drivers/gpu/drm/amd/display/include/link_service_types.h +++ b/drivers/gpu/drm/amd/display/include/link_service_types.h @@ -245,8 +245,13 @@ union dpcd_training_lane_set { }; +/* AMD's copy of various payload data for MST. We have two copies of the payload table (one in DRM, + * one in DC) since DRM's MST helpers can't be accessed here. This stream allocation table should + * _ONLY_ be filled out from DM and then passed to DC, do NOT use these for _any_ kind of atomic + * state calculations in DM, or you will break something. + */ /* DP MST stream allocation (payload bandwidth number) */ -struct dp_mst_stream_allocation { +struct dc_dp_mst_stream_allocation { uint8_t vcp_id; /* number of slots required for the DP stream in * transport packet */ @@ -254,11 +259,11 @@ struct dp_mst_stream_allocation { }; /* DP MST stream allocation table */ -struct dp_mst_stream_allocation_table { +struct dc_dp_mst_stream_allocation_table { /* number of DP video streams */ int stream_count; /* array of stream allocations */ - struct dp_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM]; + struct dc_dp_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM]; }; #endif /*__DAL_LINK_SERVICE_TYPES_H__*/ -- 2.35.3
Lyude Paul
2022-Jun-07 19:06 UTC
[Nouveau] [RFC 02/18] drm/amdgpu/dm/mst: Rename get_payload_table()
This function isn't too confusing if you see the comment around the call-site for it, but if you don't then it's not at all obvious this is meant to copy DRM's payload table over to DC's internal state structs. Seeing this function before finding that comment definitely threw me into a loop a few times. So, let's rename this to make it's purpose more obvious regardless of where in the code you are. Signed-off-by: Lyude Paul <lyude at redhat.com> Cc: Wayne Lin <Wayne.Lin at amd.com> Cc: Fangzhi Zuo <Jerry.Zuo at amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 1bd70d306c22..1eaacab0334b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -153,8 +153,9 @@ enum dc_edid_status dm_helpers_parse_edid_caps( return result; } -static void get_payload_table(struct amdgpu_dm_connector *aconnector, - struct dc_dp_mst_stream_allocation_table *proposed_table) +static void +fill_dc_mst_payload_table_from_drm(struct amdgpu_dm_connector *aconnector, + struct dc_dp_mst_stream_allocation_table *proposed_table) { int i; struct drm_dp_mst_topology_mgr *mst_mgr @@ -252,7 +253,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( * stream. AMD ASIC stream slot allocation should follow the same * sequence. copy DRM MST allocation to dc */ - get_payload_table(aconnector, proposed_table); + fill_dc_mst_payload_table_from_drm(aconnector, proposed_table); return true; } -- 2.35.3
Lyude Paul
2022-Jun-07 19:07 UTC
[Nouveau] [RFC 03/18] drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation
In retrospect, the name I chose for this originally is confusing, as there's a lot more info in here then just the VCPI. This really should be called a payload. Let's make it more obvious that this is meant to be related to the atomic state and is about payloads by renaming it to drm_dp_mst_atomic_payload. Also, rename various variables throughout the code that use atomic payloads. Signed-off-by: Lyude Paul <lyude at redhat.com> Cc: Wayne Lin <Wayne.Lin at amd.com> Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com> Cc: Fangzhi Zuo <Jerry.Zuo at amd.com> Cc: Jani Nikula <jani.nikula at intel.com> Cc: Imre Deak <imre.deak at intel.com> Cc: Daniel Vetter <daniel.vetter at ffwll.ch> Cc: Sean Paul <sean at poorly.run> --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 96 +++++++++---------- include/drm/display/drm_dp_mst_helper.h | 4 +- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 67b3b9697da7..38eecb89e22d 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4381,7 +4381,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, int pbn_div) { struct drm_dp_mst_topology_state *topology_state; - struct drm_dp_vcpi_allocation *pos, *vcpi = NULL; + struct drm_dp_mst_atomic_payload *pos, *payload = NULL; int prev_slots, prev_bw, req_slots; topology_state = drm_atomic_get_mst_topology_state(state, mgr); @@ -4389,11 +4389,11 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, return PTR_ERR(topology_state); /* Find the current allocation for this port, if any */ - list_for_each_entry(pos, &topology_state->vcpis, next) { + list_for_each_entry(pos, &topology_state->payloads, next) { if (pos->port == port) { - vcpi = pos; - prev_slots = vcpi->vcpi; - prev_bw = vcpi->pbn; + payload = pos; + prev_slots = payload->vcpi; + prev_bw = payload->pbn; /* * This should never happen, unless the driver tries @@ -4410,7 +4410,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, break; } } - if (!vcpi) { + if (!payload) { prev_slots = 0; prev_bw = 0; } @@ -4428,17 +4428,17 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, port, prev_bw, pbn); /* Add the new allocation to the state */ - if (!vcpi) { - vcpi = kzalloc(sizeof(*vcpi), GFP_KERNEL); - if (!vcpi) + if (!payload) { + payload = kzalloc(sizeof(*payload), GFP_KERNEL); + if (!payload) return -ENOMEM; drm_dp_mst_get_port_malloc(port); - vcpi->port = port; - list_add(&vcpi->next, &topology_state->vcpis); + payload->port = port; + list_add(&payload->next, &topology_state->payloads); } - vcpi->vcpi = req_slots; - vcpi->pbn = pbn; + payload->vcpi = req_slots; + payload->pbn = pbn; return req_slots; } @@ -4475,21 +4475,21 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, struct drm_dp_mst_port *port) { struct drm_dp_mst_topology_state *topology_state; - struct drm_dp_vcpi_allocation *pos; + struct drm_dp_mst_atomic_payload *pos; bool found = false; topology_state = drm_atomic_get_mst_topology_state(state, mgr); if (IS_ERR(topology_state)) return PTR_ERR(topology_state); - list_for_each_entry(pos, &topology_state->vcpis, next) { + list_for_each_entry(pos, &topology_state->payloads, next) { if (pos->port == port) { found = true; break; } } if (WARN_ON(!found)) { - drm_err(mgr->dev, "no VCPI for [MST PORT:%p] found in mst state %p\n", + drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n", port, &topology_state->base); return -EINVAL; } @@ -5072,7 +5072,7 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj) { struct drm_dp_mst_topology_state *state, *old_state to_dp_mst_topology_state(obj->state); - struct drm_dp_vcpi_allocation *pos, *vcpi; + struct drm_dp_mst_atomic_payload *pos, *payload; state = kmemdup(old_state, sizeof(*state), GFP_KERNEL); if (!state) @@ -5080,25 +5080,25 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj) __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); - INIT_LIST_HEAD(&state->vcpis); + INIT_LIST_HEAD(&state->payloads); - list_for_each_entry(pos, &old_state->vcpis, next) { + list_for_each_entry(pos, &old_state->payloads, next) { /* Prune leftover freed VCPI allocations */ if (!pos->vcpi) continue; - vcpi = kmemdup(pos, sizeof(*vcpi), GFP_KERNEL); - if (!vcpi) + payload = kmemdup(pos, sizeof(*payload), GFP_KERNEL); + if (!payload) goto fail; - drm_dp_mst_get_port_malloc(vcpi->port); - list_add(&vcpi->next, &state->vcpis); + drm_dp_mst_get_port_malloc(payload->port); + list_add(&payload->next, &state->payloads); } return &state->base; fail: - list_for_each_entry_safe(pos, vcpi, &state->vcpis, next) { + list_for_each_entry_safe(pos, payload, &state->payloads, next) { drm_dp_mst_put_port_malloc(pos->port); kfree(pos); } @@ -5112,9 +5112,9 @@ static void drm_dp_mst_destroy_state(struct drm_private_obj *obj, { struct drm_dp_mst_topology_state *mst_state to_dp_mst_topology_state(state); - struct drm_dp_vcpi_allocation *pos, *tmp; + struct drm_dp_mst_atomic_payload *pos, *tmp; - list_for_each_entry_safe(pos, tmp, &mst_state->vcpis, next) { + list_for_each_entry_safe(pos, tmp, &mst_state->payloads, next) { /* We only keep references to ports with non-zero VCPIs */ if (pos->vcpi) drm_dp_mst_put_port_malloc(pos->port); @@ -5147,7 +5147,7 @@ static int drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb, struct drm_dp_mst_topology_state *state) { - struct drm_dp_vcpi_allocation *vcpi; + struct drm_dp_mst_atomic_payload *payload; struct drm_dp_mst_port *port; int pbn_used = 0, ret; bool found = false; @@ -5155,9 +5155,9 @@ drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb, /* Check that we have at least one port in our state that's downstream * of this branch, otherwise we can skip this branch */ - list_for_each_entry(vcpi, &state->vcpis, next) { - if (!vcpi->pbn || - !drm_dp_mst_port_downstream_of_branch(vcpi->port, mstb)) + list_for_each_entry(payload, &state->payloads, next) { + if (!payload->pbn || + !drm_dp_mst_port_downstream_of_branch(payload->port, mstb)) continue; found = true; @@ -5188,7 +5188,7 @@ static int drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, struct drm_dp_mst_topology_state *state) { - struct drm_dp_vcpi_allocation *vcpi; + struct drm_dp_mst_atomic_payload *payload; int pbn_used = 0; if (port->pdt == DP_PEER_DEVICE_NONE) @@ -5197,10 +5197,10 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) { bool found = false; - list_for_each_entry(vcpi, &state->vcpis, next) { - if (vcpi->port != port) + list_for_each_entry(payload, &state->payloads, next) { + if (payload->port != port) continue; - if (!vcpi->pbn) + if (!payload->pbn) return 0; found = true; @@ -5220,7 +5220,7 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, return -EINVAL; } - pbn_used = vcpi->pbn; + pbn_used = payload->pbn; } else { pbn_used = drm_dp_mst_atomic_check_mstb_bw_limit(port->mstb, state); @@ -5245,25 +5245,25 @@ static inline int drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_state *mst_state) { - struct drm_dp_vcpi_allocation *vcpi; + struct drm_dp_mst_atomic_payload *payload; int avail_slots = mst_state->total_avail_slots, payload_count = 0; - list_for_each_entry(vcpi, &mst_state->vcpis, next) { - /* Releasing VCPI is always OK-even if the port is gone */ - if (!vcpi->vcpi) { + list_for_each_entry(payload, &mst_state->payloads, next) { + /* Releasing payloads is always OK-even if the port is gone */ + if (!payload->vcpi) { drm_dbg_atomic(mgr->dev, "[MST PORT:%p] releases all VCPI slots\n", - vcpi->port); + payload->port); continue; } drm_dbg_atomic(mgr->dev, "[MST PORT:%p] requires %d vcpi slots\n", - vcpi->port, vcpi->vcpi); + payload->port, payload->vcpi); - avail_slots -= vcpi->vcpi; + avail_slots -= payload->vcpi; if (avail_slots < 0) { drm_dbg_atomic(mgr->dev, "[MST PORT:%p] not enough VCPI slots in mst state %p (avail=%d)\n", - vcpi->port, mst_state, avail_slots + vcpi->vcpi); + payload->port, mst_state, avail_slots + payload->vcpi); return -ENOSPC; } @@ -5296,7 +5296,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr, int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr) { struct drm_dp_mst_topology_state *mst_state; - struct drm_dp_vcpi_allocation *pos; + struct drm_dp_mst_atomic_payload *pos; struct drm_connector *connector; struct drm_connector_state *conn_state; struct drm_crtc *crtc; @@ -5307,7 +5307,7 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm if (IS_ERR(mst_state)) return -EINVAL; - list_for_each_entry(pos, &mst_state->vcpis, next) { + list_for_each_entry(pos, &mst_state->payloads, next) { connector = pos->port->connector; @@ -5361,7 +5361,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, bool enable) { struct drm_dp_mst_topology_state *mst_state; - struct drm_dp_vcpi_allocation *pos; + struct drm_dp_mst_atomic_payload *pos; bool found = false; int vcpi = 0; @@ -5370,7 +5370,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, if (IS_ERR(mst_state)) return PTR_ERR(mst_state); - list_for_each_entry(pos, &mst_state->vcpis, next) { + list_for_each_entry(pos, &mst_state->payloads, next) { if (pos->port == port) { found = true; break; @@ -5557,7 +5557,7 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, mst_state->start_slot = 1; mst_state->mgr = mgr; - INIT_LIST_HEAD(&mst_state->vcpis); + INIT_LIST_HEAD(&mst_state->payloads); drm_atomic_private_obj_init(dev, &mgr->base, &mst_state->base, diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h index 10adec068b7f..5671173f9f37 100644 --- a/include/drm/display/drm_dp_mst_helper.h +++ b/include/drm/display/drm_dp_mst_helper.h @@ -542,7 +542,7 @@ struct drm_dp_payload { #define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base) -struct drm_dp_vcpi_allocation { +struct drm_dp_mst_atomic_payload { struct drm_dp_mst_port *port; int vcpi; int pbn; @@ -552,7 +552,7 @@ struct drm_dp_vcpi_allocation { struct drm_dp_mst_topology_state { struct drm_private_state base; - struct list_head vcpis; + struct list_head payloads; struct drm_dp_mst_topology_mgr *mgr; u8 total_avail_slots; u8 start_slot; -- 2.35.3
Lyude Paul
2022-Jun-07 19:07 UTC
[Nouveau] [RFC 04/18] drm/display/dp_mst: Call them time slots, not VCPI slots
VCPI is only sort of the correct term here, originally the majority of this code simply referred to timeslots vaguely as "slots" - and since I started working on it and adding atomic functionality, the name "VCPI slots" has been used to represent time slots. Now that we actually have consistent access to the DisplayPort spec thanks to VESA, I now know this isn't actually the proper term - as the specification refers to these as time slots. Since we're trying to make this code as easy to figure out as possible, let's take this opportunity to correct this nomenclature and call them by their proper name - timeslots. Likewise, we rename various functions appropriately, along with replacing references in the kernel documentation and various debugging messages. It's important to note that this patch series leaves the legacy MST code untouched for the most part, which is fine since we'll be removing it soon anyhow. There should be no functional changes in this series. Signed-off-by: Lyude Paul <lyude at redhat.com> Cc: Wayne Lin <Wayne.Lin at amd.com> Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com> Cc: Fangzhi Zuo <Jerry.Zuo at amd.com> Cc: Jani Nikula <jani.nikula at intel.com> Cc: Imre Deak <imre.deak at intel.com> Cc: Daniel Vetter <daniel.vetter at ffwll.ch> Cc: Sean Paul <sean at poorly.run> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 28 ++--- drivers/gpu/drm/display/drm_dp_mst_topology.c | 106 +++++++++--------- drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 +- include/drm/display/drm_dp_mst_helper.h | 6 +- 6 files changed, 75 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ad4571190a90..f84a4ad736d8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7393,7 +7393,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, clock = adjusted_mode->clock; dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, false); } - dm_new_connector_state->vcpi_slots = drm_dp_atomic_find_vcpi_slots(state, + dm_new_connector_state->vcpi_slots = drm_dp_atomic_find_time_slots(state, mst_mgr, mst_port, dm_new_connector_state->pbn, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 9221b6690a4a..e40ff51e7be0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -378,7 +378,7 @@ static int dm_dp_mst_atomic_check(struct drm_connector *connector, return 0; } - return drm_dp_atomic_release_vcpi_slots(state, + return drm_dp_atomic_release_time_slots(state, mst_mgr, mst_port); } @@ -689,7 +689,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state, if (initial_slack[next_index] > fair_pbn_alloc) { vars[next_index].pbn += fair_pbn_alloc; - if (drm_dp_atomic_find_vcpi_slots(state, + if (drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, vars[next_index].pbn, @@ -699,7 +699,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state, vars[next_index].bpp_x16 = bpp_x16_from_pbn(params[next_index], vars[next_index].pbn); } else { vars[next_index].pbn -= fair_pbn_alloc; - if (drm_dp_atomic_find_vcpi_slots(state, + if (drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, vars[next_index].pbn, @@ -708,7 +708,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state, } } else { vars[next_index].pbn += initial_slack[next_index]; - if (drm_dp_atomic_find_vcpi_slots(state, + if (drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, vars[next_index].pbn, @@ -718,7 +718,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state, vars[next_index].bpp_x16 = params[next_index].bw_range.max_target_bpp_x16; } else { vars[next_index].pbn -= initial_slack[next_index]; - if (drm_dp_atomic_find_vcpi_slots(state, + if (drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, vars[next_index].pbn, @@ -775,7 +775,7 @@ static void try_disable_dsc(struct drm_atomic_state *state, break; vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps); - if (drm_dp_atomic_find_vcpi_slots(state, + if (drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, vars[next_index].pbn, @@ -787,7 +787,7 @@ static void try_disable_dsc(struct drm_atomic_state *state, vars[next_index].bpp_x16 = 0; } else { vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps); - if (drm_dp_atomic_find_vcpi_slots(state, + if (drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, vars[next_index].pbn, @@ -873,11 +873,11 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 = 0; - if (drm_dp_atomic_find_vcpi_slots(state, - params[i].port->mgr, - params[i].port, - vars[i + k].pbn, - dm_mst_get_pbn_divider(dc_link)) < 0) + if (drm_dp_atomic_find_time_slots(state, + params[i].port->mgr, + params[i].port, + vars[i + k].pbn, + dm_mst_get_pbn_divider(dc_link)) < 0) return false; } if (!drm_dp_mst_atomic_check(state) && !debugfs_overwrite) { @@ -891,7 +891,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); vars[i + k].dsc_enabled = true; vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16; - if (drm_dp_atomic_find_vcpi_slots(state, + if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port, vars[i + k].pbn, @@ -901,7 +901,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 = 0; - if (drm_dp_atomic_find_vcpi_slots(state, + if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port, vars[i + k].pbn, diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 38eecb89e22d..702ff5d9ecc7 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4304,11 +4304,11 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_ EXPORT_SYMBOL(drm_dp_mst_get_edid); /** - * drm_dp_find_vcpi_slots() - Find VCPI slots for this PBN value + * drm_dp_find_vcpi_slots() - Find time slots for this PBN value * @mgr: manager to use * @pbn: payload bandwidth to convert into slots. * - * Calculate the number of VCPI slots that will be required for the given PBN + * Calculate the number of time slots that will be required for the given PBN * value. This function is deprecated, and should not be used in atomic * drivers. * @@ -4345,17 +4345,17 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr, } /** - * drm_dp_atomic_find_vcpi_slots() - Find and add VCPI slots to the state + * drm_dp_atomic_find_time_slots() - Find and add time slots to the state * @state: global atomic state * @mgr: MST topology manager for the port - * @port: port to find vcpi slots for + * @port: port to find time slots for * @pbn: bandwidth required for the mode in PBN * @pbn_div: divider for DSC mode that takes FEC into account * - * Allocates VCPI slots to @port, replacing any previous VCPI allocations it + * Allocates time slots to @port, replacing any previous timeslot allocations it * may have had. Any atomic drivers which support MST must call this function * in their &drm_encoder_helper_funcs.atomic_check() callback to change the - * current VCPI allocation for the new state, but only when + * current timeslot allocation for the new state, but only when * &drm_crtc_state.mode_changed or &drm_crtc_state.connectors_changed is set * to ensure compatibility with userspace applications that still use the * legacy modesetting UAPI. @@ -4365,17 +4365,17 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr, * * Additionally, it is OK to call this function multiple times on the same * @port as needed. It is not OK however, to call this function and - * drm_dp_atomic_release_vcpi_slots() in the same atomic check phase. + * drm_dp_atomic_release_time_slots() in the same atomic check phase. * * See also: - * drm_dp_atomic_release_vcpi_slots() + * drm_dp_atomic_release_time_slots() * drm_dp_mst_atomic_check() * * Returns: * Total slots in the atomic state assigned for this port, or a negative error * code if the port no longer exists */ -int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, +int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int pbn_div) @@ -4392,17 +4392,17 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, list_for_each_entry(pos, &topology_state->payloads, next) { if (pos->port == port) { payload = pos; - prev_slots = payload->vcpi; + prev_slots = payload->time_slots; prev_bw = payload->pbn; /* * This should never happen, unless the driver tries - * releasing and allocating the same VCPI allocation, + * releasing and allocating the same timeslot allocation, * which is an error */ if (WARN_ON(!prev_slots)) { drm_err(mgr->dev, - "cannot allocate and release VCPI on [MST PORT:%p] in the same state\n", + "cannot allocate and release time slots on [MST PORT:%p] in the same state\n", port); return -EINVAL; } @@ -4420,7 +4420,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, req_slots = DIV_ROUND_UP(pbn, pbn_div); - drm_dbg_atomic(mgr->dev, "[CONNECTOR:%d:%s] [MST PORT:%p] VCPI %d -> %d\n", + drm_dbg_atomic(mgr->dev, "[CONNECTOR:%d:%s] [MST PORT:%p] TU %d -> %d\n", port->connector->base.id, port->connector->name, port, prev_slots, req_slots); drm_dbg_atomic(mgr->dev, "[CONNECTOR:%d:%s] [MST PORT:%p] PBN %d -> %d\n", @@ -4437,20 +4437,20 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, payload->port = port; list_add(&payload->next, &topology_state->payloads); } - payload->vcpi = req_slots; + payload->time_slots = req_slots; payload->pbn = pbn; return req_slots; } -EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots); +EXPORT_SYMBOL(drm_dp_atomic_find_time_slots); /** - * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots + * drm_dp_atomic_release_time_slots() - Release allocated time slots * @state: global atomic state * @mgr: MST topology manager for the port - * @port: The port to release the VCPI slots from + * @port: The port to release the time slots from * - * Releases any VCPI slots that have been allocated to a port in the atomic + * Releases any time slots that have been allocated to a port in the atomic * state. Any atomic drivers which support MST must call this function in * their &drm_connector_helper_funcs.atomic_check() callback when the * connector will no longer have VCPI allocated (e.g. because its CRTC was @@ -4459,18 +4459,18 @@ EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots); * It is OK to call this even if @port has been removed from the system. * Additionally, it is OK to call this function multiple times on the same * @port as needed. It is not OK however, to call this function and - * drm_dp_atomic_find_vcpi_slots() on the same @port in a single atomic check + * drm_dp_atomic_find_time_slots() on the same @port in a single atomic check * phase. * * See also: - * drm_dp_atomic_find_vcpi_slots() + * drm_dp_atomic_find_time_slots() * drm_dp_mst_atomic_check() * * Returns: * 0 if all slots for this port were added back to * &drm_dp_mst_topology_state.avail_slots or negative error code */ -int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, +int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) { @@ -4494,16 +4494,16 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, return -EINVAL; } - drm_dbg_atomic(mgr->dev, "[MST PORT:%p] VCPI %d -> 0\n", port, pos->vcpi); - if (pos->vcpi) { + drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, pos->time_slots); + if (pos->time_slots) { drm_dp_mst_put_port_malloc(port); - pos->vcpi = 0; + pos->time_slots = 0; pos->pbn = 0; } return 0; } -EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots); +EXPORT_SYMBOL(drm_dp_atomic_release_time_slots); /** * drm_dp_mst_update_slots() - updates the slot info depending on the DP ecoding format @@ -4557,7 +4557,7 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots); if (ret) { - drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d ret=%d\n", + drm_dbg_kms(mgr->dev, "failed to init time slots=%d ret=%d\n", DIV_ROUND_UP(pbn, mgr->pbn_div), ret); drm_dp_mst_topology_put_port(port); goto out; @@ -5083,8 +5083,8 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj) INIT_LIST_HEAD(&state->payloads); list_for_each_entry(pos, &old_state->payloads, next) { - /* Prune leftover freed VCPI allocations */ - if (!pos->vcpi) + /* Prune leftover freed timeslot allocations */ + if (!pos->time_slots) continue; payload = kmemdup(pos, sizeof(*payload), GFP_KERNEL); @@ -5116,7 +5116,7 @@ static void drm_dp_mst_destroy_state(struct drm_private_obj *obj, list_for_each_entry_safe(pos, tmp, &mst_state->payloads, next) { /* We only keep references to ports with non-zero VCPIs */ - if (pos->vcpi) + if (pos->time_slots) drm_dp_mst_put_port_malloc(pos->port); kfree(pos); } @@ -5242,28 +5242,28 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, } static inline int -drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr, - struct drm_dp_mst_topology_state *mst_state) +drm_dp_mst_atomic_check_payload_alloc_limits(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_topology_state *mst_state) { struct drm_dp_mst_atomic_payload *payload; int avail_slots = mst_state->total_avail_slots, payload_count = 0; list_for_each_entry(payload, &mst_state->payloads, next) { /* Releasing payloads is always OK-even if the port is gone */ - if (!payload->vcpi) { - drm_dbg_atomic(mgr->dev, "[MST PORT:%p] releases all VCPI slots\n", + if (!payload->time_slots) { + drm_dbg_atomic(mgr->dev, "[MST PORT:%p] releases all time slots\n", payload->port); continue; } - drm_dbg_atomic(mgr->dev, "[MST PORT:%p] requires %d vcpi slots\n", - payload->port, payload->vcpi); + drm_dbg_atomic(mgr->dev, "[MST PORT:%p] requires %d time slots\n", + payload->port, payload->time_slots); - avail_slots -= payload->vcpi; + avail_slots -= payload->time_slots; if (avail_slots < 0) { drm_dbg_atomic(mgr->dev, - "[MST PORT:%p] not enough VCPI slots in mst state %p (avail=%d)\n", - payload->port, mst_state, avail_slots + payload->vcpi); + "[MST PORT:%p] not enough time slots in mst state %p (avail=%d)\n", + payload->port, mst_state, avail_slots + payload->time_slots); return -ENOSPC; } @@ -5274,7 +5274,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr, return -EINVAL; } } - drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n", + drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p TU avail=%d used=%d\n", mgr, mst_state, avail_slots, mst_state->total_avail_slots - avail_slots); return 0; @@ -5363,7 +5363,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, struct drm_dp_mst_topology_state *mst_state; struct drm_dp_mst_atomic_payload *pos; bool found = false; - int vcpi = 0; + int time_slots = 0; mst_state = drm_atomic_get_mst_topology_state(state, port->mgr); @@ -5379,30 +5379,30 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, if (!found) { drm_dbg_atomic(state->dev, - "[MST PORT:%p] Couldn't find VCPI allocation in mst state %p\n", + "[MST PORT:%p] Couldn't find payload in mst state %p\n", port, mst_state); return -EINVAL; } if (pos->dsc_enabled == enable) { drm_dbg_atomic(state->dev, - "[MST PORT:%p] DSC flag is already set to %d, returning %d VCPI slots\n", - port, enable, pos->vcpi); - vcpi = pos->vcpi; + "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n", + port, enable, pos->time_slots); + time_slots = pos->time_slots; } if (enable) { - vcpi = drm_dp_atomic_find_vcpi_slots(state, port->mgr, port, pbn, pbn_div); + time_slots = drm_dp_atomic_find_time_slots(state, port->mgr, port, pbn, pbn_div); drm_dbg_atomic(state->dev, - "[MST PORT:%p] Enabling DSC flag, reallocating %d VCPI slots on the port\n", - port, vcpi); - if (vcpi < 0) + "[MST PORT:%p] Enabling DSC flag, reallocating %d time slots on the port\n", + port, time_slots); + if (time_slots < 0) return -EINVAL; } pos->dsc_enabled = enable; - return vcpi; + return time_slots; } EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc); /** @@ -5412,15 +5412,15 @@ EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc); * * Checks the given topology state for an atomic update to ensure that it's * valid. This includes checking whether there's enough bandwidth to support - * the new VCPI allocations in the atomic update. + * the new timeslot allocations in the atomic update. * * Any atomic drivers supporting DP MST must make sure to call this after * checking the rest of their state in their * &drm_mode_config_funcs.atomic_check() callback. * * See also: - * drm_dp_atomic_find_vcpi_slots() - * drm_dp_atomic_release_vcpi_slots() + * drm_dp_atomic_find_time_slots() + * drm_dp_atomic_release_time_slots() * * Returns: * @@ -5436,7 +5436,7 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state) if (!mgr->mst_state) continue; - ret = drm_dp_mst_atomic_check_vcpi_alloc_limit(mgr, mst_state); + ret = drm_dp_mst_atomic_check_payload_alloc_limits(mgr, mst_state); if (ret) break; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 061b277e5ce7..0c922667398a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -70,7 +70,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, crtc_state->pipe_bpp, false); - slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr, + slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, connector->port, crtc_state->pbn, drm_dp_get_vc_payload_bw(&intel_dp->mst_mgr, @@ -344,8 +344,7 @@ intel_dp_mst_atomic_check(struct drm_connector *connector, } mgr = &enc_to_mst(to_intel_encoder(old_conn_state->best_encoder))->primary->dp.mst_mgr; - ret = drm_dp_atomic_release_vcpi_slots(&state->base, mgr, - intel_connector->port); + ret = drm_dp_atomic_release_time_slots(&state->base, mgr, intel_connector->port); return ret; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 4347f0b61797..631dba5a2418 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1070,7 +1070,7 @@ nv50_msto_atomic_check(struct drm_encoder *encoder, false); } - slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, mstc->port, + slots = drm_dp_atomic_find_time_slots(state, &mstm->mgr, mstc->port, asyh->dp.pbn, 0); if (slots < 0) return slots; @@ -1282,7 +1282,7 @@ nv50_mstc_atomic_check(struct drm_connector *connector, return 0; } - return drm_dp_atomic_release_vcpi_slots(state, mgr, mstc->port); + return drm_dp_atomic_release_time_slots(state, mgr, mstc->port); } static int diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h index 5671173f9f37..8ab4f14f2344 100644 --- a/include/drm/display/drm_dp_mst_helper.h +++ b/include/drm/display/drm_dp_mst_helper.h @@ -544,7 +544,7 @@ struct drm_dp_payload { struct drm_dp_mst_atomic_payload { struct drm_dp_mst_port *port; - int vcpi; + int time_slots; int pbn; bool dsc_enabled; struct list_head next; @@ -846,7 +846,7 @@ void drm_dp_mst_connector_early_unregister(struct drm_connector *connector, struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr); int __must_check -drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, +drm_dp_atomic_find_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int pbn_div); @@ -858,7 +858,7 @@ int __must_check drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr); int __must_check -drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, +drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, -- 2.35.3
Lyude Paul
2022-Jun-07 19:07 UTC
[Nouveau] [RFC 05/18] drm/display/dp_mst: Fix confusing docs for drm_dp_atomic_release_time_slots()
For some reason we mention returning 0 if "slots have been added back to drm_dp_mst_topology_state->avail_slots". This is totally misleading, avail_slots is simply for figuring out the total number of slots available in total on the topology and has no relation to the current payload allocations. So, let's get rid of that comment. Signed-off-by: Lyude Paul <lyude at redhat.com> Cc: Wayne Lin <Wayne.Lin at amd.com> Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com> Cc: Fangzhi Zuo <Jerry.Zuo at amd.com> Cc: Jani Nikula <jani.nikula at intel.com> Cc: Imre Deak <imre.deak at intel.com> Cc: Daniel Vetter <daniel.vetter at ffwll.ch> Cc: Sean Paul <sean at poorly.run> --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 702ff5d9ecc7..ec52f91b1f0e 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4467,8 +4467,7 @@ EXPORT_SYMBOL(drm_dp_atomic_find_time_slots); * drm_dp_mst_atomic_check() * * Returns: - * 0 if all slots for this port were added back to - * &drm_dp_mst_topology_state.avail_slots or negative error code + * 0 on success, negative error code otherwise */ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, -- 2.35.3
Lyude Paul
2022-Jun-07 19:07 UTC
[Nouveau] [RFC 06/18] drm/display/dp_mst: Add some missing kdocs for atomic MST structs
Since we're about to start adding some stuff here, we may as well fill in any missing documentation that we forgot to write. Signed-off-by: Lyude Paul <lyude at redhat.com> Cc: Wayne Lin <Wayne.Lin at amd.com> Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com> Cc: Fangzhi Zuo <Jerry.Zuo at amd.com> Cc: Jani Nikula <jani.nikula at intel.com> Cc: Imre Deak <imre.deak at intel.com> Cc: Daniel Vetter <daniel.vetter at ffwll.ch> Cc: Sean Paul <sean at poorly.run> --- include/drm/display/drm_dp_mst_helper.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h index 8ab4f14f2344..eb0ea578b227 100644 --- a/include/drm/display/drm_dp_mst_helper.h +++ b/include/drm/display/drm_dp_mst_helper.h @@ -542,19 +542,43 @@ struct drm_dp_payload { #define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base) +/** + * struct drm_dp_mst_atomic_payload - Atomic state struct for an MST payload + * + * The primary atomic state structure for a given MST payload. Stores information like current + * bandwidth allocation, intended action for this payload, etc. + */ struct drm_dp_mst_atomic_payload { + /** @port: The MST port assigned to this payload */ struct drm_dp_mst_port *port; + /** @time_slots: The number of timeslots allocated to this payload */ int time_slots; + /** @pbn: The payload bandwidth for this payload */ int pbn; + /** @dsc_enabled: Whether or not this payload has DSC enabled */ bool dsc_enabled; + + /** @next: The list node for this payload */ struct list_head next; }; +/** + * struct drm_dp_mst_topology_state - DisplayPort MST topology atomic state + * + * This struct represents the atomic state of the toplevel DisplayPort MST manager + */ struct drm_dp_mst_topology_state { + /** @base: Base private state for atomic */ struct drm_private_state base; + + /** @payloads: The list of payloads being created/destroyed in this state */ struct list_head payloads; + /** @mgr: The topology manager */ struct drm_dp_mst_topology_mgr *mgr; + + /** @total_avail_slots: The total number of slots this topology can handle (63 or 64) */ u8 total_avail_slots; + /** @start_slot: The first usable time slot in this topology (1 or 0) */ u8 start_slot; }; -- 2.35.3
Lyude Paul
2022-Jun-07 19:07 UTC
[Nouveau] [RFC 07/18] drm/display/dp_mst: Add helper for finding payloads in atomic MST state
We already open-code this quite often, and will be iterating through payloads even more once we've moved all of the payload tracking into the atomic state. So, let's add a helper for doing this. Signed-off-by: Lyude Paul <lyude at redhat.com> Cc: Wayne Lin <Wayne.Lin at amd.com> Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com> Cc: Fangzhi Zuo <Jerry.Zuo at amd.com> Cc: Jani Nikula <jani.nikula at intel.com> Cc: Imre Deak <imre.deak at intel.com> Cc: Daniel Vetter <daniel.vetter at ffwll.ch> Cc: Sean Paul <sean at poorly.run> --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 109 ++++++++---------- 1 file changed, 45 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index ec52f91b1f0e..0bc2c7a90c37 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -1737,6 +1737,19 @@ drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {} #define save_port_topology_ref(port, type) #endif +static struct drm_dp_mst_atomic_payload * +drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state, + struct drm_dp_mst_port *port) +{ + struct drm_dp_mst_atomic_payload *payload; + + list_for_each_entry(payload, &state->payloads, next) + if (payload->port == port) + return payload; + + return NULL; +} + static void drm_dp_destroy_mst_branch_device(struct kref *kref) { struct drm_dp_mst_branch *mstb @@ -4381,39 +4394,31 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state, int pbn_div) { struct drm_dp_mst_topology_state *topology_state; - struct drm_dp_mst_atomic_payload *pos, *payload = NULL; - int prev_slots, prev_bw, req_slots; + struct drm_dp_mst_atomic_payload *payload = NULL; + int prev_slots = 0, prev_bw = 0, req_slots; topology_state = drm_atomic_get_mst_topology_state(state, mgr); if (IS_ERR(topology_state)) return PTR_ERR(topology_state); /* Find the current allocation for this port, if any */ - list_for_each_entry(pos, &topology_state->payloads, next) { - if (pos->port == port) { - payload = pos; - prev_slots = payload->time_slots; - prev_bw = payload->pbn; - - /* - * This should never happen, unless the driver tries - * releasing and allocating the same timeslot allocation, - * which is an error - */ - if (WARN_ON(!prev_slots)) { - drm_err(mgr->dev, - "cannot allocate and release time slots on [MST PORT:%p] in the same state\n", - port); - return -EINVAL; - } + payload = drm_atomic_get_mst_payload_state(topology_state, port); + if (payload) { + prev_slots = payload->time_slots; + prev_bw = payload->pbn; - break; + /* + * This should never happen, unless the driver tries + * releasing and allocating the same timeslot allocation, + * which is an error + */ + if (WARN_ON(!prev_slots)) { + drm_err(mgr->dev, + "cannot allocate and release time slots on [MST PORT:%p] in the same state\n", + port); + return -EINVAL; } } - if (!payload) { - prev_slots = 0; - prev_bw = 0; - } if (pbn_div <= 0) pbn_div = mgr->pbn_div; @@ -4474,30 +4479,24 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_port *port) { struct drm_dp_mst_topology_state *topology_state; - struct drm_dp_mst_atomic_payload *pos; - bool found = false; + struct drm_dp_mst_atomic_payload *payload; topology_state = drm_atomic_get_mst_topology_state(state, mgr); if (IS_ERR(topology_state)) return PTR_ERR(topology_state); - list_for_each_entry(pos, &topology_state->payloads, next) { - if (pos->port == port) { - found = true; - break; - } - } - if (WARN_ON(!found)) { + payload = drm_atomic_get_mst_payload_state(topology_state, port); + if (WARN_ON(!payload)) { drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n", port, &topology_state->base); return -EINVAL; } - drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, pos->time_slots); - if (pos->time_slots) { + drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, payload->time_slots); + if (payload->time_slots) { drm_dp_mst_put_port_malloc(port); - pos->time_slots = 0; - pos->pbn = 0; + payload->time_slots = 0; + payload->pbn = 0; } return 0; @@ -5194,18 +5193,8 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, return 0; if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) { - bool found = false; - - list_for_each_entry(payload, &state->payloads, next) { - if (payload->port != port) - continue; - if (!payload->pbn) - return 0; - - found = true; - break; - } - if (!found) + payload = drm_atomic_get_mst_payload_state(state, port); + if (!payload) return 0; /* @@ -5360,34 +5349,26 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, bool enable) { struct drm_dp_mst_topology_state *mst_state; - struct drm_dp_mst_atomic_payload *pos; - bool found = false; + struct drm_dp_mst_atomic_payload *payload; int time_slots = 0; mst_state = drm_atomic_get_mst_topology_state(state, port->mgr); - if (IS_ERR(mst_state)) return PTR_ERR(mst_state); - list_for_each_entry(pos, &mst_state->payloads, next) { - if (pos->port == port) { - found = true; - break; - } - } - - if (!found) { + payload = drm_atomic_get_mst_payload_state(mst_state, port); + if (!payload) { drm_dbg_atomic(state->dev, "[MST PORT:%p] Couldn't find payload in mst state %p\n", port, mst_state); return -EINVAL; } - if (pos->dsc_enabled == enable) { + if (payload->dsc_enabled == enable) { drm_dbg_atomic(state->dev, "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n", - port, enable, pos->time_slots); - time_slots = pos->time_slots; + port, enable, payload->time_slots); + time_slots = payload->time_slots; } if (enable) { @@ -5399,7 +5380,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, return -EINVAL; } - pos->dsc_enabled = enable; + payload->dsc_enabled = enable; return time_slots; } -- 2.35.3