bf8818976fb2a3963c867e9ab41969060384d5e3
[openwrt/staging/blogic.git] /
1 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
2 Subject: [PATCH 1/2] net: phy: cherry-pick Broadcom drivers updates from
3 v4.10-rc1
4 MIME-Version: 1.0
5 Content-Type: text/plain; charset=UTF-8
6 Content-Transfer-Encoding: 8bit
7
8 This includes following upstream commits:
9 5519da874ad0 net: phy: broadcom: Move bcm54xx_auxctl_{read, write} to common library
10 b14995ac2527 net: phy: broadcom: Add BCM54810 PHY entry
11 5b4e29005123 net: phy: broadcom: add bcm54xx_auxctl_read
12 d92ead16be40 net: phy: broadcom: Add support for BCM54612E
13 3cf25904fe46 net: phy: broadcom: Update Auxiliary Control Register macros
14
15 Other commits were skipped as they depend on other changes like
16 ETHTOOL_PHY_DOWNSHIFT & DOWNSHIFT_DEV_DISABLE and new APIs like
17 get_sset_count.
18
19 One exception was picking new regs from commit d06f78c4232d ("net: phy:
20 broadcom: Add support code for downshift/Wirespeed").
21
22 Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
23 ---
24
25 --- a/drivers/net/phy/Kconfig
26 +++ b/drivers/net/phy/Kconfig
27 @@ -77,7 +77,7 @@ config BROADCOM_PHY
28 select BCM_NET_PHYLIB
29 ---help---
30 Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464,
31 - BCM5481 and BCM5482 PHYs.
32 + BCM5481, BCM54810 and BCM5482 PHYs.
33
34 config BCM_CYGNUS_PHY
35 tristate "Drivers for Broadcom Cygnus SoC internal PHY"
36 --- a/drivers/net/phy/bcm-phy-lib.c
37 +++ b/drivers/net/phy/bcm-phy-lib.c
38 @@ -50,6 +50,23 @@ int bcm_phy_read_exp(struct phy_device *
39 }
40 EXPORT_SYMBOL_GPL(bcm_phy_read_exp);
41
42 +int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
43 +{
44 + /* The register must be written to both the Shadow Register Select and
45 + * the Shadow Read Register Selector
46 + */
47 + phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum |
48 + regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT);
49 + return phy_read(phydev, MII_BCM54XX_AUX_CTL);
50 +}
51 +EXPORT_SYMBOL_GPL(bcm54xx_auxctl_read);
52 +
53 +int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
54 +{
55 + return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
56 +}
57 +EXPORT_SYMBOL(bcm54xx_auxctl_write);
58 +
59 int bcm_phy_write_misc(struct phy_device *phydev,
60 u16 reg, u16 chl, u16 val)
61 {
62 --- a/drivers/net/phy/bcm-phy-lib.h
63 +++ b/drivers/net/phy/bcm-phy-lib.h
64 @@ -19,6 +19,9 @@
65 int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
66 int bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
67
68 +int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val);
69 +int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum);
70 +
71 int bcm_phy_write_misc(struct phy_device *phydev,
72 u16 reg, u16 chl, u16 value);
73 int bcm_phy_read_misc(struct phy_device *phydev,
74 --- a/drivers/net/phy/broadcom.c
75 +++ b/drivers/net/phy/broadcom.c
76 @@ -18,7 +18,7 @@
77 #include <linux/module.h>
78 #include <linux/phy.h>
79 #include <linux/brcmphy.h>
80 -
81 +#include <linux/of.h>
82
83 #define BRCM_PHY_MODEL(phydev) \
84 ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
85 @@ -30,9 +30,32 @@ MODULE_DESCRIPTION("Broadcom PHY driver"
86 MODULE_AUTHOR("Maciej W. Rozycki");
87 MODULE_LICENSE("GPL");
88
89 -static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
90 +static int bcm54810_config(struct phy_device *phydev)
91 {
92 - return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
93 + int rc, val;
94 +
95 + val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
96 + val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
97 + rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
98 + val);
99 + if (rc < 0)
100 + return rc;
101 +
102 + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
103 + val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
104 + val |= MII_BCM54XX_AUXCTL_MISC_WREN;
105 + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
106 + val);
107 + if (rc < 0)
108 + return rc;
109 +
110 + val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
111 + val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
112 + rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
113 + if (rc < 0)
114 + return rc;
115 +
116 + return 0;
117 }
118
119 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
120 @@ -207,6 +230,12 @@ static int bcm54xx_config_init(struct ph
121 (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
122 bcm54xx_adjust_rxrefclk(phydev);
123
124 + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
125 + err = bcm54810_config(phydev);
126 + if (err)
127 + return err;
128 + }
129 +
130 bcm54xx_phydsp_config(phydev);
131
132 return 0;
133 @@ -304,6 +333,7 @@ static int bcm5482_read_status(struct ph
134
135 static int bcm5481_config_aneg(struct phy_device *phydev)
136 {
137 + struct device_node *np = phydev->dev.of_node;
138 int ret;
139
140 /* Aneg firsly. */
141 @@ -334,6 +364,49 @@ static int bcm5481_config_aneg(struct ph
142 phy_write(phydev, 0x18, reg);
143 }
144
145 + if (of_property_read_bool(np, "enet-phy-lane-swap")) {
146 + /* Lane Swap - Undocumented register...magic! */
147 + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
148 + 0x11B);
149 + if (ret < 0)
150 + return ret;
151 + }
152 +
153 + return ret;
154 +}
155 +
156 +static int bcm54612e_config_aneg(struct phy_device *phydev)
157 +{
158 + int ret;
159 +
160 + /* First, auto-negotiate. */
161 + ret = genphy_config_aneg(phydev);
162 +
163 + /* Clear TX internal delay unless requested. */
164 + if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
165 + (phydev->interface != PHY_INTERFACE_MODE_RGMII_TXID)) {
166 + /* Disable TXD to GTXCLK clock delay (default set) */
167 + /* Bit 9 is the only field in shadow register 00011 */
168 + bcm_phy_write_shadow(phydev, 0x03, 0);
169 + }
170 +
171 + /* Clear RX internal delay unless requested. */
172 + if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
173 + (phydev->interface != PHY_INTERFACE_MODE_RGMII_RXID)) {
174 + u16 reg;
175 +
176 + /* Errata: reads require filling in the write selector field */
177 + bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
178 + MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC);
179 + reg = phy_read(phydev, MII_BCM54XX_AUX_CTL);
180 + /* Disable RXD to RXC delay (default set) */
181 + reg &= ~MII_BCM54XX_AUXCTL_MISC_RXD_RXC_SKEW;
182 + /* Clear shadow selector field */
183 + reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MASK;
184 + bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
185 + MII_BCM54XX_AUXCTL_MISC_WREN | reg);
186 + }
187 +
188 return ret;
189 }
190
191 @@ -488,6 +561,18 @@ static struct phy_driver broadcom_driver
192 .config_intr = bcm_phy_config_intr,
193 .driver = { .owner = THIS_MODULE },
194 }, {
195 + .phy_id = PHY_ID_BCM54612E,
196 + .phy_id_mask = 0xfffffff0,
197 + .name = "Broadcom BCM54612E",
198 + .features = PHY_GBIT_FEATURES |
199 + SUPPORTED_Pause | SUPPORTED_Asym_Pause,
200 + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
201 + .config_init = bcm54xx_config_init,
202 + .config_aneg = bcm54612e_config_aneg,
203 + .read_status = genphy_read_status,
204 + .ack_interrupt = bcm_phy_ack_intr,
205 + .config_intr = bcm_phy_config_intr,
206 +}, {
207 .phy_id = PHY_ID_BCM54616S,
208 .phy_id_mask = 0xfffffff0,
209 .name = "Broadcom BCM54616S",
210 @@ -527,6 +612,18 @@ static struct phy_driver broadcom_driver
211 .config_intr = bcm_phy_config_intr,
212 .driver = { .owner = THIS_MODULE },
213 }, {
214 + .phy_id = PHY_ID_BCM54810,
215 + .phy_id_mask = 0xfffffff0,
216 + .name = "Broadcom BCM54810",
217 + .features = PHY_GBIT_FEATURES |
218 + SUPPORTED_Pause | SUPPORTED_Asym_Pause,
219 + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
220 + .config_init = bcm54xx_config_init,
221 + .config_aneg = bcm5481_config_aneg,
222 + .read_status = genphy_read_status,
223 + .ack_interrupt = bcm_phy_ack_intr,
224 + .config_intr = bcm_phy_config_intr,
225 +}, {
226 .phy_id = PHY_ID_BCM5482,
227 .phy_id_mask = 0xfffffff0,
228 .name = "Broadcom BCM5482",
229 @@ -612,9 +709,11 @@ static struct mdio_device_id __maybe_unu
230 { PHY_ID_BCM5411, 0xfffffff0 },
231 { PHY_ID_BCM5421, 0xfffffff0 },
232 { PHY_ID_BCM5461, 0xfffffff0 },
233 + { PHY_ID_BCM54612E, 0xfffffff0 },
234 { PHY_ID_BCM54616S, 0xfffffff0 },
235 { PHY_ID_BCM5464, 0xfffffff0 },
236 { PHY_ID_BCM5481, 0xfffffff0 },
237 + { PHY_ID_BCM54810, 0xfffffff0 },
238 { PHY_ID_BCM5482, 0xfffffff0 },
239 { PHY_ID_BCM50610, 0xfffffff0 },
240 { PHY_ID_BCM50610M, 0xfffffff0 },
241 --- a/include/linux/brcmphy.h
242 +++ b/include/linux/brcmphy.h
243 @@ -13,11 +13,13 @@
244 #define PHY_ID_BCM5241 0x0143bc30
245 #define PHY_ID_BCMAC131 0x0143bc70
246 #define PHY_ID_BCM5481 0x0143bca0
247 +#define PHY_ID_BCM54810 0x03625d00
248 #define PHY_ID_BCM5482 0x0143bcb0
249 #define PHY_ID_BCM5411 0x00206070
250 #define PHY_ID_BCM5421 0x002060e0
251 #define PHY_ID_BCM5464 0x002060b0
252 #define PHY_ID_BCM5461 0x002060c0
253 +#define PHY_ID_BCM54612E 0x03625e60
254 #define PHY_ID_BCM54616S 0x03625d10
255 #define PHY_ID_BCM57780 0x03625d90
256
257 @@ -55,6 +57,7 @@
258 #define PHY_BRCM_EXT_IBND_TX_ENABLE 0x00002000
259 #define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000
260 #define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000
261 +
262 /* Broadcom BCM7xxx specific workarounds */
263 #define PHY_BRCM_7XXX_REV(x) (((x) >> 8) & 0xff)
264 #define PHY_BRCM_7XXX_PATCH(x) ((x) & 0xff)
265 @@ -105,11 +108,14 @@
266 #define MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA 0x0800
267
268 #define MII_BCM54XX_AUXCTL_MISC_WREN 0x8000
269 +#define MII_BCM54XX_AUXCTL_MISC_RXD_RXC_SKEW 0x0100
270 #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX 0x0200
271 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000
272 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007
273 +#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
274 +#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN (1 << 8)
275
276 -#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL 0x0000
277 +#define MII_BCM54XX_AUXCTL_SHDWSEL_MASK 0x0007
278
279 /*
280 * Broadcom LED source encodings. These are used in BCM5461, BCM5481,
281 @@ -124,6 +130,7 @@
282 #define BCM_LED_SRC_INTR 0x6
283 #define BCM_LED_SRC_QUALITY 0x7
284 #define BCM_LED_SRC_RCVLED 0x8
285 +#define BCM_LED_SRC_WIRESPEED 0x9
286 #define BCM_LED_SRC_MULTICOLOR1 0xa
287 #define BCM_LED_SRC_OPENSHORT 0xb
288 #define BCM_LED_SRC_OFF 0xe /* Tied high */
289 @@ -135,6 +142,14 @@
290 * Shadow values go into bits [14:10] of register 0x1c to select a shadow
291 * register to access.
292 */
293 +
294 +/* 00100: Reserved control register 2 */
295 +#define BCM54XX_SHD_SCR2 0x04
296 +#define BCM54XX_SHD_SCR2_WSPD_RTRY_DIS 0x100
297 +#define BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT 2
298 +#define BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET 2
299 +#define BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK 0x7
300 +
301 /* 00101: Spare Control Register 3 */
302 #define BCM54XX_SHD_SCR3 0x05
303 #define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001
304 @@ -189,6 +204,12 @@
305 #define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */
306 #define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */
307
308 +/* BCM54810 Registers */
309 +#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL (MII_BCM54XX_EXP_SEL_ER + 0x90)
310 +#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN (1 << 0)
311 +#define BCM54810_SHD_CLK_CTL 0x3
312 +#define BCM54810_SHD_CLK_CTL_GTXCLK_EN (1 << 9)
313 +
314
315 /*****************************************************************************/
316 /* Fast Ethernet Transceiver definitions. */