@@ -418,6 +418,10 @@ static int tb_dp_cm_handshake(struct tb_port *in, struct tb_port *out,
418418 return - ETIMEDOUT ;
419419}
420420
421+ /*
422+ * Returns maximum possible rate from capability supporting only DP 2.0
423+ * and below. Used when DP BW allocation mode is not enabled.
424+ */
421425static inline u32 tb_dp_cap_get_rate (u32 val )
422426{
423427 u32 rate = (val & DP_COMMON_CAP_RATE_MASK ) >> DP_COMMON_CAP_RATE_SHIFT ;
@@ -436,6 +440,28 @@ static inline u32 tb_dp_cap_get_rate(u32 val)
436440 }
437441}
438442
443+ /*
444+ * Returns maximum possible rate from capability supporting DP 2.1
445+ * UHBR20, 13.5 and 10 rates as well. Use only when DP BW allocation
446+ * mode is enabled.
447+ */
448+ static inline u32 tb_dp_cap_get_rate_ext (u32 val )
449+ {
450+ if (val & DP_COMMON_CAP_UHBR20 )
451+ return 20000 ;
452+ else if (val & DP_COMMON_CAP_UHBR13_5 )
453+ return 13500 ;
454+ else if (val & DP_COMMON_CAP_UHBR10 )
455+ return 10000 ;
456+
457+ return tb_dp_cap_get_rate (val );
458+ }
459+
460+ static inline bool tb_dp_is_uhbr_rate (unsigned int rate )
461+ {
462+ return rate >= 10000 ;
463+ }
464+
439465static inline u32 tb_dp_cap_set_rate (u32 val , u32 rate )
440466{
441467 val &= ~DP_COMMON_CAP_RATE_MASK ;
@@ -498,7 +524,9 @@ static inline u32 tb_dp_cap_set_lanes(u32 val, u32 lanes)
498524
499525static unsigned int tb_dp_bandwidth (unsigned int rate , unsigned int lanes )
500526{
501- /* Tunneling removes the DP 8b/10b encoding */
527+ /* Tunneling removes the DP 8b/10b 128/132b encoding */
528+ if (tb_dp_is_uhbr_rate (rate ))
529+ return rate * lanes * 128 / 132 ;
502530 return rate * lanes * 8 / 10 ;
503531}
504532
@@ -691,6 +719,19 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel)
691719 if (ret )
692720 return ret ;
693721
722+ /*
723+ * Pick up granularity that supports maximum possible bandwidth.
724+ * For that we use the UHBR rates too.
725+ */
726+ in_rate = tb_dp_cap_get_rate_ext (in_dp_cap );
727+ out_rate = tb_dp_cap_get_rate_ext (out_dp_cap );
728+ rate = min (in_rate , out_rate );
729+ tmp = tb_dp_bandwidth (rate , lanes );
730+
731+ tb_port_dbg (in ,
732+ "maximum bandwidth through allocation mode %u Mb/s x%u = %u Mb/s\n" ,
733+ rate , lanes , tmp );
734+
694735 for (granularity = 250 ; tmp / granularity > 255 && granularity <= 1000 ;
695736 granularity *= 2 )
696737 ;
@@ -806,15 +847,42 @@ static int tb_dp_activate(struct tb_tunnel *tunnel, bool active)
806847}
807848
808849/* max_bw is rounded up to next granularity */
809- static int tb_dp_nrd_bandwidth (struct tb_tunnel * tunnel , int * max_bw )
850+ static int tb_dp_bandwidth_mode_maximum_bandwidth (struct tb_tunnel * tunnel ,
851+ int * max_bw )
810852{
811853 struct tb_port * in = tunnel -> src_port ;
812854 int ret , rate , lanes , nrd_bw ;
855+ u32 cap ;
813856
814- ret = usb4_dp_port_nrd (in , & rate , & lanes );
857+ /*
858+ * DP IN adapter DP_LOCAL_CAP gets updated to the lowest AUX
859+ * read parameter values so this so we can use this to determine
860+ * the maximum possible bandwidth over this link.
861+ *
862+ * See USB4 v2 spec 1.0 10.4.4.5.
863+ */
864+ ret = tb_port_read (in , & cap , TB_CFG_PORT ,
865+ in -> cap_adap + DP_LOCAL_CAP , 1 );
815866 if (ret )
816867 return ret ;
817868
869+ rate = tb_dp_cap_get_rate_ext (cap );
870+ if (tb_dp_is_uhbr_rate (rate )) {
871+ /*
872+ * When UHBR is used there is no reduction in lanes so
873+ * we can use this directly.
874+ */
875+ lanes = tb_dp_cap_get_lanes (cap );
876+ } else {
877+ /*
878+ * If there is no UHBR supported then check the
879+ * non-reduced rate and lanes.
880+ */
881+ ret = usb4_dp_port_nrd (in , & rate , & lanes );
882+ if (ret )
883+ return ret ;
884+ }
885+
818886 nrd_bw = tb_dp_bandwidth (rate , lanes );
819887
820888 if (max_bw ) {
@@ -847,7 +915,7 @@ static int tb_dp_bandwidth_mode_consumed_bandwidth(struct tb_tunnel *tunnel,
847915 return ret ;
848916 allocated_bw = ret ;
849917
850- ret = tb_dp_nrd_bandwidth (tunnel , & max_bw );
918+ ret = tb_dp_bandwidth_mode_maximum_bandwidth (tunnel , & max_bw );
851919 if (ret < 0 )
852920 return ret ;
853921 if (allocated_bw == max_bw )
@@ -885,7 +953,7 @@ static int tb_dp_allocated_bandwidth(struct tb_tunnel *tunnel, int *allocated_up
885953 return ret ;
886954 allocated_bw = ret ;
887955
888- ret = tb_dp_nrd_bandwidth (tunnel , & max_bw );
956+ ret = tb_dp_bandwidth_mode_maximum_bandwidth (tunnel , & max_bw );
889957 if (ret < 0 )
890958 return ret ;
891959 if (allocated_bw == max_bw )
@@ -915,7 +983,7 @@ static int tb_dp_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up,
915983 if (!usb4_dp_port_bandwidth_mode_enabled (in ))
916984 return - EOPNOTSUPP ;
917985
918- ret = tb_dp_nrd_bandwidth (tunnel , & max_bw );
986+ ret = tb_dp_bandwidth_mode_maximum_bandwidth (tunnel , & max_bw );
919987 if (ret < 0 )
920988 return ret ;
921989
@@ -938,6 +1006,9 @@ static int tb_dp_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up,
9381006 /* Now we can use BW mode registers to figure out the bandwidth */
9391007 /* TODO: need to handle discovery too */
9401008 tunnel -> bw_mode = true;
1009+
1010+ tb_port_dbg (in , "allocated bandwidth through allocation mode %d Mb/s\n" ,
1011+ tmp );
9411012 return 0 ;
9421013}
9431014
@@ -1012,23 +1083,20 @@ static int tb_dp_maximum_bandwidth(struct tb_tunnel *tunnel, int *max_up,
10121083 int * max_down )
10131084{
10141085 struct tb_port * in = tunnel -> src_port ;
1015- u32 rate , lanes ;
10161086 int ret ;
10171087
1018- /*
1019- * DP IN adapter DP_LOCAL_CAP gets updated to the lowest AUX read
1020- * parameter values so this so we can use this to determine the
1021- * maximum possible bandwidth over this link.
1022- */
1023- ret = tb_dp_read_cap (tunnel , DP_LOCAL_CAP , & rate , & lanes );
1024- if (ret )
1088+ if (!usb4_dp_port_bandwidth_mode_enabled (in ))
1089+ return - EOPNOTSUPP ;
1090+
1091+ ret = tb_dp_bandwidth_mode_maximum_bandwidth (tunnel , NULL );
1092+ if (ret < 0 )
10251093 return ret ;
10261094
10271095 if (in -> sw -> config .depth < tunnel -> dst_port -> sw -> config .depth ) {
10281096 * max_up = 0 ;
1029- * max_down = tb_dp_bandwidth ( rate , lanes ) ;
1097+ * max_down = ret ;
10301098 } else {
1031- * max_up = tb_dp_bandwidth ( rate , lanes ) ;
1099+ * max_up = ret ;
10321100 * max_down = 0 ;
10331101 }
10341102
0 commit comments