kernel: add fix for bgmac with B50212E B1 PHY
[openwrt/openwrt.git] / target / linux / generic / patches-4.4 / 078-0004-net-phy-cherry-pick-Broadcom-drivers-updates-from-v4.patch
1 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
2 Subject: [PATCH] net: phy: cherry-pick Broadcom drivers updates from v4.11
3 MIME-Version: 1.0
4 Content-Type: text/plain; charset=UTF-8
5 Content-Transfer-Encoding: 8bit
6
7 Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
8 ---
9
10 --- a/drivers/net/phy/broadcom.c
11 +++ b/drivers/net/phy/broadcom.c
12 @@ -30,6 +30,50 @@ MODULE_DESCRIPTION("Broadcom PHY driver"
13 MODULE_AUTHOR("Maciej W. Rozycki");
14 MODULE_LICENSE("GPL");
15
16 +static int bcm54210e_config_init(struct phy_device *phydev)
17 +{
18 + int val;
19 +
20 + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
21 + val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
22 + val |= MII_BCM54XX_AUXCTL_MISC_WREN;
23 + bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, val);
24 +
25 + val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
26 + val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
27 + bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
28 +
29 + return 0;
30 +}
31 +
32 +static int bcm54612e_config_init(struct phy_device *phydev)
33 +{
34 + /* Clear TX internal delay unless requested. */
35 + if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
36 + (phydev->interface != PHY_INTERFACE_MODE_RGMII_TXID)) {
37 + /* Disable TXD to GTXCLK clock delay (default set) */
38 + /* Bit 9 is the only field in shadow register 00011 */
39 + bcm_phy_write_shadow(phydev, 0x03, 0);
40 + }
41 +
42 + /* Clear RX internal delay unless requested. */
43 + if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
44 + (phydev->interface != PHY_INTERFACE_MODE_RGMII_RXID)) {
45 + u16 reg;
46 +
47 + reg = bcm54xx_auxctl_read(phydev,
48 + MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
49 + /* Disable RXD to RXC delay (default set) */
50 + reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
51 + /* Clear shadow selector field */
52 + reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MASK;
53 + bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
54 + MII_BCM54XX_AUXCTL_MISC_WREN | reg);
55 + }
56 +
57 + return 0;
58 +}
59 +
60 static int bcm54810_config(struct phy_device *phydev)
61 {
62 int rc, val;
63 @@ -230,7 +274,15 @@ static int bcm54xx_config_init(struct ph
64 (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
65 bcm54xx_adjust_rxrefclk(phydev);
66
67 - if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
68 + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E) {
69 + err = bcm54210e_config_init(phydev);
70 + if (err)
71 + return err;
72 + } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) {
73 + err = bcm54612e_config_init(phydev);
74 + if (err)
75 + return err;
76 + } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
77 err = bcm54810_config(phydev);
78 if (err)
79 return err;
80 @@ -375,41 +427,6 @@ static int bcm5481_config_aneg(struct ph
81 return ret;
82 }
83
84 -static int bcm54612e_config_aneg(struct phy_device *phydev)
85 -{
86 - int ret;
87 -
88 - /* First, auto-negotiate. */
89 - ret = genphy_config_aneg(phydev);
90 -
91 - /* Clear TX internal delay unless requested. */
92 - if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
93 - (phydev->interface != PHY_INTERFACE_MODE_RGMII_TXID)) {
94 - /* Disable TXD to GTXCLK clock delay (default set) */
95 - /* Bit 9 is the only field in shadow register 00011 */
96 - bcm_phy_write_shadow(phydev, 0x03, 0);
97 - }
98 -
99 - /* Clear RX internal delay unless requested. */
100 - if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
101 - (phydev->interface != PHY_INTERFACE_MODE_RGMII_RXID)) {
102 - u16 reg;
103 -
104 - /* Errata: reads require filling in the write selector field */
105 - bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
106 - MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC);
107 - reg = phy_read(phydev, MII_BCM54XX_AUX_CTL);
108 - /* Disable RXD to RXC delay (default set) */
109 - reg &= ~MII_BCM54XX_AUXCTL_MISC_RXD_RXC_SKEW;
110 - /* Clear shadow selector field */
111 - reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MASK;
112 - bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
113 - MII_BCM54XX_AUXCTL_MISC_WREN | reg);
114 - }
115 -
116 - return ret;
117 -}
118 -
119 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
120 {
121 int val;
122 @@ -548,6 +565,19 @@ static struct phy_driver broadcom_driver
123 .config_intr = bcm_phy_config_intr,
124 .driver = { .owner = THIS_MODULE },
125 }, {
126 + .phy_id = PHY_ID_BCM54210E,
127 + .phy_id_mask = 0xfffffff0,
128 + .name = "Broadcom BCM54210E",
129 + .features = PHY_GBIT_FEATURES |
130 + SUPPORTED_Pause | SUPPORTED_Asym_Pause,
131 + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
132 + .config_init = bcm54xx_config_init,
133 + .config_aneg = genphy_config_aneg,
134 + .read_status = genphy_read_status,
135 + .ack_interrupt = bcm_phy_ack_intr,
136 + .config_intr = bcm_phy_config_intr,
137 + .driver = { .owner = THIS_MODULE },
138 +}, {
139 .phy_id = PHY_ID_BCM5461,
140 .phy_id_mask = 0xfffffff0,
141 .name = "Broadcom BCM5461",
142 @@ -568,7 +598,7 @@ static struct phy_driver broadcom_driver
143 SUPPORTED_Pause | SUPPORTED_Asym_Pause,
144 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
145 .config_init = bcm54xx_config_init,
146 - .config_aneg = bcm54612e_config_aneg,
147 + .config_aneg = genphy_config_aneg,
148 .read_status = genphy_read_status,
149 .ack_interrupt = bcm_phy_ack_intr,
150 .config_intr = bcm_phy_config_intr,
151 @@ -710,6 +740,7 @@ module_phy_driver(broadcom_drivers);
152 static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
153 { PHY_ID_BCM5411, 0xfffffff0 },
154 { PHY_ID_BCM5421, 0xfffffff0 },
155 + { PHY_ID_BCM54210E, 0xfffffff0 },
156 { PHY_ID_BCM5461, 0xfffffff0 },
157 { PHY_ID_BCM54612E, 0xfffffff0 },
158 { PHY_ID_BCM54616S, 0xfffffff0 },
159 --- a/include/linux/brcmphy.h
160 +++ b/include/linux/brcmphy.h
161 @@ -17,6 +17,7 @@
162 #define PHY_ID_BCM5482 0x0143bcb0
163 #define PHY_ID_BCM5411 0x00206070
164 #define PHY_ID_BCM5421 0x002060e0
165 +#define PHY_ID_BCM54210E 0x600d84a0
166 #define PHY_ID_BCM5464 0x002060b0
167 #define PHY_ID_BCM5461 0x002060c0
168 #define PHY_ID_BCM54612E 0x03625e60