@@ -212,6 +212,21 @@ bool needs_dsc_aux_workaround(struct dc_link *link)
212
212
return false;
213
213
}
214
214
215
+ bool is_synaptics_cascaded_panamera (struct dc_link * link , struct drm_dp_mst_port * port )
216
+ {
217
+ u8 branch_vendor_data [4 ] = { 0 }; // Vendor data 0x50C ~ 0x50F
218
+
219
+ if (drm_dp_dpcd_read (port -> mgr -> aux , DP_BRANCH_VENDOR_SPECIFIC_START , & branch_vendor_data , 4 ) == 4 ) {
220
+ if (link -> dpcd_caps .branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
221
+ IS_SYNAPTICS_CASCADED_PANAMERA (link -> dpcd_caps .branch_dev_name , branch_vendor_data )) {
222
+ DRM_INFO ("Synaptics Cascaded MST hub\n" );
223
+ return true;
224
+ }
225
+ }
226
+
227
+ return false;
228
+ }
229
+
215
230
static bool validate_dsc_caps_on_connector (struct amdgpu_dm_connector * aconnector )
216
231
{
217
232
struct dc_sink * dc_sink = aconnector -> dc_sink ;
@@ -235,6 +250,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
235
250
needs_dsc_aux_workaround (aconnector -> dc_link ))
236
251
aconnector -> dsc_aux = & aconnector -> mst_root -> dm_dp_aux .aux ;
237
252
253
+ /* synaptics cascaded MST hub case */
254
+ if (!aconnector -> dsc_aux && is_synaptics_cascaded_panamera (aconnector -> dc_link , port ))
255
+ aconnector -> dsc_aux = port -> mgr -> aux ;
256
+
238
257
if (!aconnector -> dsc_aux )
239
258
return false;
240
259
@@ -662,12 +681,25 @@ struct dsc_mst_fairness_params {
662
681
struct amdgpu_dm_connector * aconnector ;
663
682
};
664
683
665
- static int kbps_to_peak_pbn (int kbps )
684
+ static uint16_t get_fec_overhead_multiplier (struct dc_link * dc_link )
685
+ {
686
+ u8 link_coding_cap ;
687
+ uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B ;
688
+
689
+ link_coding_cap = dc_link_dp_mst_decide_link_encoding_format (dc_link );
690
+ if (link_coding_cap == DP_128b_132b_ENCODING )
691
+ fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B ;
692
+
693
+ return fec_overhead_multiplier_x1000 ;
694
+ }
695
+
696
+ static int kbps_to_peak_pbn (int kbps , uint16_t fec_overhead_multiplier_x1000 )
666
697
{
667
698
u64 peak_kbps = kbps ;
668
699
669
700
peak_kbps *= 1006 ;
670
- peak_kbps = div_u64 (peak_kbps , 1000 );
701
+ peak_kbps *= fec_overhead_multiplier_x1000 ;
702
+ peak_kbps = div_u64 (peak_kbps , 1000 * 1000 );
671
703
return (int ) DIV64_U64_ROUND_UP (peak_kbps * 64 , (54 * 8 * 1000 ));
672
704
}
673
705
@@ -761,11 +793,12 @@ static int increase_dsc_bpp(struct drm_atomic_state *state,
761
793
int link_timeslots_used ;
762
794
int fair_pbn_alloc ;
763
795
int ret = 0 ;
796
+ uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier (dc_link );
764
797
765
798
for (i = 0 ; i < count ; i ++ ) {
766
799
if (vars [i + k ].dsc_enabled ) {
767
800
initial_slack [i ] =
768
- kbps_to_peak_pbn (params [i ].bw_range .max_kbps ) - vars [i + k ].pbn ;
801
+ kbps_to_peak_pbn (params [i ].bw_range .max_kbps , fec_overhead_multiplier_x1000 ) - vars [i + k ].pbn ;
769
802
bpp_increased [i ] = false;
770
803
remaining_to_increase += 1 ;
771
804
} else {
@@ -861,6 +894,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
861
894
int next_index ;
862
895
int remaining_to_try = 0 ;
863
896
int ret ;
897
+ uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier (dc_link );
864
898
865
899
for (i = 0 ; i < count ; i ++ ) {
866
900
if (vars [i + k ].dsc_enabled
@@ -890,7 +924,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
890
924
if (next_index == -1 )
891
925
break ;
892
926
893
- vars [next_index ].pbn = kbps_to_peak_pbn (params [next_index ].bw_range .stream_kbps );
927
+ vars [next_index ].pbn = kbps_to_peak_pbn (params [next_index ].bw_range .stream_kbps , fec_overhead_multiplier_x1000 );
894
928
ret = drm_dp_atomic_find_time_slots (state ,
895
929
params [next_index ].port -> mgr ,
896
930
params [next_index ].port ,
@@ -903,7 +937,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
903
937
vars [next_index ].dsc_enabled = false;
904
938
vars [next_index ].bpp_x16 = 0 ;
905
939
} else {
906
- vars [next_index ].pbn = kbps_to_peak_pbn (params [next_index ].bw_range .max_kbps );
940
+ vars [next_index ].pbn = kbps_to_peak_pbn (params [next_index ].bw_range .max_kbps , fec_overhead_multiplier_x1000 );
907
941
ret = drm_dp_atomic_find_time_slots (state ,
908
942
params [next_index ].port -> mgr ,
909
943
params [next_index ].port ,
@@ -932,6 +966,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
932
966
int count = 0 ;
933
967
int i , k , ret ;
934
968
bool debugfs_overwrite = false;
969
+ uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier (dc_link );
935
970
936
971
memset (params , 0 , sizeof (params ));
937
972
@@ -993,7 +1028,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
993
1028
/* Try no compression */
994
1029
for (i = 0 ; i < count ; i ++ ) {
995
1030
vars [i + k ].aconnector = params [i ].aconnector ;
996
- vars [i + k ].pbn = kbps_to_peak_pbn (params [i ].bw_range .stream_kbps );
1031
+ vars [i + k ].pbn = kbps_to_peak_pbn (params [i ].bw_range .stream_kbps , fec_overhead_multiplier_x1000 );
997
1032
vars [i + k ].dsc_enabled = false;
998
1033
vars [i + k ].bpp_x16 = 0 ;
999
1034
ret = drm_dp_atomic_find_time_slots (state , params [i ].port -> mgr , params [i ].port ,
@@ -1012,15 +1047,15 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
1012
1047
/* Try max compression */
1013
1048
for (i = 0 ; i < count ; i ++ ) {
1014
1049
if (params [i ].compression_possible && params [i ].clock_force_enable != DSC_CLK_FORCE_DISABLE ) {
1015
- vars [i + k ].pbn = kbps_to_peak_pbn (params [i ].bw_range .min_kbps );
1050
+ vars [i + k ].pbn = kbps_to_peak_pbn (params [i ].bw_range .min_kbps , fec_overhead_multiplier_x1000 );
1016
1051
vars [i + k ].dsc_enabled = true;
1017
1052
vars [i + k ].bpp_x16 = params [i ].bw_range .min_target_bpp_x16 ;
1018
1053
ret = drm_dp_atomic_find_time_slots (state , params [i ].port -> mgr ,
1019
1054
params [i ].port , vars [i + k ].pbn );
1020
1055
if (ret < 0 )
1021
1056
return ret ;
1022
1057
} else {
1023
- vars [i + k ].pbn = kbps_to_peak_pbn (params [i ].bw_range .stream_kbps );
1058
+ vars [i + k ].pbn = kbps_to_peak_pbn (params [i ].bw_range .stream_kbps , fec_overhead_multiplier_x1000 );
1024
1059
vars [i + k ].dsc_enabled = false;
1025
1060
vars [i + k ].bpp_x16 = 0 ;
1026
1061
ret = drm_dp_atomic_find_time_slots (state , params [i ].port -> mgr ,
0 commit comments