1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * RealTek PHY drivers
4 *
5 * Copyright 2010-2011, 2015 Freescale Semiconductor, Inc.
6 * author Andy Fleming
7 * Copyright 2016 Karsten Merker <merker@debian.org>
8 */
9 #include <common.h>
10 #include <linux/bitops.h>
11 #include <phy.h>
12 #include <linux/delay.h>
13
14 #define PHY_RTL8211x_FORCE_MASTER BIT(1)
15 #define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2)
16 #define PHY_RTL8211F_FORCE_EEE_RXC_ON BIT(3)
17 #define PHY_RTL8201F_S700_RMII_TIMINGS BIT(4)
18
19 #define PHY_AUTONEGOTIATE_TIMEOUT 5000
20
21 /* RTL8211x 1000BASE-T Control Register */
22 #define MIIM_RTL8211x_CTRL1000T_MSCE BIT(12);
23 #define MIIM_RTL8211x_CTRL1000T_MASTER BIT(11);
24
25 /* RTL8211x PHY Status Register */
26 #define MIIM_RTL8211x_PHY_STATUS 0x11
27 #define MIIM_RTL8211x_PHYSTAT_SPEED 0xc000
28 #define MIIM_RTL8211x_PHYSTAT_GBIT 0x8000
29 #define MIIM_RTL8211x_PHYSTAT_100 0x4000
30 #define MIIM_RTL8211x_PHYSTAT_DUPLEX 0x2000
31 #define MIIM_RTL8211x_PHYSTAT_SPDDONE 0x0800
32 #define MIIM_RTL8211x_PHYSTAT_LINK 0x0400
33
34 /* RTL8211x PHY Interrupt Enable Register */
35 #define MIIM_RTL8211x_PHY_INER 0x12
36 #define MIIM_RTL8211x_PHY_INTR_ENA 0x9f01
37 #define MIIM_RTL8211x_PHY_INTR_DIS 0x0000
38
39 /* RTL8211x PHY Interrupt Status Register */
40 #define MIIM_RTL8211x_PHY_INSR 0x13
41
42 /* RTL8211F PHY Status Register */
43 #define MIIM_RTL8211F_PHY_STATUS 0x1a
44 #define MIIM_RTL8211F_AUTONEG_ENABLE 0x1000
45 #define MIIM_RTL8211F_PHYSTAT_SPEED 0x0030
46 #define MIIM_RTL8211F_PHYSTAT_GBIT 0x0020
47 #define MIIM_RTL8211F_PHYSTAT_100 0x0010
48 #define MIIM_RTL8211F_PHYSTAT_DUPLEX 0x0008
49 #define MIIM_RTL8211F_PHYSTAT_SPDDONE 0x0800
50 #define MIIM_RTL8211F_PHYSTAT_LINK 0x0004
51
52 #define MIIM_RTL8211E_CONFREG 0x1c
53 #define MIIM_RTL8211E_CONFREG_TXD 0x0002
54 #define MIIM_RTL8211E_CONFREG_RXD 0x0004
55 #define MIIM_RTL8211E_CONFREG_MAGIC 0xb400 /* Undocumented */
56
57 #define MIIM_RTL8211E_EXT_PAGE_SELECT 0x1e
58
59 #define MIIM_RTL8211F_PAGE_SELECT 0x1f
60 #define MIIM_RTL8211F_TX_DELAY 0x100
61 #define MIIM_RTL8211F_RX_DELAY 0x8
62 #define MIIM_RTL8211F_LCR 0x10
63
64 #define RTL8201F_RMSR 0x10
65
66 #define RMSR_RX_TIMING_SHIFT BIT(2)
67 #define RMSR_RX_TIMING_MASK GENMASK(7, 4)
68 #define RMSR_RX_TIMING_VAL 0x4
69 #define RMSR_TX_TIMING_SHIFT BIT(3)
70 #define RMSR_TX_TIMING_MASK GENMASK(11, 8)
71 #define RMSR_TX_TIMING_VAL 0x5
72
rtl8211f_phy_extread(struct phy_device * phydev,int addr,int devaddr,int regnum)73 static int rtl8211f_phy_extread(struct phy_device *phydev, int addr,
74 int devaddr, int regnum)
75 {
76 int oldpage = phy_read(phydev, MDIO_DEVAD_NONE,
77 MIIM_RTL8211F_PAGE_SELECT);
78 int val;
79
80 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr);
81 val = phy_read(phydev, MDIO_DEVAD_NONE, regnum);
82 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage);
83
84 return val;
85 }
86
rtl8211f_phy_extwrite(struct phy_device * phydev,int addr,int devaddr,int regnum,u16 val)87 static int rtl8211f_phy_extwrite(struct phy_device *phydev, int addr,
88 int devaddr, int regnum, u16 val)
89 {
90 int oldpage = phy_read(phydev, MDIO_DEVAD_NONE,
91 MIIM_RTL8211F_PAGE_SELECT);
92
93 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr);
94 phy_write(phydev, MDIO_DEVAD_NONE, regnum, val);
95 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage);
96
97 return 0;
98 }
99
rtl8211b_probe(struct phy_device * phydev)100 static int rtl8211b_probe(struct phy_device *phydev)
101 {
102 #ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER
103 phydev->flags |= PHY_RTL8211x_FORCE_MASTER;
104 #endif
105
106 return 0;
107 }
108
rtl8211e_probe(struct phy_device * phydev)109 static int rtl8211e_probe(struct phy_device *phydev)
110 {
111 #ifdef CONFIG_RTL8211E_PINE64_GIGABIT_FIX
112 phydev->flags |= PHY_RTL8211E_PINE64_GIGABIT_FIX;
113 #endif
114
115 return 0;
116 }
117
rtl8211f_probe(struct phy_device * phydev)118 static int rtl8211f_probe(struct phy_device *phydev)
119 {
120 #ifdef CONFIG_RTL8211F_PHY_FORCE_EEE_RXC_ON
121 phydev->flags |= PHY_RTL8211F_FORCE_EEE_RXC_ON;
122 #endif
123
124 return 0;
125 }
126
rtl8210f_probe(struct phy_device * phydev)127 static int rtl8210f_probe(struct phy_device *phydev)
128 {
129 #ifdef CONFIG_RTL8201F_PHY_S700_RMII_TIMINGS
130 phydev->flags |= PHY_RTL8201F_S700_RMII_TIMINGS;
131 #endif
132
133 return 0;
134 }
135
136 /* RealTek RTL8211x */
rtl8211x_config(struct phy_device * phydev)137 static int rtl8211x_config(struct phy_device *phydev)
138 {
139 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
140
141 /* mask interrupt at init; if the interrupt is
142 * needed indeed, it should be explicitly enabled
143 */
144 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER,
145 MIIM_RTL8211x_PHY_INTR_DIS);
146
147 if (phydev->flags & PHY_RTL8211x_FORCE_MASTER) {
148 unsigned int reg;
149
150 reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
151 /* force manual master/slave configuration */
152 reg |= MIIM_RTL8211x_CTRL1000T_MSCE;
153 /* force master mode */
154 reg |= MIIM_RTL8211x_CTRL1000T_MASTER;
155 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg);
156 }
157 if (phydev->flags & PHY_RTL8211E_PINE64_GIGABIT_FIX) {
158 unsigned int reg;
159
160 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
161 7);
162 phy_write(phydev, MDIO_DEVAD_NONE,
163 MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4);
164 reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG);
165 /* Ensure both internal delays are turned off */
166 reg &= ~(MIIM_RTL8211E_CONFREG_TXD | MIIM_RTL8211E_CONFREG_RXD);
167 /* Flip the magic undocumented bits */
168 reg |= MIIM_RTL8211E_CONFREG_MAGIC;
169 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg);
170 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
171 0);
172 }
173 /* read interrupt status just to clear it */
174 phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER);
175
176 genphy_config_aneg(phydev);
177
178 return 0;
179 }
180
181 /* RealTek RTL8201F */
rtl8201f_config(struct phy_device * phydev)182 static int rtl8201f_config(struct phy_device *phydev)
183 {
184 unsigned int reg;
185
186 if (phydev->flags & PHY_RTL8201F_S700_RMII_TIMINGS) {
187 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
188 7);
189 reg = phy_read(phydev, MDIO_DEVAD_NONE, RTL8201F_RMSR);
190 reg &= ~(RMSR_RX_TIMING_MASK | RMSR_TX_TIMING_MASK);
191 /* Set the needed Rx/Tx Timings for proper PHY operation */
192 reg |= (RMSR_RX_TIMING_VAL << RMSR_RX_TIMING_SHIFT)
193 | (RMSR_TX_TIMING_VAL << RMSR_TX_TIMING_SHIFT);
194 phy_write(phydev, MDIO_DEVAD_NONE, RTL8201F_RMSR, reg);
195 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
196 0);
197 }
198
199 genphy_config_aneg(phydev);
200
201 return 0;
202 }
203
rtl8211f_config(struct phy_device * phydev)204 static int rtl8211f_config(struct phy_device *phydev)
205 {
206 u16 reg;
207
208 if (phydev->flags & PHY_RTL8211F_FORCE_EEE_RXC_ON) {
209 unsigned int reg;
210
211 reg = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
212 reg &= ~MDIO_PCS_CTRL1_CLKSTOP_EN;
213 phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, reg);
214 }
215
216 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
217
218 phy_write(phydev, MDIO_DEVAD_NONE,
219 MIIM_RTL8211F_PAGE_SELECT, 0xd08);
220 reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x11);
221
222 /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
223 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
224 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
225 reg |= MIIM_RTL8211F_TX_DELAY;
226 else
227 reg &= ~MIIM_RTL8211F_TX_DELAY;
228
229 phy_write(phydev, MDIO_DEVAD_NONE, 0x11, reg);
230
231 /* enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it */
232 reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x15);
233 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
234 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
235 reg |= MIIM_RTL8211F_RX_DELAY;
236 else
237 reg &= ~MIIM_RTL8211F_RX_DELAY;
238 phy_write(phydev, MDIO_DEVAD_NONE, 0x15, reg);
239
240 /* restore to default page 0 */
241 phy_write(phydev, MDIO_DEVAD_NONE,
242 MIIM_RTL8211F_PAGE_SELECT, 0x0);
243
244 /* Set green LED for Link, yellow LED for Active */
245 phy_write(phydev, MDIO_DEVAD_NONE,
246 MIIM_RTL8211F_PAGE_SELECT, 0xd04);
247 phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f);
248 phy_write(phydev, MDIO_DEVAD_NONE,
249 MIIM_RTL8211F_PAGE_SELECT, 0x0);
250
251 genphy_config_aneg(phydev);
252
253 return 0;
254 }
255
rtl8211x_parse_status(struct phy_device * phydev)256 static int rtl8211x_parse_status(struct phy_device *phydev)
257 {
258 unsigned int speed;
259 unsigned int mii_reg;
260
261 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS);
262
263 if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
264 int i = 0;
265
266 /* in case of timeout ->link is cleared */
267 phydev->link = 1;
268 puts("Waiting for PHY realtime link");
269 while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
270 /* Timeout reached ? */
271 if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
272 puts(" TIMEOUT !\n");
273 phydev->link = 0;
274 break;
275 }
276
277 if ((i++ % 1000) == 0)
278 putc('.');
279 udelay(1000); /* 1 ms */
280 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
281 MIIM_RTL8211x_PHY_STATUS);
282 }
283 puts(" done\n");
284 udelay(500000); /* another 500 ms (results in faster booting) */
285 } else {
286 if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK)
287 phydev->link = 1;
288 else
289 phydev->link = 0;
290 }
291
292 if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX)
293 phydev->duplex = DUPLEX_FULL;
294 else
295 phydev->duplex = DUPLEX_HALF;
296
297 speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED);
298
299 switch (speed) {
300 case MIIM_RTL8211x_PHYSTAT_GBIT:
301 phydev->speed = SPEED_1000;
302 break;
303 case MIIM_RTL8211x_PHYSTAT_100:
304 phydev->speed = SPEED_100;
305 break;
306 default:
307 phydev->speed = SPEED_10;
308 }
309
310 return 0;
311 }
312
rtl8211f_parse_status(struct phy_device * phydev)313 static int rtl8211f_parse_status(struct phy_device *phydev)
314 {
315 unsigned int speed;
316 unsigned int mii_reg;
317 int i = 0;
318
319 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0xa43);
320 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PHY_STATUS);
321
322 phydev->link = 1;
323 while (!(mii_reg & MIIM_RTL8211F_PHYSTAT_LINK)) {
324 if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
325 puts(" TIMEOUT !\n");
326 phydev->link = 0;
327 break;
328 }
329
330 if ((i++ % 1000) == 0)
331 putc('.');
332 udelay(1000);
333 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
334 MIIM_RTL8211F_PHY_STATUS);
335 }
336
337 if (mii_reg & MIIM_RTL8211F_PHYSTAT_DUPLEX)
338 phydev->duplex = DUPLEX_FULL;
339 else
340 phydev->duplex = DUPLEX_HALF;
341
342 speed = (mii_reg & MIIM_RTL8211F_PHYSTAT_SPEED);
343
344 switch (speed) {
345 case MIIM_RTL8211F_PHYSTAT_GBIT:
346 phydev->speed = SPEED_1000;
347 break;
348 case MIIM_RTL8211F_PHYSTAT_100:
349 phydev->speed = SPEED_100;
350 break;
351 default:
352 phydev->speed = SPEED_10;
353 }
354
355 return 0;
356 }
357
rtl8211x_startup(struct phy_device * phydev)358 static int rtl8211x_startup(struct phy_device *phydev)
359 {
360 int ret;
361
362 /* Read the Status (2x to make sure link is right) */
363 ret = genphy_update_link(phydev);
364 if (ret)
365 return ret;
366
367 return rtl8211x_parse_status(phydev);
368 }
369
rtl8211e_startup(struct phy_device * phydev)370 static int rtl8211e_startup(struct phy_device *phydev)
371 {
372 int ret;
373
374 ret = genphy_update_link(phydev);
375 if (ret)
376 return ret;
377
378 return genphy_parse_link(phydev);
379 }
380
rtl8211f_startup(struct phy_device * phydev)381 static int rtl8211f_startup(struct phy_device *phydev)
382 {
383 int ret;
384
385 /* Read the Status (2x to make sure link is right) */
386 ret = genphy_update_link(phydev);
387 if (ret)
388 return ret;
389 /* Read the Status (2x to make sure link is right) */
390
391 return rtl8211f_parse_status(phydev);
392 }
393
394 /* Support for RTL8211B PHY */
395 static struct phy_driver RTL8211B_driver = {
396 .name = "RealTek RTL8211B",
397 .uid = 0x1cc912,
398 .mask = 0xffffff,
399 .features = PHY_GBIT_FEATURES,
400 .probe = &rtl8211b_probe,
401 .config = &rtl8211x_config,
402 .startup = &rtl8211x_startup,
403 .shutdown = &genphy_shutdown,
404 };
405
406 /* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */
407 static struct phy_driver RTL8211E_driver = {
408 .name = "RealTek RTL8211E",
409 .uid = 0x1cc915,
410 .mask = 0xffffff,
411 .features = PHY_GBIT_FEATURES,
412 .probe = &rtl8211e_probe,
413 .config = &rtl8211x_config,
414 .startup = &rtl8211e_startup,
415 .shutdown = &genphy_shutdown,
416 };
417
418 /* Support for RTL8211DN PHY */
419 static struct phy_driver RTL8211DN_driver = {
420 .name = "RealTek RTL8211DN",
421 .uid = 0x1cc914,
422 .mask = 0xffffff,
423 .features = PHY_GBIT_FEATURES,
424 .config = &rtl8211x_config,
425 .startup = &rtl8211x_startup,
426 .shutdown = &genphy_shutdown,
427 };
428
429 /* Support for RTL8211F PHY */
430 static struct phy_driver RTL8211F_driver = {
431 .name = "RealTek RTL8211F",
432 .uid = 0x1cc916,
433 .mask = 0xffffff,
434 .features = PHY_GBIT_FEATURES,
435 .probe = &rtl8211f_probe,
436 .config = &rtl8211f_config,
437 .startup = &rtl8211f_startup,
438 .shutdown = &genphy_shutdown,
439 .readext = &rtl8211f_phy_extread,
440 .writeext = &rtl8211f_phy_extwrite,
441 };
442
443 /* Support for RTL8201F PHY */
444 static struct phy_driver RTL8201F_driver = {
445 .name = "RealTek RTL8201F 10/100Mbps Ethernet",
446 .uid = 0x1cc816,
447 .mask = 0xffffff,
448 .features = PHY_BASIC_FEATURES,
449 .probe = &rtl8210f_probe,
450 .config = &rtl8201f_config,
451 .startup = &rtl8211e_startup,
452 .shutdown = &genphy_shutdown,
453 };
454
phy_realtek_init(void)455 int phy_realtek_init(void)
456 {
457 phy_register(&RTL8211B_driver);
458 phy_register(&RTL8211E_driver);
459 phy_register(&RTL8211F_driver);
460 phy_register(&RTL8211DN_driver);
461 phy_register(&RTL8201F_driver);
462
463 return 0;
464 }
465