On Tue, Dec 9, 2025 at 12:34 PM Mario Limonciello <[email protected]> wrote: > > Deeply daisy chained DP/MST displays are no longer able to light > up. This reverts commit 1788ef30725da53face7e311cdf62ad65fababcd. > > Cc: Jerry Zuo <[email protected]> > Cc: [email protected] # 6.17+ > Reported-by: [email protected] > Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4756 > Signed-off-by: Mario Limonciello <[email protected]>
Acked-by: Alex Deucher <[email protected]> > --- > .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 59 +++++++++++-------- > 1 file changed, 36 insertions(+), 23 deletions(-) > > 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 dbd1da4d85d3..5e92eaa67aa3 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 > @@ -884,28 +884,26 @@ struct dsc_mst_fairness_params { > }; > > #if defined(CONFIG_DRM_AMD_DC_FP) > -static uint64_t kbps_to_pbn(int kbps, bool is_peak_pbn) > +static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link) > { > - uint64_t effective_kbps = (uint64_t)kbps; > + u8 link_coding_cap; > + uint16_t fec_overhead_multiplier_x1000 = > PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B; > > - if (is_peak_pbn) { // add 0.6% (1006/1000) overhead into > effective kbps > - effective_kbps *= 1006; > - effective_kbps = div_u64(effective_kbps, 1000); > - } > + link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link); > + if (link_coding_cap == DP_128b_132b_ENCODING) > + fec_overhead_multiplier_x1000 = > PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B; > > - return (uint64_t) DIV64_U64_ROUND_UP(effective_kbps * 64, (54 * 8 * > 1000)); > + return fec_overhead_multiplier_x1000; > } > > -static uint32_t pbn_to_kbps(unsigned int pbn, bool with_margin) > +static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000) > { > - uint64_t pbn_effective = (uint64_t)pbn; > - > - if (with_margin) // deduct 0.6% (994/1000) overhead from > effective pbn > - pbn_effective *= (1000000 / PEAK_FACTOR_X1000); > - else > - pbn_effective *= 1000; > + u64 peak_kbps = kbps; > > - return DIV_U64_ROUND_UP(pbn_effective * 8 * 54, 64); > + peak_kbps *= 1006; > + peak_kbps *= fec_overhead_multiplier_x1000; > + peak_kbps = div_u64(peak_kbps, 1000 * 1000); > + return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); > } > > static void set_dsc_configs_from_fairness_vars(struct > dsc_mst_fairness_params *params, > @@ -976,7 +974,7 @@ static int bpp_x16_from_pbn(struct > dsc_mst_fairness_params param, int pbn) > dc_dsc_get_default_config_option(param.sink->ctx->dc, &dsc_options); > dsc_options.max_target_bpp_limit_override_x16 = > drm_connector->display_info.max_dsc_bpp * 16; > > - kbps = pbn_to_kbps(pbn, false); > + kbps = div_u64((u64)pbn * 994 * 8 * 54, 64); > dc_dsc_compute_config( > param.sink->ctx->dc->res_pool->dscs[0], > ¶m.sink->dsc_caps.dsc_dec_caps, > @@ -1005,11 +1003,12 @@ static int increase_dsc_bpp(struct drm_atomic_state > *state, > int link_timeslots_used; > int fair_pbn_alloc; > int ret = 0; > + uint16_t fec_overhead_multiplier_x1000 = > get_fec_overhead_multiplier(dc_link); > > for (i = 0; i < count; i++) { > if (vars[i + k].dsc_enabled) { > initial_slack[i] = > - kbps_to_pbn(params[i].bw_range.max_kbps, false) - > vars[i + k].pbn; > + kbps_to_peak_pbn(params[i].bw_range.max_kbps, > fec_overhead_multiplier_x1000) - vars[i + k].pbn; > bpp_increased[i] = false; > remaining_to_increase += 1; > } else { > @@ -1105,6 +1104,7 @@ static int try_disable_dsc(struct drm_atomic_state > *state, > int next_index; > int remaining_to_try = 0; > int ret; > + uint16_t fec_overhead_multiplier_x1000 = > get_fec_overhead_multiplier(dc_link); > int var_pbn; > > for (i = 0; i < count; i++) { > @@ -1137,7 +1137,7 @@ static int try_disable_dsc(struct drm_atomic_state > *state, > > DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", > next_index); > var_pbn = vars[next_index].pbn; > - vars[next_index].pbn = > kbps_to_pbn(params[next_index].bw_range.stream_kbps, true); > + vars[next_index].pbn = > kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, > fec_overhead_multiplier_x1000); > ret = drm_dp_atomic_find_time_slots(state, > > params[next_index].port->mgr, > params[next_index].port, > @@ -1197,6 +1197,7 @@ static int compute_mst_dsc_configs_for_link(struct > drm_atomic_state *state, > int count = 0; > int i, k, ret; > bool debugfs_overwrite = false; > + uint16_t fec_overhead_multiplier_x1000 = > get_fec_overhead_multiplier(dc_link); > struct drm_connector_state *new_conn_state; > > memset(params, 0, sizeof(params)); > @@ -1277,7 +1278,7 @@ static int compute_mst_dsc_configs_for_link(struct > drm_atomic_state *state, > DRM_DEBUG_DRIVER("MST_DSC Try no compression\n"); > for (i = 0; i < count; i++) { > vars[i + k].aconnector = params[i].aconnector; > - vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.stream_kbps, > false); > + vars[i + k].pbn = > kbps_to_peak_pbn(params[i].bw_range.stream_kbps, > fec_overhead_multiplier_x1000); > vars[i + k].dsc_enabled = false; > vars[i + k].bpp_x16 = 0; > ret = drm_dp_atomic_find_time_slots(state, > params[i].port->mgr, params[i].port, > @@ -1299,7 +1300,7 @@ static int compute_mst_dsc_configs_for_link(struct > drm_atomic_state *state, > DRM_DEBUG_DRIVER("MST_DSC Try max compression\n"); > for (i = 0; i < count; i++) { > if (params[i].compression_possible && > params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) { > - vars[i + k].pbn = > kbps_to_pbn(params[i].bw_range.min_kbps, false); > + vars[i + k].pbn = > kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000); > vars[i + k].dsc_enabled = true; > vars[i + k].bpp_x16 = > params[i].bw_range.min_target_bpp_x16; > ret = drm_dp_atomic_find_time_slots(state, > params[i].port->mgr, > @@ -1307,7 +1308,7 @@ static int compute_mst_dsc_configs_for_link(struct > drm_atomic_state *state, > if (ret < 0) > return ret; > } else { > - vars[i + k].pbn = > kbps_to_pbn(params[i].bw_range.stream_kbps, false); > + vars[i + k].pbn = > kbps_to_peak_pbn(params[i].bw_range.stream_kbps, > fec_overhead_multiplier_x1000); > vars[i + k].dsc_enabled = false; > vars[i + k].bpp_x16 = 0; > ret = drm_dp_atomic_find_time_slots(state, > params[i].port->mgr, > @@ -1762,6 +1763,18 @@ int pre_validate_dsc(struct drm_atomic_state *state, > return ret; > } > > +static uint32_t kbps_from_pbn(unsigned int pbn) > +{ > + uint64_t kbps = (uint64_t)pbn; > + > + kbps *= (1000000 / PEAK_FACTOR_X1000); > + kbps *= 8; > + kbps *= 54; > + kbps /= 64; > + > + return (uint32_t)kbps; > +} > + > static bool is_dsc_common_config_possible(struct dc_stream_state *stream, > struct dc_dsc_bw_range *bw_range) > { > @@ -1860,7 +1873,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( > dc_link_get_highest_encoding_format(stream->link)); > cur_link_settings = stream->link->verified_link_cap; > root_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, > &cur_link_settings); > - virtual_channel_bw_in_kbps = > pbn_to_kbps(aconnector->mst_output_port->full_pbn, true); > + virtual_channel_bw_in_kbps = > kbps_from_pbn(aconnector->mst_output_port->full_pbn); > > /* pick the end to end bw bottleneck */ > end_to_end_bw_in_kbps = min(root_link_bw_in_kbps, > virtual_channel_bw_in_kbps); > @@ -1913,7 +1926,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( > immediate_upstream_port = > aconnector->mst_output_port->parent->port_parent; > > if (immediate_upstream_port) { > - virtual_channel_bw_in_kbps = > pbn_to_kbps(immediate_upstream_port->full_pbn, true); > + virtual_channel_bw_in_kbps = > kbps_from_pbn(immediate_upstream_port->full_pbn); > virtual_channel_bw_in_kbps = > min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps); > } else { > /* For topology LCT 1 case - only one mstb*/ > -- > 2.51.2 >
