hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/phy/bcm7xxx.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * Broadcom BCM7xxx internal transceivers support.
34 *
45 * Copyright (C) 2014-2017 Broadcom
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
106 */
117
128 #include <linux/module.h>
....@@ -15,6 +11,7 @@
1511 #include "bcm-phy-lib.h"
1612 #include <linux/bitops.h>
1713 #include <linux/brcmphy.h>
14
+#include <linux/clk.h>
1815 #include <linux/mdio.h>
1916
2017 /* Broadcom BCM7xxx internal PHY registers */
....@@ -46,76 +43,10 @@
4643 #define MII_BCM7XXX_SHD_3_TL4 0x23
4744 #define MII_BCM7XXX_TL4_RST_MSK (BIT(2) | BIT(1))
4845
49
-/* 28nm only register definitions */
50
-#define MISC_ADDR(base, channel) base, channel
51
-
52
-#define DSP_TAP10 MISC_ADDR(0x0a, 0)
53
-#define PLL_PLLCTRL_1 MISC_ADDR(0x32, 1)
54
-#define PLL_PLLCTRL_2 MISC_ADDR(0x32, 2)
55
-#define PLL_PLLCTRL_4 MISC_ADDR(0x33, 0)
56
-
57
-#define AFE_RXCONFIG_0 MISC_ADDR(0x38, 0)
58
-#define AFE_RXCONFIG_1 MISC_ADDR(0x38, 1)
59
-#define AFE_RXCONFIG_2 MISC_ADDR(0x38, 2)
60
-#define AFE_RX_LP_COUNTER MISC_ADDR(0x38, 3)
61
-#define AFE_TX_CONFIG MISC_ADDR(0x39, 0)
62
-#define AFE_VDCA_ICTRL_0 MISC_ADDR(0x39, 1)
63
-#define AFE_VDAC_OTHERS_0 MISC_ADDR(0x39, 3)
64
-#define AFE_HPF_TRIM_OTHERS MISC_ADDR(0x3a, 0)
65
-
6646 struct bcm7xxx_phy_priv {
6747 u64 *stats;
48
+ struct clk *clk;
6849 };
69
-
70
-static void r_rc_cal_reset(struct phy_device *phydev)
71
-{
72
- /* Reset R_CAL/RC_CAL Engine */
73
- bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0010);
74
-
75
- /* Disable Reset R_AL/RC_CAL Engine */
76
- bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0000);
77
-}
78
-
79
-static int bcm7xxx_28nm_b0_afe_config_init(struct phy_device *phydev)
80
-{
81
- /* Increase VCO range to prevent unlocking problem of PLL at low
82
- * temp
83
- */
84
- bcm_phy_write_misc(phydev, PLL_PLLCTRL_1, 0x0048);
85
-
86
- /* Change Ki to 011 */
87
- bcm_phy_write_misc(phydev, PLL_PLLCTRL_2, 0x021b);
88
-
89
- /* Disable loading of TVCO buffer to bandgap, set bandgap trim
90
- * to 111
91
- */
92
- bcm_phy_write_misc(phydev, PLL_PLLCTRL_4, 0x0e20);
93
-
94
- /* Adjust bias current trim by -3 */
95
- bcm_phy_write_misc(phydev, DSP_TAP10, 0x690b);
96
-
97
- /* Switch to CORE_BASE1E */
98
- phy_write(phydev, MII_BRCM_CORE_BASE1E, 0xd);
99
-
100
- r_rc_cal_reset(phydev);
101
-
102
- /* write AFE_RXCONFIG_0 */
103
- bcm_phy_write_misc(phydev, AFE_RXCONFIG_0, 0xeb19);
104
-
105
- /* write AFE_RXCONFIG_1 */
106
- bcm_phy_write_misc(phydev, AFE_RXCONFIG_1, 0x9a3f);
107
-
108
- /* write AFE_RX_LP_COUNTER */
109
- bcm_phy_write_misc(phydev, AFE_RX_LP_COUNTER, 0x7fc0);
110
-
111
- /* write AFE_HPF_TRIM_OTHERS */
112
- bcm_phy_write_misc(phydev, AFE_HPF_TRIM_OTHERS, 0x000b);
113
-
114
- /* write AFTE_TX_CONFIG */
115
- bcm_phy_write_misc(phydev, AFE_TX_CONFIG, 0x0800);
116
-
117
- return 0;
118
-}
11950
12051 static int bcm7xxx_28nm_d0_afe_config_init(struct phy_device *phydev)
12152 {
....@@ -152,7 +83,7 @@
15283 bcm_phy_write_misc(phydev, DSP_TAP10, 0x011b);
15384
15485 /* Reset R_CAL/RC_CAL engine */
155
- r_rc_cal_reset(phydev);
86
+ bcm_phy_r_rc_cal_reset(phydev);
15687
15788 return 0;
15889 }
....@@ -180,7 +111,7 @@
180111 bcm_phy_write_misc(phydev, DSP_TAP10, 0x011b);
181112
182113 /* Reset R_CAL/RC_CAL engine */
183
- r_rc_cal_reset(phydev);
114
+ bcm_phy_r_rc_cal_reset(phydev);
184115
185116 return 0;
186117 }
....@@ -205,7 +136,7 @@
205136 /* Enable ffe zero detection for Vitesse interoperability */
206137 bcm_phy_write_misc(phydev, 0x26, 0x2, 0x0015);
207138
208
- r_rc_cal_reset(phydev);
139
+ bcm_phy_r_rc_cal_reset(phydev);
209140
210141 return 0;
211142 }
....@@ -236,7 +167,7 @@
236167 switch (rev) {
237168 case 0xa0:
238169 case 0xb0:
239
- ret = bcm7xxx_28nm_b0_afe_config_init(phydev);
170
+ ret = bcm_phy_28nm_a0b0_afe_config_init(phydev);
240171 break;
241172 case 0xd0:
242173 ret = bcm7xxx_28nm_d0_afe_config_init(phydev);
....@@ -254,6 +185,10 @@
254185 break;
255186 }
256187
188
+ if (ret)
189
+ return ret;
190
+
191
+ ret = bcm_phy_enable_jumbo(phydev);
257192 if (ret)
258193 return ret;
259194
....@@ -286,23 +221,35 @@
286221 return genphy_config_aneg(phydev);
287222 }
288223
289
-static int phy_set_clr_bits(struct phy_device *dev, int location,
290
- int set_mask, int clr_mask)
224
+static int __phy_set_clr_bits(struct phy_device *dev, int location,
225
+ int set_mask, int clr_mask)
291226 {
292227 int v, ret;
293228
294
- v = phy_read(dev, location);
229
+ v = __phy_read(dev, location);
295230 if (v < 0)
296231 return v;
297232
298233 v &= ~clr_mask;
299234 v |= set_mask;
300235
301
- ret = phy_write(dev, location, v);
236
+ ret = __phy_write(dev, location, v);
302237 if (ret < 0)
303238 return ret;
304239
305240 return v;
241
+}
242
+
243
+static int phy_set_clr_bits(struct phy_device *dev, int location,
244
+ int set_mask, int clr_mask)
245
+{
246
+ int ret;
247
+
248
+ mutex_lock(&dev->mdio.bus->mdio_lock);
249
+ ret = __phy_set_clr_bits(dev, location, set_mask, clr_mask);
250
+ mutex_unlock(&dev->mdio.bus->mdio_lock);
251
+
252
+ return ret;
306253 }
307254
308255 static int bcm7xxx_28nm_ephy_01_afe_config_init(struct phy_device *phydev)
....@@ -506,22 +453,22 @@
506453 return -EOPNOTSUPP;
507454
508455 /* set shadow mode 2 */
509
- ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST,
510
- MII_BCM7XXX_SHD_MODE_2, 0);
456
+ ret = __phy_set_clr_bits(phydev, MII_BCM7XXX_TEST,
457
+ MII_BCM7XXX_SHD_MODE_2, 0);
511458 if (ret < 0)
512459 return ret;
513460
514461 /* Access the desired shadow register address */
515
- ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, shd);
462
+ ret = __phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, shd);
516463 if (ret < 0)
517464 goto reset_shadow_mode;
518465
519
- ret = phy_read(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT);
466
+ ret = __phy_read(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT);
520467
521468 reset_shadow_mode:
522469 /* reset shadow mode 2 */
523
- phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0,
524
- MII_BCM7XXX_SHD_MODE_2);
470
+ __phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0,
471
+ MII_BCM7XXX_SHD_MODE_2);
525472 return ret;
526473 }
527474
....@@ -536,23 +483,23 @@
536483 return -EOPNOTSUPP;
537484
538485 /* set shadow mode 2 */
539
- ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST,
540
- MII_BCM7XXX_SHD_MODE_2, 0);
486
+ ret = __phy_set_clr_bits(phydev, MII_BCM7XXX_TEST,
487
+ MII_BCM7XXX_SHD_MODE_2, 0);
541488 if (ret < 0)
542489 return ret;
543490
544491 /* Access the desired shadow register address */
545
- ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, shd);
492
+ ret = __phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, shd);
546493 if (ret < 0)
547494 goto reset_shadow_mode;
548495
549496 /* Write the desired value in the shadow register */
550
- phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, val);
497
+ __phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, val);
551498
552499 reset_shadow_mode:
553500 /* reset shadow mode 2 */
554
- return phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0,
555
- MII_BCM7XXX_SHD_MODE_2);
501
+ return __phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0,
502
+ MII_BCM7XXX_SHD_MODE_2);
556503 }
557504
558505 static int bcm7xxx_28nm_ephy_resume(struct phy_device *phydev)
....@@ -680,6 +627,7 @@
680627 static int bcm7xxx_28nm_probe(struct phy_device *phydev)
681628 {
682629 struct bcm7xxx_phy_priv *priv;
630
+ int ret = 0;
683631
684632 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
685633 if (!priv)
....@@ -693,7 +641,30 @@
693641 if (!priv->stats)
694642 return -ENOMEM;
695643
696
- return 0;
644
+ priv->clk = devm_clk_get_optional(&phydev->mdio.dev, NULL);
645
+ if (IS_ERR(priv->clk))
646
+ return PTR_ERR(priv->clk);
647
+
648
+ ret = clk_prepare_enable(priv->clk);
649
+ if (ret)
650
+ return ret;
651
+
652
+ /* Dummy read to a register to workaround an issue upon reset where the
653
+ * internal inverter may not allow the first MDIO transaction to pass
654
+ * the MDIO management controller and make us return 0xffff for such
655
+ * reads. This is needed to ensure that any subsequent reads to the
656
+ * PHY will succeed.
657
+ */
658
+ phy_read(phydev, MII_BMSR);
659
+
660
+ return ret;
661
+}
662
+
663
+static void bcm7xxx_28nm_remove(struct phy_device *phydev)
664
+{
665
+ struct bcm7xxx_phy_priv *priv = phydev->priv;
666
+
667
+ clk_disable_unprepare(priv->clk);
697668 }
698669
699670 #define BCM7XXX_28NM_GPHY(_oui, _name) \
....@@ -701,7 +672,7 @@
701672 .phy_id = (_oui), \
702673 .phy_id_mask = 0xfffffff0, \
703674 .name = _name, \
704
- .features = PHY_GBIT_FEATURES, \
675
+ /* PHY_GBIT_FEATURES */ \
705676 .flags = PHY_IS_INTERNAL, \
706677 .config_init = bcm7xxx_28nm_config_init, \
707678 .resume = bcm7xxx_28nm_resume, \
....@@ -711,6 +682,7 @@
711682 .get_strings = bcm_phy_get_strings, \
712683 .get_stats = bcm7xxx_28nm_get_phy_stats, \
713684 .probe = bcm7xxx_28nm_probe, \
685
+ .remove = bcm7xxx_28nm_remove, \
714686 }
715687
716688 #define BCM7XXX_28NM_EPHY(_oui, _name) \
....@@ -718,7 +690,7 @@
718690 .phy_id = (_oui), \
719691 .phy_id_mask = 0xfffffff0, \
720692 .name = _name, \
721
- .features = PHY_BASIC_FEATURES, \
693
+ /* PHY_BASIC_FEATURES */ \
722694 .flags = PHY_IS_INTERNAL, \
723695 .config_init = bcm7xxx_28nm_ephy_config_init, \
724696 .resume = bcm7xxx_28nm_ephy_resume, \
....@@ -726,6 +698,7 @@
726698 .get_strings = bcm_phy_get_strings, \
727699 .get_stats = bcm7xxx_28nm_get_phy_stats, \
728700 .probe = bcm7xxx_28nm_probe, \
701
+ .remove = bcm7xxx_28nm_remove, \
729702 .read_mmd = bcm7xxx_28nm_ephy_read_mmd, \
730703 .write_mmd = bcm7xxx_28nm_ephy_write_mmd, \
731704 }
....@@ -735,7 +708,7 @@
735708 .phy_id = (_oui), \
736709 .phy_id_mask = 0xfffffff0, \
737710 .name = _name, \
738
- .features = PHY_BASIC_FEATURES, \
711
+ /* PHY_BASIC_FEATURES */ \
739712 .flags = PHY_IS_INTERNAL, \
740713 .soft_reset = genphy_soft_reset, \
741714 .config_init = bcm7xxx_config_init, \
....@@ -744,7 +717,9 @@
744717 }
745718
746719 static struct phy_driver bcm7xxx_driver[] = {
720
+ BCM7XXX_28NM_EPHY(PHY_ID_BCM72113, "Broadcom BCM72113"),
747721 BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"),
722
+ BCM7XXX_28NM_EPHY(PHY_ID_BCM7255, "Broadcom BCM7255"),
748723 BCM7XXX_28NM_EPHY(PHY_ID_BCM7260, "Broadcom BCM7260"),
749724 BCM7XXX_28NM_EPHY(PHY_ID_BCM7268, "Broadcom BCM7268"),
750725 BCM7XXX_28NM_EPHY(PHY_ID_BCM7271, "Broadcom BCM7271"),
....@@ -755,7 +730,6 @@
755730 BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"),
756731 BCM7XXX_28NM_GPHY(PHY_ID_BCM7439_2, "Broadcom BCM7439 (2)"),
757732 BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"),
758
- BCM7XXX_28NM_GPHY(PHY_ID_BCM_OMEGA, "Broadcom Omega Combo GPHY"),
759733 BCM7XXX_40NM_EPHY(PHY_ID_BCM7346, "Broadcom BCM7346"),
760734 BCM7XXX_40NM_EPHY(PHY_ID_BCM7362, "Broadcom BCM7362"),
761735 BCM7XXX_40NM_EPHY(PHY_ID_BCM7425, "Broadcom BCM7425"),
....@@ -764,7 +738,9 @@
764738 };
765739
766740 static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
741
+ { PHY_ID_BCM72113, 0xfffffff0 },
767742 { PHY_ID_BCM7250, 0xfffffff0, },
743
+ { PHY_ID_BCM7255, 0xfffffff0, },
768744 { PHY_ID_BCM7260, 0xfffffff0, },
769745 { PHY_ID_BCM7268, 0xfffffff0, },
770746 { PHY_ID_BCM7271, 0xfffffff0, },