Skip to content

Commit 1788ef3

Browse files
Fangzhi Zuoalexdeucher
authored andcommitted
drm/amd/display: Fix pbn to kbps Conversion
[Why] Existing routine has two conversion sequence, pbn_to_kbps and kbps_to_pbn with margin. Non of those has without-margin calculation. kbps_to_pbn with margin conversion includes fec overhead which has already been included in pbn_div calculation with 0.994 factor considered. It is a double counted fec overhead factor that causes potential bw loss. [How] Add without-margin calculation. Fix fec overhead double counted issue. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3735 Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com> Signed-off-by: Ivan Lipski <ivan.lipski@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit e0dec00) Cc: stable@vger.kernel.org
1 parent 5bab4c8 commit 1788ef3

1 file changed

Lines changed: 23 additions & 36 deletions

File tree

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -884,26 +884,28 @@ struct dsc_mst_fairness_params {
884884
};
885885

886886
#if defined(CONFIG_DRM_AMD_DC_FP)
887-
static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link)
887+
static uint64_t kbps_to_pbn(int kbps, bool is_peak_pbn)
888888
{
889-
u8 link_coding_cap;
890-
uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B;
889+
uint64_t effective_kbps = (uint64_t)kbps;
891890

892-
link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link);
893-
if (link_coding_cap == DP_128b_132b_ENCODING)
894-
fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B;
891+
if (is_peak_pbn) { // add 0.6% (1006/1000) overhead into effective kbps
892+
effective_kbps *= 1006;
893+
effective_kbps = div_u64(effective_kbps, 1000);
894+
}
895895

896-
return fec_overhead_multiplier_x1000;
896+
return (uint64_t) DIV64_U64_ROUND_UP(effective_kbps * 64, (54 * 8 * 1000));
897897
}
898898

899-
static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000)
899+
static uint32_t pbn_to_kbps(unsigned int pbn, bool with_margin)
900900
{
901-
u64 peak_kbps = kbps;
901+
uint64_t pbn_effective = (uint64_t)pbn;
902+
903+
if (with_margin) // deduct 0.6% (994/1000) overhead from effective pbn
904+
pbn_effective *= (1000000 / PEAK_FACTOR_X1000);
905+
else
906+
pbn_effective *= 1000;
902907

903-
peak_kbps *= 1006;
904-
peak_kbps *= fec_overhead_multiplier_x1000;
905-
peak_kbps = div_u64(peak_kbps, 1000 * 1000);
906-
return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000));
908+
return DIV_U64_ROUND_UP(pbn_effective * 8 * 54, 64);
907909
}
908910

909911
static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params,
@@ -974,7 +976,7 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn)
974976
dc_dsc_get_default_config_option(param.sink->ctx->dc, &dsc_options);
975977
dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;
976978

977-
kbps = div_u64((u64)pbn * 994 * 8 * 54, 64);
979+
kbps = pbn_to_kbps(pbn, false);
978980
dc_dsc_compute_config(
979981
param.sink->ctx->dc->res_pool->dscs[0],
980982
&param.sink->dsc_caps.dsc_dec_caps,
@@ -1003,12 +1005,11 @@ static int increase_dsc_bpp(struct drm_atomic_state *state,
10031005
int link_timeslots_used;
10041006
int fair_pbn_alloc;
10051007
int ret = 0;
1006-
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
10071008

10081009
for (i = 0; i < count; i++) {
10091010
if (vars[i + k].dsc_enabled) {
10101011
initial_slack[i] =
1011-
kbps_to_peak_pbn(params[i].bw_range.max_kbps, fec_overhead_multiplier_x1000) - vars[i + k].pbn;
1012+
kbps_to_pbn(params[i].bw_range.max_kbps, false) - vars[i + k].pbn;
10121013
bpp_increased[i] = false;
10131014
remaining_to_increase += 1;
10141015
} else {
@@ -1104,7 +1105,6 @@ static int try_disable_dsc(struct drm_atomic_state *state,
11041105
int next_index;
11051106
int remaining_to_try = 0;
11061107
int ret;
1107-
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
11081108
int var_pbn;
11091109

11101110
for (i = 0; i < count; i++) {
@@ -1137,7 +1137,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
11371137

11381138
DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index);
11391139
var_pbn = vars[next_index].pbn;
1140-
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
1140+
vars[next_index].pbn = kbps_to_pbn(params[next_index].bw_range.stream_kbps, true);
11411141
ret = drm_dp_atomic_find_time_slots(state,
11421142
params[next_index].port->mgr,
11431143
params[next_index].port,
@@ -1197,7 +1197,6 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
11971197
int count = 0;
11981198
int i, k, ret;
11991199
bool debugfs_overwrite = false;
1200-
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
12011200
struct drm_connector_state *new_conn_state;
12021201

12031202
memset(params, 0, sizeof(params));
@@ -1278,7 +1277,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
12781277
DRM_DEBUG_DRIVER("MST_DSC Try no compression\n");
12791278
for (i = 0; i < count; i++) {
12801279
vars[i + k].aconnector = params[i].aconnector;
1281-
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
1280+
vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.stream_kbps, false);
12821281
vars[i + k].dsc_enabled = false;
12831282
vars[i + k].bpp_x16 = 0;
12841283
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port,
@@ -1300,15 +1299,15 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
13001299
DRM_DEBUG_DRIVER("MST_DSC Try max compression\n");
13011300
for (i = 0; i < count; i++) {
13021301
if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) {
1303-
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000);
1302+
vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.min_kbps, false);
13041303
vars[i + k].dsc_enabled = true;
13051304
vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16;
13061305
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
13071306
params[i].port, vars[i + k].pbn);
13081307
if (ret < 0)
13091308
return ret;
13101309
} else {
1311-
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
1310+
vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.stream_kbps, false);
13121311
vars[i + k].dsc_enabled = false;
13131312
vars[i + k].bpp_x16 = 0;
13141313
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
@@ -1763,18 +1762,6 @@ int pre_validate_dsc(struct drm_atomic_state *state,
17631762
return ret;
17641763
}
17651764

1766-
static uint32_t kbps_from_pbn(unsigned int pbn)
1767-
{
1768-
uint64_t kbps = (uint64_t)pbn;
1769-
1770-
kbps *= (1000000 / PEAK_FACTOR_X1000);
1771-
kbps *= 8;
1772-
kbps *= 54;
1773-
kbps /= 64;
1774-
1775-
return (uint32_t)kbps;
1776-
}
1777-
17781765
static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
17791766
struct dc_dsc_bw_range *bw_range)
17801767
{
@@ -1873,7 +1860,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
18731860
dc_link_get_highest_encoding_format(stream->link));
18741861
cur_link_settings = stream->link->verified_link_cap;
18751862
root_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, &cur_link_settings);
1876-
virtual_channel_bw_in_kbps = kbps_from_pbn(aconnector->mst_output_port->full_pbn);
1863+
virtual_channel_bw_in_kbps = pbn_to_kbps(aconnector->mst_output_port->full_pbn, true);
18771864

18781865
/* pick the end to end bw bottleneck */
18791866
end_to_end_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
@@ -1926,7 +1913,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
19261913
immediate_upstream_port = aconnector->mst_output_port->parent->port_parent;
19271914

19281915
if (immediate_upstream_port) {
1929-
virtual_channel_bw_in_kbps = kbps_from_pbn(immediate_upstream_port->full_pbn);
1916+
virtual_channel_bw_in_kbps = pbn_to_kbps(immediate_upstream_port->full_pbn, true);
19301917
virtual_channel_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
19311918
} else {
19321919
/* For topology LCT 1 case - only one mstb*/

0 commit comments

Comments
 (0)