@@ -1119,6 +1119,135 @@ static int rtpcs_93xx_init_serdes_common(struct rtpcs_ctrl *ctrl)
11191119 return 0 ;
11201120}
11211121
1122+ static int rtpcs_93xx_sds_get_pll_config (struct rtpcs_serdes * sds , enum rtpcs_sds_pll_type pll ,
1123+ enum rtpcs_sds_pll_speed * speed )
1124+ {
1125+ struct rtpcs_serdes * even_sds = rtpcs_sds_get_even (sds );
1126+ int sbit , speed_val ;
1127+
1128+ /*
1129+ * PLL config is shared between adjacent SerDes in the even lane. Each SerDes defines
1130+ * what PLL it needs (ring or LC) while the PLL itself stores the current speed.
1131+ */
1132+
1133+ sbit = pll == RTPCS_SDS_PLL_TYPE_LC ? 8 : 12 ;
1134+ speed_val = rtpcs_sds_read_bits (even_sds , 0x20 , 0x12 , sbit + 3 , sbit );
1135+ if (speed_val < 0 )
1136+ return speed_val ;
1137+
1138+ /* bit 0 is force-bit, bits [3:1] are speed selector */
1139+ * speed = (enum rtpcs_sds_pll_speed )(speed_val >> 1 );
1140+ return 0 ;
1141+ }
1142+
1143+ static int rtpcs_93xx_sds_set_pll_config (struct rtpcs_serdes * sds , enum rtpcs_sds_pll_type pll ,
1144+ enum rtpcs_sds_pll_speed speed )
1145+ {
1146+ struct rtpcs_serdes * even_sds = rtpcs_sds_get_even (sds );
1147+ int sbit = pll == RTPCS_SDS_PLL_TYPE_LC ? 8 : 12 ;
1148+ int ret ;
1149+
1150+ if (speed >= RTPCS_SDS_PLL_SPD_END )
1151+ return - EINVAL ;
1152+
1153+ if (pll >= RTPCS_SDS_PLL_TYPE_END )
1154+ return - EINVAL ;
1155+
1156+ if ((pll == RTPCS_SDS_PLL_TYPE_RING ) && (speed == RTPCS_SDS_PLL_SPD_10000 ))
1157+ return - EINVAL ;
1158+
1159+ /*
1160+ * A SerDes clock can either be taken from the low speed ring PLL or the high speed
1161+ * LC PLL. As it is unclear if disabling PLLs has any positive or negative effect,
1162+ * always activate both.
1163+ */
1164+
1165+ ret = rtpcs_sds_write_bits (even_sds , 0x20 , 0x12 , 3 , 0 , 0xf );
1166+ if (ret < 0 )
1167+ return ret ;
1168+
1169+ /* bit 0 is force-bit, bits [3:1] are speed selector */
1170+ ret = rtpcs_sds_write_bits (even_sds , 0x20 , 0x12 , sbit + 3 , sbit , (speed << 1 ) | BIT (0 ));
1171+ if (ret < 0 )
1172+ return ret ;
1173+
1174+ if (sds -> ops -> reset_cmu )
1175+ ret = sds -> ops -> reset_cmu (sds , pll );
1176+
1177+ return ret ;
1178+ }
1179+
1180+ static int rtpcs_93xx_sds_config_cmu (struct rtpcs_serdes * sds , enum rtpcs_sds_mode hw_mode )
1181+ {
1182+ struct rtpcs_serdes * nb_sds = rtpcs_sds_get_neighbor (sds );
1183+ enum rtpcs_sds_pll_speed speed , neighbor_speed ;
1184+ enum rtpcs_sds_pll_type pll , neighbor_pll ;
1185+ bool speed_changed = true;
1186+ int ret ;
1187+
1188+ /*
1189+ * A SerDes pair on the RTL930x is driven by two PLLs. A low speed ring PLL can generate
1190+ * signals of 1.25G and 3.125G for link speeds of 1G/2.5G. A high speed LC PLL can
1191+ * additionally generate a 10.3125G signal for 10G speeds. To drive the pair at different
1192+ * speeds each SerDes must use its own PLL. But what if the SerDess attached to the ring
1193+ * PLL suddenly needs 10G but the LC PLL is running at 1G? To avoid reconfiguring the
1194+ * "partner" SerDes we must choose wisely what assignment serves the current needs. The
1195+ * logic boils down to the following rules:
1196+ *
1197+ * - Use ring PLL for slow 1G speeds
1198+ * - Use LC PLL for fast 10G speeds
1199+ * - For 2.5G prefer ring over LC PLL
1200+ *
1201+ * However, when we want to configure 10G speed while the other SerDes is already using
1202+ * the LC PLL for a slower speed, there is no way to avoid reconfiguration. Note that
1203+ * this can even happen when the other SerDes is not actually in use, because changing
1204+ * the state of a SerDes back to RTL930X_SDS_OFF is not (yet) implemented.
1205+ */
1206+
1207+ ret = nb_sds -> ops -> get_pll_select (nb_sds , & neighbor_pll );
1208+ if (ret < 0 )
1209+ return ret ;
1210+
1211+ ret = rtpcs_93xx_sds_get_pll_config (nb_sds , neighbor_pll , & neighbor_speed );
1212+ if (ret < 0 )
1213+ return ret ;
1214+
1215+ ret = rtpcs_sds_select_pll_speed (hw_mode , & speed );
1216+ if (ret < 0 )
1217+ return ret ;
1218+
1219+ if (nb_sds -> hw_mode == RTPCS_SDS_MODE_OFF )
1220+ pll = speed == RTPCS_SDS_PLL_SPD_10000 ? RTPCS_SDS_PLL_TYPE_LC
1221+ : RTPCS_SDS_PLL_TYPE_RING ;
1222+ else if (speed == neighbor_speed ) {
1223+ speed_changed = false;
1224+ pll = neighbor_pll ;
1225+ } else if (neighbor_pll == RTPCS_SDS_PLL_TYPE_RING )
1226+ pll = RTPCS_SDS_PLL_TYPE_LC ;
1227+ else if (speed == RTPCS_SDS_PLL_SPD_10000 ) {
1228+ pr_info ("%s: SDS %d needs LC PLL, reconfigure SDS %d to use ring PLL\n" ,
1229+ __func__ , sds -> id , nb_sds -> id );
1230+ ret = nb_sds -> ops -> reconfigure_to_pll (nb_sds , RTPCS_SDS_PLL_TYPE_RING );
1231+ if (ret < 0 )
1232+ return ret ;
1233+
1234+ pll = RTPCS_SDS_PLL_TYPE_LC ;
1235+ } else
1236+ pll = RTPCS_SDS_PLL_TYPE_RING ;
1237+
1238+ if (speed_changed )
1239+ ret = rtpcs_93xx_sds_set_pll_config (sds , pll , speed );
1240+
1241+ ret = sds -> ops -> set_pll_select (sds , hw_mode , pll );
1242+ if (ret < 0 )
1243+ return ret ;
1244+
1245+ pr_info ("%s: SDS %d using %s PLL for mode %d\n" , __func__ , sds -> id ,
1246+ pll == RTPCS_SDS_PLL_TYPE_LC ? "LC" : "ring" , hw_mode );
1247+
1248+ return ret ;
1249+ }
1250+
11221251/* RTL930X */
11231252
11241253/*
@@ -1290,27 +1419,6 @@ static int rtpcs_930x_sds_get_pll_select(struct rtpcs_serdes *sds, enum rtpcs_sd
12901419 return 0 ;
12911420}
12921421
1293- static int rtpcs_930x_sds_get_pll_config (struct rtpcs_serdes * sds , enum rtpcs_sds_pll_type pll ,
1294- enum rtpcs_sds_pll_speed * speed )
1295- {
1296- struct rtpcs_serdes * even_sds = rtpcs_sds_get_even (sds );
1297- int sbit , speed_val ;
1298-
1299- /*
1300- * PLL data is shared between adjacent SerDes in the even lane. Each SerDes defines
1301- * what PLL it needs (ring or LC) while the PLL itself stores the current speed.
1302- */
1303-
1304- sbit = pll == RTPCS_SDS_PLL_TYPE_LC ? 8 : 12 ;
1305- speed_val = rtpcs_sds_read_bits (even_sds , 0x20 , 0x12 , sbit + 3 , sbit );
1306- if (speed_val < 0 )
1307- return speed_val ;
1308-
1309- /* bit 0 is force-bit, bits [3:1] are speed selector */
1310- * speed = (enum rtpcs_sds_pll_speed )(speed_val >> 1 );
1311- return 0 ;
1312- }
1313-
13141422static int rtpcs_930x_sds_set_pll_select (struct rtpcs_serdes * sds , enum rtpcs_sds_mode hw_mode ,
13151423 enum rtpcs_sds_pll_type pll )
13161424{
@@ -1323,21 +1431,17 @@ static int rtpcs_930x_sds_set_pll_select(struct rtpcs_serdes *sds, enum rtpcs_sd
13231431 return rtpcs_sds_write_bits (even_sds , 0x20 , 0x12 , pbit + 1 , pbit , (pll << 1 ) | BIT (0 ));
13241432}
13251433
1326- static int rtpcs_930x_sds_reset_cmu (struct rtpcs_serdes * sds )
1434+ static int rtpcs_930x_sds_reset_cmu (struct rtpcs_serdes * sds , enum rtpcs_sds_pll_type pll )
13271435{
13281436 struct rtpcs_serdes * even_sds = rtpcs_sds_get_even (sds );
13291437 int reset_sequence [4 ] = { 3 , 2 , 3 , 1 };
1330- enum rtpcs_sds_pll_type pll ;
13311438 int bit , i , ret ;
13321439
13331440 /*
13341441 * After the PLL speed has changed, the CMU must take over the new values. The models
13351442 * of the Otto platform have different reset sequences. Luckily it always boils down
13361443 * to flipping two bits in a special sequence.
13371444 */
1338- ret = rtpcs_930x_sds_get_pll_select (sds , & pll );
1339- if (ret < 0 )
1340- return ret ;
13411445
13421446 bit = pll == RTPCS_SDS_PLL_TYPE_LC ? 2 : 0 ;
13431447
@@ -1350,40 +1454,6 @@ static int rtpcs_930x_sds_reset_cmu(struct rtpcs_serdes *sds)
13501454 return 0 ;
13511455}
13521456
1353- static int rtpcs_930x_sds_set_pll_config (struct rtpcs_serdes * sds , enum rtpcs_sds_pll_type pll ,
1354- enum rtpcs_sds_pll_speed speed )
1355- {
1356- struct rtpcs_serdes * even_sds = rtpcs_sds_get_even (sds );
1357- int sbit = pll == RTPCS_SDS_PLL_TYPE_LC ? 8 : 12 ;
1358- int ret ;
1359-
1360- if (speed >= RTPCS_SDS_PLL_SPD_END )
1361- return - EINVAL ;
1362-
1363- if (pll >= RTPCS_SDS_PLL_TYPE_END )
1364- return - EINVAL ;
1365-
1366- if ((pll == RTPCS_SDS_PLL_TYPE_RING ) && (speed == RTPCS_SDS_PLL_SPD_10000 ))
1367- return - EINVAL ;
1368-
1369- /*
1370- * A SerDes clock can either be taken from the low speed ring PLL or the high speed
1371- * LC PLL. As it is unclear if disabling PLLs has any positive or negative effect,
1372- * always activate both.
1373- */
1374-
1375- ret = rtpcs_sds_write_bits (even_sds , 0x20 , 0x12 , 3 , 0 , 0xf );
1376- if (ret < 0 )
1377- return ret ;
1378-
1379- /* bit 0 is force-bit, bits [3:1] are speed selector */
1380- ret = rtpcs_sds_write_bits (even_sds , 0x20 , 0x12 , sbit + 3 , sbit , (speed << 1 ) | BIT (0 ));
1381- if (ret < 0 )
1382- return ret ;
1383-
1384- return rtpcs_930x_sds_reset_cmu (sds );
1385- }
1386-
13871457static int rtpcs_930x_sds_wait_clock_ready (struct rtpcs_serdes * sds )
13881458{
13891459 struct rtpcs_serdes * even_sds = rtpcs_sds_get_even (sds );
@@ -1441,14 +1511,14 @@ static int rtpcs_930x_sds_reconfigure_to_pll(struct rtpcs_serdes *sds, enum rtpc
14411511 if (ret < 0 )
14421512 return ret ;
14431513
1444- ret = rtpcs_930x_sds_get_pll_config (sds , old_pll , & speed );
1514+ ret = rtpcs_93xx_sds_get_pll_config (sds , old_pll , & speed );
14451515 if (ret < 0 )
14461516 return ret ;
14471517
14481518 rtpcs_930x_sds_set_power (sds , false);
14491519 __rtpcs_930x_sds_set_ip_mode (sds , RTPCS_930X_SDS_OFF );
14501520
1451- ret = rtpcs_930x_sds_set_pll_config (sds , pll , speed );
1521+ ret = rtpcs_93xx_sds_set_pll_config (sds , pll , speed );
14521522 if (ret < 0 )
14531523 return ret ;
14541524
@@ -1464,80 +1534,6 @@ static int rtpcs_930x_sds_reconfigure_to_pll(struct rtpcs_serdes *sds, enum rtpc
14641534 return 0 ;
14651535}
14661536
1467- static int rtpcs_930x_sds_config_cmu (struct rtpcs_serdes * sds ,
1468- enum rtpcs_sds_mode hw_mode )
1469- {
1470- struct rtpcs_serdes * nb_sds = rtpcs_sds_get_neighbor (sds );
1471- enum rtpcs_sds_pll_speed speed , neighbor_speed ;
1472- enum rtpcs_sds_pll_type pll , neighbor_pll ;
1473- bool speed_changed = true;
1474- int neighbor_mode , ret ;
1475-
1476- /*
1477- * A SerDes pair on the RTL930x is driven by two PLLs. A low speed ring PLL can generate
1478- * signals of 1.25G and 3.125G for link speeds of 1G/2.5G. A high speed LC PLL can
1479- * additionally generate a 10.3125G signal for 10G speeds. To drive the pair at different
1480- * speeds each SerDes must use its own PLL. But what if the SerDess attached to the ring
1481- * PLL suddenly needs 10G but the LC PLL is running at 1G? To avoid reconfiguring the
1482- * "partner" SerDes we must choose wisely what assignment serves the current needs. The
1483- * logic boils down to the following rules:
1484- *
1485- * - Use ring PLL for slow 1G speeds
1486- * - Use LC PLL for fast 10G speeds
1487- * - For 2.5G prefer ring over LC PLL
1488- *
1489- * However, when we want to configure 10G speed while the other SerDes is already using
1490- * the LC PLL for a slower speed, there is no way to avoid reconfiguration. Note that
1491- * this can even happen when the other SerDes is not actually in use, because changing
1492- * the state of a SerDes back to RTL930X_SDS_OFF is not (yet) implemented.
1493- */
1494-
1495- neighbor_mode = __rtpcs_930x_sds_get_ip_mode (nb_sds );
1496-
1497- ret = rtpcs_930x_sds_get_pll_select (sds , & neighbor_pll );
1498- if (ret < 0 )
1499- return ret ;
1500-
1501- ret = rtpcs_930x_sds_get_pll_config (nb_sds , neighbor_pll , & neighbor_speed );
1502- if (ret < 0 )
1503- return ret ;
1504-
1505- ret = rtpcs_sds_select_pll_speed (hw_mode , & speed );
1506- if (ret < 0 )
1507- return ret ;
1508-
1509- if (!neighbor_mode )
1510- pll = speed == RTPCS_SDS_PLL_SPD_10000 ? RTPCS_SDS_PLL_TYPE_LC
1511- : RTPCS_SDS_PLL_TYPE_RING ;
1512- else if (speed == neighbor_speed ) {
1513- speed_changed = false;
1514- pll = neighbor_pll ;
1515- } else if (neighbor_pll == RTPCS_SDS_PLL_TYPE_RING )
1516- pll = RTPCS_SDS_PLL_TYPE_LC ;
1517- else if (speed == RTPCS_SDS_PLL_SPD_10000 ) {
1518- pr_info ("%s: SDS %d needs LC PLL, reconfigure SDS %d to use ring PLL\n" ,
1519- __func__ , sds -> id , nb_sds -> id );
1520- ret = rtpcs_930x_sds_reconfigure_to_pll (nb_sds , RTPCS_SDS_PLL_TYPE_RING );
1521- if (ret < 0 )
1522- return ret ;
1523-
1524- pll = RTPCS_SDS_PLL_TYPE_LC ;
1525- } else
1526- pll = RTPCS_SDS_PLL_TYPE_RING ;
1527-
1528- if (speed_changed )
1529- ret = rtpcs_930x_sds_set_pll_config (sds , pll , speed );
1530-
1531- ret = rtpcs_930x_sds_set_pll_select (sds , hw_mode , pll );
1532- if (ret < 0 )
1533- return ret ;
1534-
1535- pr_info ("%s: SDS %d using %s PLL for mode %d\n" , __func__ , sds -> id ,
1536- pll == RTPCS_SDS_PLL_TYPE_LC ? "LC" : "ring" , hw_mode );
1537-
1538- return ret ;
1539- }
1540-
15411537static void rtpcs_930x_sds_reset_state_machine (struct rtpcs_serdes * sds )
15421538{
15431539 rtpcs_sds_write_bits (sds , 0x06 , 0x02 , 12 , 12 , 0x01 ); /* SM_RESET bit */
@@ -1627,7 +1623,7 @@ static int rtpcs_930x_sds_set_ip_mode(struct rtpcs_serdes *sds,
16271623 if (hw_mode == RTPCS_SDS_MODE_OFF )
16281624 return 0 ;
16291625
1630- ret = rtpcs_930x_sds_config_cmu (sds , hw_mode );
1626+ ret = rtpcs_93xx_sds_config_cmu (sds , hw_mode );
16311627 if (ret < 0 )
16321628 pr_err ("%s: SDS %d could not configure PLL for mode %d: %d\n" , __func__ ,
16331629 sds -> id , hw_mode , ret );
@@ -4300,6 +4296,10 @@ static const struct rtpcs_serdes_ops rtpcs_930x_sds_ops = {
43004296 .xsg_write = rtpcs_930x_sds_op_xsg_write ,
43014297 .set_autoneg = rtpcs_93xx_sds_set_autoneg ,
43024298 .restart_autoneg = rtpcs_generic_sds_restart_autoneg ,
4299+ .get_pll_select = rtpcs_930x_sds_get_pll_select ,
4300+ .set_pll_select = rtpcs_930x_sds_set_pll_select ,
4301+ .reset_cmu = rtpcs_930x_sds_reset_cmu ,
4302+ .reconfigure_to_pll = rtpcs_930x_sds_reconfigure_to_pll ,
43034303};
43044304
43054305static const struct rtpcs_sds_regs rtpcs_930x_sds_regs = {
0 commit comments