10
10
#include <linux/kernel.h>
11
11
#include <linux/module.h>
12
12
#include <linux/phy.h>
13
+ #include <linux/of.h>
13
14
14
15
#define PHY_ID_YT8511 0x0000010a
15
16
#define PHY_ID_YT8521 0x0000011a
187
188
* 1b1 use inverted tx_clk_rgmii.
188
189
*/
189
190
#define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14)
190
- /* TX Gig-E Delay is bits 3:0, default 0x1
191
- * TX Fast-E Delay is bits 7:4, default 0xf
192
- * RX Delay is bits 13:10, default 0x0
193
- * Delay = 150ps * N
194
- * On = 2250ps, off = 0ps
195
- */
196
191
#define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10)
197
- #define YT8521_RC1R_RX_DELAY_EN (0xF << 10)
198
- #define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10)
199
192
#define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
200
- #define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4)
201
- #define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4)
202
193
#define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
203
- #define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0)
204
- #define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0)
205
194
#define YT8521_RC1R_RGMII_0_000_NS 0
206
195
#define YT8521_RC1R_RGMII_0_150_NS 1
207
196
#define YT8521_RC1R_RGMII_0_300_NS 2
274
263
275
264
/* Extended Register end */
276
265
266
+ #define YTPHY_DTS_OUTPUT_CLK_DIS 0
267
+ #define YTPHY_DTS_OUTPUT_CLK_25M 25000000
268
+ #define YTPHY_DTS_OUTPUT_CLK_125M 125000000
269
+
277
270
struct yt8521_priv {
278
271
/* combo_advertising is used for case of YT8521 in combo mode,
279
272
* this means that yt8521 may work in utp or fiber mode which depends
@@ -640,6 +633,142 @@ static int yt8521_write_page(struct phy_device *phydev, int page)
640
633
return ytphy_modify_ext (phydev , YT8521_REG_SPACE_SELECT_REG , mask , set );
641
634
};
642
635
636
+ /**
637
+ * struct ytphy_cfg_reg_map - map a config value to a register value
638
+ * @cfg: value in device configuration
639
+ * @reg: value in the register
640
+ */
641
+ struct ytphy_cfg_reg_map {
642
+ u32 cfg ;
643
+ u32 reg ;
644
+ };
645
+
646
+ static const struct ytphy_cfg_reg_map ytphy_rgmii_delays [] = {
647
+ /* for tx delay / rx delay with YT8521_CCR_RXC_DLY_EN is not set. */
648
+ { 0 , YT8521_RC1R_RGMII_0_000_NS },
649
+ { 150 , YT8521_RC1R_RGMII_0_150_NS },
650
+ { 300 , YT8521_RC1R_RGMII_0_300_NS },
651
+ { 450 , YT8521_RC1R_RGMII_0_450_NS },
652
+ { 600 , YT8521_RC1R_RGMII_0_600_NS },
653
+ { 750 , YT8521_RC1R_RGMII_0_750_NS },
654
+ { 900 , YT8521_RC1R_RGMII_0_900_NS },
655
+ { 1050 , YT8521_RC1R_RGMII_1_050_NS },
656
+ { 1200 , YT8521_RC1R_RGMII_1_200_NS },
657
+ { 1350 , YT8521_RC1R_RGMII_1_350_NS },
658
+ { 1500 , YT8521_RC1R_RGMII_1_500_NS },
659
+ { 1650 , YT8521_RC1R_RGMII_1_650_NS },
660
+ { 1800 , YT8521_RC1R_RGMII_1_800_NS },
661
+ { 1950 , YT8521_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */
662
+ { 2100 , YT8521_RC1R_RGMII_2_100_NS },
663
+ { 2250 , YT8521_RC1R_RGMII_2_250_NS },
664
+
665
+ /* only for rx delay with YT8521_CCR_RXC_DLY_EN is set. */
666
+ { 0 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_0_000_NS },
667
+ { 150 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_0_150_NS },
668
+ { 300 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_0_300_NS },
669
+ { 450 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_0_450_NS },
670
+ { 600 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_0_600_NS },
671
+ { 750 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_0_750_NS },
672
+ { 900 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_0_900_NS },
673
+ { 1050 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_1_050_NS },
674
+ { 1200 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_1_200_NS },
675
+ { 1350 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_1_350_NS },
676
+ { 1500 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_1_500_NS },
677
+ { 1650 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_1_650_NS },
678
+ { 1800 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_1_800_NS },
679
+ { 1950 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_1_950_NS },
680
+ { 2100 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_2_100_NS },
681
+ { 2250 + YT8521_CCR_RXC_DLY_1_900_NS , YT8521_RC1R_RGMII_2_250_NS }
682
+ };
683
+
684
+ static u32 ytphy_get_delay_reg_value (struct phy_device * phydev ,
685
+ const char * prop_name ,
686
+ const struct ytphy_cfg_reg_map * tbl ,
687
+ int tb_size ,
688
+ u16 * rxc_dly_en ,
689
+ u32 dflt )
690
+ {
691
+ struct device_node * node = phydev -> mdio .dev .of_node ;
692
+ int tb_size_half = tb_size / 2 ;
693
+ u32 val ;
694
+ int i ;
695
+
696
+ if (of_property_read_u32 (node , prop_name , & val ))
697
+ goto err_dts_val ;
698
+
699
+ /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
700
+ * tb_size is valid.
701
+ */
702
+ if (!rxc_dly_en )
703
+ tb_size = tb_size_half ;
704
+
705
+ for (i = 0 ; i < tb_size ; i ++ ) {
706
+ if (tbl [i ].cfg == val ) {
707
+ if (rxc_dly_en && i < tb_size_half )
708
+ * rxc_dly_en = 0 ;
709
+ return tbl [i ].reg ;
710
+ }
711
+ }
712
+
713
+ phydev_warn (phydev , "Unsupported value %d for %s using default (%u)\n" ,
714
+ val , prop_name , dflt );
715
+
716
+ err_dts_val :
717
+ /* when rxc_dly_en is not NULL, it is get the delay for rx.
718
+ * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
719
+ * so YT8521_CCR_RXC_DLY_EN should not be set.
720
+ */
721
+ if (rxc_dly_en )
722
+ * rxc_dly_en = 0 ;
723
+
724
+ return dflt ;
725
+ }
726
+
727
+ static int ytphy_rgmii_clk_delay_config (struct phy_device * phydev )
728
+ {
729
+ int tb_size = ARRAY_SIZE (ytphy_rgmii_delays );
730
+ u16 rxc_dly_en = YT8521_CCR_RXC_DLY_EN ;
731
+ u32 rx_reg , tx_reg ;
732
+ u16 mask , val = 0 ;
733
+ int ret ;
734
+
735
+ rx_reg = ytphy_get_delay_reg_value (phydev , "rx-internal-delay-ps" ,
736
+ ytphy_rgmii_delays , tb_size ,
737
+ & rxc_dly_en ,
738
+ YT8521_RC1R_RGMII_1_950_NS );
739
+ tx_reg = ytphy_get_delay_reg_value (phydev , "tx-internal-delay-ps" ,
740
+ ytphy_rgmii_delays , tb_size , NULL ,
741
+ YT8521_RC1R_RGMII_1_950_NS );
742
+
743
+ switch (phydev -> interface ) {
744
+ case PHY_INTERFACE_MODE_RGMII :
745
+ rxc_dly_en = 0 ;
746
+ break ;
747
+ case PHY_INTERFACE_MODE_RGMII_RXID :
748
+ val |= FIELD_PREP (YT8521_RC1R_RX_DELAY_MASK , rx_reg );
749
+ break ;
750
+ case PHY_INTERFACE_MODE_RGMII_TXID :
751
+ rxc_dly_en = 0 ;
752
+ val |= FIELD_PREP (YT8521_RC1R_GE_TX_DELAY_MASK , tx_reg );
753
+ break ;
754
+ case PHY_INTERFACE_MODE_RGMII_ID :
755
+ val |= FIELD_PREP (YT8521_RC1R_RX_DELAY_MASK , rx_reg ) |
756
+ FIELD_PREP (YT8521_RC1R_GE_TX_DELAY_MASK , tx_reg );
757
+ break ;
758
+ default : /* do not support other modes */
759
+ return - EOPNOTSUPP ;
760
+ }
761
+
762
+ ret = ytphy_modify_ext (phydev , YT8521_CHIP_CONFIG_REG ,
763
+ YT8521_CCR_RXC_DLY_EN , rxc_dly_en );
764
+ if (ret < 0 )
765
+ return ret ;
766
+
767
+ /* Generally, it is not necessary to adjust YT8521_RC1R_FE_TX_DELAY */
768
+ mask = YT8521_RC1R_RX_DELAY_MASK | YT8521_RC1R_GE_TX_DELAY_MASK ;
769
+ return ytphy_modify_ext (phydev , YT8521_RGMII_CONFIG1_REG , mask , val );
770
+ }
771
+
643
772
/**
644
773
* yt8521_probe() - read chip config then set suitable polling_mode
645
774
* @phydev: a pointer to a &struct phy_device
@@ -648,9 +777,12 @@ static int yt8521_write_page(struct phy_device *phydev, int page)
648
777
*/
649
778
static int yt8521_probe (struct phy_device * phydev )
650
779
{
780
+ struct device_node * node = phydev -> mdio .dev .of_node ;
651
781
struct device * dev = & phydev -> mdio .dev ;
652
782
struct yt8521_priv * priv ;
653
783
int chip_config ;
784
+ u16 mask , val ;
785
+ u32 freq ;
654
786
int ret ;
655
787
656
788
priv = devm_kzalloc (dev , sizeof (* priv ), GFP_KERNEL );
@@ -695,7 +827,45 @@ static int yt8521_probe(struct phy_device *phydev)
695
827
return ret ;
696
828
}
697
829
698
- return 0 ;
830
+ if (of_property_read_u32 (node , "motorcomm,clk-out-frequency-hz" , & freq ))
831
+ freq = YTPHY_DTS_OUTPUT_CLK_DIS ;
832
+
833
+ if (phydev -> drv -> phy_id == PHY_ID_YT8521 ) {
834
+ switch (freq ) {
835
+ case YTPHY_DTS_OUTPUT_CLK_DIS :
836
+ mask = YT8521_SCR_SYNCE_ENABLE ;
837
+ val = 0 ;
838
+ break ;
839
+ case YTPHY_DTS_OUTPUT_CLK_25M :
840
+ mask = YT8521_SCR_SYNCE_ENABLE |
841
+ YT8521_SCR_CLK_SRC_MASK |
842
+ YT8521_SCR_CLK_FRE_SEL_125M ;
843
+ val = YT8521_SCR_SYNCE_ENABLE |
844
+ FIELD_PREP (YT8521_SCR_CLK_SRC_MASK ,
845
+ YT8521_SCR_CLK_SRC_REF_25M );
846
+ break ;
847
+ case YTPHY_DTS_OUTPUT_CLK_125M :
848
+ mask = YT8521_SCR_SYNCE_ENABLE |
849
+ YT8521_SCR_CLK_SRC_MASK |
850
+ YT8521_SCR_CLK_FRE_SEL_125M ;
851
+ val = YT8521_SCR_SYNCE_ENABLE |
852
+ YT8521_SCR_CLK_FRE_SEL_125M |
853
+ FIELD_PREP (YT8521_SCR_CLK_SRC_MASK ,
854
+ YT8521_SCR_CLK_SRC_PLL_125M );
855
+ break ;
856
+ default :
857
+ phydev_warn (phydev , "Freq err:%u\n" , freq );
858
+ return - EINVAL ;
859
+ }
860
+ } else if (phydev -> drv -> phy_id == PHY_ID_YT8531S ) {
861
+ return 0 ;
862
+ } else {
863
+ phydev_warn (phydev , "PHY id err\n" );
864
+ return - EINVAL ;
865
+ }
866
+
867
+ return ytphy_modify_ext_with_lock (phydev , YTPHY_SYNCE_CFG_REG , mask ,
868
+ val );
699
869
}
700
870
701
871
/**
@@ -1180,61 +1350,36 @@ static int yt8521_resume(struct phy_device *phydev)
1180
1350
*/
1181
1351
static int yt8521_config_init (struct phy_device * phydev )
1182
1352
{
1353
+ struct device_node * node = phydev -> mdio .dev .of_node ;
1183
1354
int old_page ;
1184
1355
int ret = 0 ;
1185
- u16 val ;
1186
1356
1187
1357
old_page = phy_select_page (phydev , YT8521_RSSR_UTP_SPACE );
1188
1358
if (old_page < 0 )
1189
1359
goto err_restore_page ;
1190
1360
1191
- switch (phydev -> interface ) {
1192
- case PHY_INTERFACE_MODE_RGMII :
1193
- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS ;
1194
- val |= YT8521_RC1R_RX_DELAY_DIS ;
1195
- break ;
1196
- case PHY_INTERFACE_MODE_RGMII_RXID :
1197
- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS ;
1198
- val |= YT8521_RC1R_RX_DELAY_EN ;
1199
- break ;
1200
- case PHY_INTERFACE_MODE_RGMII_TXID :
1201
- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN ;
1202
- val |= YT8521_RC1R_RX_DELAY_DIS ;
1203
- break ;
1204
- case PHY_INTERFACE_MODE_RGMII_ID :
1205
- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN ;
1206
- val |= YT8521_RC1R_RX_DELAY_EN ;
1207
- break ;
1208
- case PHY_INTERFACE_MODE_SGMII :
1209
- break ;
1210
- default : /* do not support other modes */
1211
- ret = - EOPNOTSUPP ;
1212
- goto err_restore_page ;
1213
- }
1214
-
1215
1361
/* set rgmii delay mode */
1216
1362
if (phydev -> interface != PHY_INTERFACE_MODE_SGMII ) {
1217
- ret = ytphy_modify_ext (phydev , YT8521_RGMII_CONFIG1_REG ,
1218
- (YT8521_RC1R_RX_DELAY_MASK |
1219
- YT8521_RC1R_FE_TX_DELAY_MASK |
1220
- YT8521_RC1R_GE_TX_DELAY_MASK ),
1221
- val );
1363
+ ret = ytphy_rgmii_clk_delay_config (phydev );
1222
1364
if (ret < 0 )
1223
1365
goto err_restore_page ;
1224
1366
}
1225
1367
1226
- /* disable auto sleep */
1227
- ret = ytphy_modify_ext (phydev , YT8521_EXTREG_SLEEP_CONTROL1_REG ,
1228
- YT8521_ESC1R_SLEEP_SW , 0 );
1229
- if (ret < 0 )
1230
- goto err_restore_page ;
1231
-
1232
- /* enable RXC clock when no wire plug */
1233
- ret = ytphy_modify_ext (phydev , YT8521_CLOCK_GATING_REG ,
1234
- YT8521_CGR_RX_CLK_EN , 0 );
1235
- if (ret < 0 )
1236
- goto err_restore_page ;
1368
+ if (of_property_read_bool (node , "motorcomm,auto-sleep-disabled" )) {
1369
+ /* disable auto sleep */
1370
+ ret = ytphy_modify_ext (phydev , YT8521_EXTREG_SLEEP_CONTROL1_REG ,
1371
+ YT8521_ESC1R_SLEEP_SW , 0 );
1372
+ if (ret < 0 )
1373
+ goto err_restore_page ;
1374
+ }
1237
1375
1376
+ if (of_property_read_bool (node , "motorcomm,keep-pll-enabled" )) {
1377
+ /* enable RXC clock when no wire plug */
1378
+ ret = ytphy_modify_ext (phydev , YT8521_CLOCK_GATING_REG ,
1379
+ YT8521_CGR_RX_CLK_EN , 0 );
1380
+ if (ret < 0 )
1381
+ goto err_restore_page ;
1382
+ }
1238
1383
err_restore_page :
1239
1384
return phy_restore_page (phydev , old_page , ret );
1240
1385
}
0 commit comments