@@ -81,13 +81,6 @@ struct dp_ctrl_private {
81
81
struct completion video_comp ;
82
82
};
83
83
84
- struct dp_cr_status {
85
- u8 lane_0_1 ;
86
- u8 lane_2_3 ;
87
- };
88
-
89
- #define DP_LANE0_1_CR_DONE 0x11
90
-
91
84
static int dp_aux_link_configure (struct drm_dp_aux * aux ,
92
85
struct dp_link_info * link )
93
86
{
@@ -1080,7 +1073,7 @@ static int dp_ctrl_read_link_status(struct dp_ctrl_private *ctrl,
1080
1073
}
1081
1074
1082
1075
static int dp_ctrl_link_train_1 (struct dp_ctrl_private * ctrl ,
1083
- struct dp_cr_status * cr , int * training_step )
1076
+ int * training_step )
1084
1077
{
1085
1078
int tries , old_v_level , ret = 0 ;
1086
1079
u8 link_status [DP_LINK_STATUS_SIZE ];
@@ -1109,9 +1102,6 @@ static int dp_ctrl_link_train_1(struct dp_ctrl_private *ctrl,
1109
1102
if (ret )
1110
1103
return ret ;
1111
1104
1112
- cr -> lane_0_1 = link_status [0 ];
1113
- cr -> lane_2_3 = link_status [1 ];
1114
-
1115
1105
if (drm_dp_clock_recovery_ok (link_status ,
1116
1106
ctrl -> link -> link_params .num_lanes )) {
1117
1107
return 0 ;
@@ -1188,7 +1178,7 @@ static void dp_ctrl_clear_training_pattern(struct dp_ctrl_private *ctrl)
1188
1178
}
1189
1179
1190
1180
static int dp_ctrl_link_train_2 (struct dp_ctrl_private * ctrl ,
1191
- struct dp_cr_status * cr , int * training_step )
1181
+ int * training_step )
1192
1182
{
1193
1183
int tries = 0 , ret = 0 ;
1194
1184
char pattern ;
@@ -1204,10 +1194,6 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl,
1204
1194
else
1205
1195
pattern = DP_TRAINING_PATTERN_2 ;
1206
1196
1207
- ret = dp_ctrl_update_vx_px (ctrl );
1208
- if (ret )
1209
- return ret ;
1210
-
1211
1197
ret = dp_catalog_ctrl_set_pattern (ctrl -> catalog , pattern );
1212
1198
if (ret )
1213
1199
return ret ;
@@ -1220,8 +1206,6 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl,
1220
1206
ret = dp_ctrl_read_link_status (ctrl , link_status );
1221
1207
if (ret )
1222
1208
return ret ;
1223
- cr -> lane_0_1 = link_status [0 ];
1224
- cr -> lane_2_3 = link_status [1 ];
1225
1209
1226
1210
if (drm_dp_channel_eq_ok (link_status ,
1227
1211
ctrl -> link -> link_params .num_lanes )) {
@@ -1241,7 +1225,7 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl,
1241
1225
static int dp_ctrl_reinitialize_mainlink (struct dp_ctrl_private * ctrl );
1242
1226
1243
1227
static int dp_ctrl_link_train (struct dp_ctrl_private * ctrl ,
1244
- struct dp_cr_status * cr , int * training_step )
1228
+ int * training_step )
1245
1229
{
1246
1230
int ret = 0 ;
1247
1231
u8 encoding = DP_SET_ANSI_8B10B ;
@@ -1257,7 +1241,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
1257
1241
drm_dp_dpcd_write (ctrl -> aux , DP_MAIN_LINK_CHANNEL_CODING_SET ,
1258
1242
& encoding , 1 );
1259
1243
1260
- ret = dp_ctrl_link_train_1 (ctrl , cr , training_step );
1244
+ ret = dp_ctrl_link_train_1 (ctrl , training_step );
1261
1245
if (ret ) {
1262
1246
DRM_ERROR ("link training #1 failed. ret=%d\n" , ret );
1263
1247
goto end ;
@@ -1266,7 +1250,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
1266
1250
/* print success info as this is a result of user initiated action */
1267
1251
DRM_DEBUG_DP ("link training #1 successful\n" );
1268
1252
1269
- ret = dp_ctrl_link_train_2 (ctrl , cr , training_step );
1253
+ ret = dp_ctrl_link_train_2 (ctrl , training_step );
1270
1254
if (ret ) {
1271
1255
DRM_ERROR ("link training #2 failed. ret=%d\n" , ret );
1272
1256
goto end ;
@@ -1282,7 +1266,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
1282
1266
}
1283
1267
1284
1268
static int dp_ctrl_setup_main_link (struct dp_ctrl_private * ctrl ,
1285
- struct dp_cr_status * cr , int * training_step )
1269
+ int * training_step )
1286
1270
{
1287
1271
int ret = 0 ;
1288
1272
@@ -1297,7 +1281,7 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl,
1297
1281
* a link training pattern, we have to first do soft reset.
1298
1282
*/
1299
1283
1300
- ret = dp_ctrl_link_train (ctrl , cr , training_step );
1284
+ ret = dp_ctrl_link_train (ctrl , training_step );
1301
1285
1302
1286
return ret ;
1303
1287
}
@@ -1495,14 +1479,13 @@ static int dp_ctrl_deinitialize_mainlink(struct dp_ctrl_private *ctrl)
1495
1479
static int dp_ctrl_link_maintenance (struct dp_ctrl_private * ctrl )
1496
1480
{
1497
1481
int ret = 0 ;
1498
- struct dp_cr_status cr ;
1499
1482
int training_step = DP_TRAINING_NONE ;
1500
1483
1501
1484
dp_ctrl_push_idle (& ctrl -> dp_ctrl );
1502
1485
1503
1486
ctrl -> dp_ctrl .pixel_rate = ctrl -> panel -> dp_mode .drm_mode .clock ;
1504
1487
1505
- ret = dp_ctrl_setup_main_link (ctrl , & cr , & training_step );
1488
+ ret = dp_ctrl_setup_main_link (ctrl , & training_step );
1506
1489
if (ret )
1507
1490
goto end ;
1508
1491
@@ -1633,14 +1616,33 @@ void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl)
1633
1616
}
1634
1617
}
1635
1618
1619
+ static bool dp_ctrl_clock_recovery_any_ok (
1620
+ const u8 link_status [DP_LINK_STATUS_SIZE ],
1621
+ int lane_count )
1622
+ {
1623
+ int reduced_cnt ;
1624
+
1625
+ if (lane_count <= 1 )
1626
+ return false;
1627
+
1628
+ /*
1629
+ * only interested in the lane number after reduced
1630
+ * lane_count = 4, then only interested in 2 lanes
1631
+ * lane_count = 2, then only interested in 1 lane
1632
+ */
1633
+ reduced_cnt = lane_count >> 1 ;
1634
+
1635
+ return drm_dp_clock_recovery_ok (link_status , reduced_cnt );
1636
+ }
1637
+
1636
1638
int dp_ctrl_on_link (struct dp_ctrl * dp_ctrl )
1637
1639
{
1638
1640
int rc = 0 ;
1639
1641
struct dp_ctrl_private * ctrl ;
1640
1642
u32 rate = 0 ;
1641
1643
int link_train_max_retries = 5 ;
1642
1644
u32 const phy_cts_pixel_clk_khz = 148500 ;
1643
- struct dp_cr_status cr ;
1645
+ u8 link_status [ DP_LINK_STATUS_SIZE ] ;
1644
1646
unsigned int training_step ;
1645
1647
1646
1648
if (!dp_ctrl )
@@ -1680,19 +1682,21 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl)
1680
1682
}
1681
1683
1682
1684
training_step = DP_TRAINING_NONE ;
1683
- rc = dp_ctrl_setup_main_link (ctrl , & cr , & training_step );
1685
+ rc = dp_ctrl_setup_main_link (ctrl , & training_step );
1684
1686
if (rc == 0 ) {
1685
1687
/* training completed successfully */
1686
1688
break ;
1687
1689
} else if (training_step == DP_TRAINING_1 ) {
1688
1690
/* link train_1 failed */
1689
- if (!dp_catalog_link_is_connected (ctrl -> catalog )) {
1691
+ if (!dp_catalog_link_is_connected (ctrl -> catalog ))
1690
1692
break ;
1691
- }
1693
+
1694
+ dp_ctrl_read_link_status (ctrl , link_status );
1692
1695
1693
1696
rc = dp_ctrl_link_rate_down_shift (ctrl );
1694
1697
if (rc < 0 ) { /* already in RBR = 1.6G */
1695
- if (cr .lane_0_1 & DP_LANE0_1_CR_DONE ) {
1698
+ if (dp_ctrl_clock_recovery_any_ok (link_status ,
1699
+ ctrl -> link -> link_params .num_lanes )) {
1696
1700
/*
1697
1701
* some lanes are ready,
1698
1702
* reduce lane number
@@ -1708,12 +1712,18 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl)
1708
1712
}
1709
1713
}
1710
1714
} else if (training_step == DP_TRAINING_2 ) {
1711
- /* link train_2 failed, lower lane rate */
1712
- if (!dp_catalog_link_is_connected (ctrl -> catalog )) {
1715
+ /* link train_2 failed */
1716
+ if (!dp_catalog_link_is_connected (ctrl -> catalog ))
1713
1717
break ;
1714
- }
1715
1718
1716
- rc = dp_ctrl_link_lane_down_shift (ctrl );
1719
+ dp_ctrl_read_link_status (ctrl , link_status );
1720
+
1721
+ if (!drm_dp_clock_recovery_ok (link_status ,
1722
+ ctrl -> link -> link_params .num_lanes ))
1723
+ rc = dp_ctrl_link_rate_down_shift (ctrl );
1724
+ else
1725
+ rc = dp_ctrl_link_lane_down_shift (ctrl );
1726
+
1717
1727
if (rc < 0 ) {
1718
1728
/* end with failure */
1719
1729
break ; /* lane == 1 already */
0 commit comments