Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Fix mst hub unplug warning

[Why]
Unplug mst hub will cause warning. That's because
dm_helpers_construct_old_payload() is changed to be called after
payload removement from dc link.

In dm_helpers_construct_old_payload(), We refer to the vcpi in
payload allocation table of dc link to construct the old payload
and payload is no longer in the table when we call the function
now.

[How]
Refer to the mst_state to construct the number of time slot for old
payload now. Note that dm_helpers_construct_old_payload() is just
a quick workaround before and we are going to abandon it soon.

Fixes: 5aa1dfcdf0a4 ("drm/mst: Refactor the flow for payload allocation/removement")
Reviewed-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231005080405.169841-1-Wayne.Lin@amd.com

authored by

Wayne Lin and committed by
Alex Deucher
9031e001 eba90a7a

+18 -20
+18 -20
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
··· 204 204 {} 205 205 206 206 static void dm_helpers_construct_old_payload( 207 - struct dc_link *link, 208 - int pbn_per_slot, 207 + struct drm_dp_mst_topology_mgr *mgr, 208 + struct drm_dp_mst_topology_state *mst_state, 209 209 struct drm_dp_mst_atomic_payload *new_payload, 210 210 struct drm_dp_mst_atomic_payload *old_payload) 211 211 { 212 - struct link_mst_stream_allocation_table current_link_table = 213 - link->mst_stream_alloc_table; 214 - struct link_mst_stream_allocation *dc_alloc; 215 - int i; 212 + struct drm_dp_mst_atomic_payload *pos; 213 + int pbn_per_slot = mst_state->pbn_div; 214 + u8 next_payload_vc_start = mgr->next_start_slot; 215 + u8 payload_vc_start = new_payload->vc_start_slot; 216 + u8 allocated_time_slots; 216 217 217 218 *old_payload = *new_payload; 218 219 ··· 222 221 * struct drm_dp_mst_atomic_payload are don't care fields 223 222 * while calling drm_dp_remove_payload_part2() 224 223 */ 225 - for (i = 0; i < current_link_table.stream_count; i++) { 226 - dc_alloc = 227 - &current_link_table.stream_allocations[i]; 228 - 229 - if (dc_alloc->vcp_id == new_payload->vcpi) { 230 - old_payload->time_slots = dc_alloc->slot_count; 231 - old_payload->pbn = dc_alloc->slot_count * pbn_per_slot; 232 - break; 233 - } 224 + list_for_each_entry(pos, &mst_state->payloads, next) { 225 + if (pos != new_payload && 226 + pos->vc_start_slot > payload_vc_start && 227 + pos->vc_start_slot < next_payload_vc_start) 228 + next_payload_vc_start = pos->vc_start_slot; 234 229 } 235 230 236 - /* make sure there is an old payload*/ 237 - ASSERT(i != current_link_table.stream_count); 231 + allocated_time_slots = next_payload_vc_start - payload_vc_start; 238 232 233 + old_payload->time_slots = allocated_time_slots; 234 + old_payload->pbn = allocated_time_slots * pbn_per_slot; 239 235 } 240 236 241 237 /* ··· 269 271 drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload); 270 272 } else { 271 273 /* construct old payload by VCPI*/ 272 - dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div, 273 - new_payload, &old_payload); 274 + dm_helpers_construct_old_payload(mst_mgr, mst_state, 275 + new_payload, &old_payload); 274 276 target_payload = &old_payload; 275 277 276 278 drm_dp_remove_payload_part1(mst_mgr, mst_state, new_payload); ··· 362 364 if (enable) { 363 365 ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload); 364 366 } else { 365 - dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div, 367 + dm_helpers_construct_old_payload(mst_mgr, mst_state, 366 368 new_payload, &old_payload); 367 369 drm_dp_remove_payload_part2(mst_mgr, mst_state, &old_payload, new_payload); 368 370 }