1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Driver for Motorcomm PHYs
4 *
5 * Author: Peter Geis <pgwipeout@gmail.com>
6 */
7
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/netdevice.h>
11 #include <linux/of_device.h>
12 #include <linux/phy.h>
13
14 #define PHY_ID_YT8511 0x0000010a
15 #define PHY_ID_YT8512 0x00000118
16 #define PHY_ID_YT8512B 0x00000128
17 #define PHY_ID_YT8531S 0x4f51e91a
18 #define PHY_ID_YT8531 0x4f51e91b
19
20 #define YT8511_PAGE_SELECT 0x1e
21 #define YT8511_PAGE 0x1f
22 #define YT8511_EXT_CLK_GATE 0x0c
23 #define YT8511_EXT_DELAY_DRIVE 0x0d
24 #define YT8511_EXT_SLEEP_CTRL 0x27
25
26 /* 2b00 25m from pll
27 * 2b01 25m from xtl *default*
28 * 2b10 62.m from pll
29 * 2b11 125m from pll
30 */
31 #define YT8511_CLK_125M (BIT(2) | BIT(1))
32 #define YT8511_PLLON_SLP BIT(14)
33
34 /* RX Delay enabled = 1.8ns 1000T, 8ns 10/100T */
35 #define YT8511_DELAY_RX BIT(0)
36
37 /* TX Gig-E Delay is bits 7:4, default 0x5
38 * TX Fast-E Delay is bits 15:12, default 0xf
39 * Delay = 150ps * N - 250ps
40 * On = 2000ps, off = 50ps
41 */
42 #define YT8511_DELAY_GE_TX_EN (0xf << 4)
43 #define YT8511_DELAY_GE_TX_DIS (0x2 << 4)
44 #define YT8511_DELAY_FE_TX_EN (0xf << 12)
45 #define YT8511_DELAY_FE_TX_DIS (0x2 << 12)
46
47 #define YT8512_EXTREG_AFE_PLL 0x50
48 #define YT8512_EXTREG_EXTEND_COMBO 0x4000
49 #define YT8512_EXTREG_LED0 0x40c0
50 #define YT8512_EXTREG_LED1 0x40c3
51
52 #define YT8512_EXTREG_SLEEP_CONTROL1 0x2027
53
54 #define YT_SOFTWARE_RESET 0x8000
55
56 #define YT8512_CONFIG_PLL_REFCLK_SEL_EN 0x0040
57 #define YT8512_CONTROL1_RMII_EN 0x0001
58 #define YT8512_LED0_ACT_BLK_IND 0x1000
59 #define YT8512_LED0_DIS_LED_AN_TRY 0x0001
60 #define YT8512_LED0_BT_BLK_EN 0x0002
61 #define YT8512_LED0_HT_BLK_EN 0x0004
62 #define YT8512_LED0_COL_BLK_EN 0x0008
63 #define YT8512_LED0_BT_ON_EN 0x0010
64 #define YT8512_LED1_BT_ON_EN 0x0010
65 #define YT8512_LED1_TXACT_BLK_EN 0x0100
66 #define YT8512_LED1_RXACT_BLK_EN 0x0200
67 #define YT8512_SPEED_MODE 0xc000
68 #define YT8512_DUPLEX 0x2000
69
70 #define YT8512_SPEED_MODE_BIT 14
71 #define YT8512_DUPLEX_BIT 13
72 #define YT8512_EN_SLEEP_SW_BIT 15
73
74 /* if system depends on ethernet packet to restore from sleep,
75 * please define this macro to 1 otherwise, define it to 0.
76 */
77 #define SYS_WAKEUP_BASED_ON_ETH_PKT 1
78
79 /* to enable system WOL feature of phy, please define this macro to 1
80 * otherwise, define it to 0.
81 */
82 #define YTPHY_WOL_FEATURE_ENABLE 0
83
84 #if (YTPHY_WOL_FEATURE_ENABLE)
85 #undef SYS_WAKEUP_BASED_ON_ETH_PKT
86 #define SYS_WAKEUP_BASED_ON_ETH_PKT 1
87 #endif
88
89 /* for YT8531 package A xtal init config */
90 #define YTPHY8531A_XTAL_INIT 0
91
92 #define REG_PHY_SPEC_STATUS 0x11
93 #define REG_DEBUG_ADDR_OFFSET 0x1e
94 #define REG_DEBUG_DATA 0x1f
95
96 #define YT8521_EXTREG_SLEEP_CONTROL1 0x27
97 #define YT8521_EN_SLEEP_SW_BIT 15
98
99 #define YT8521_SPEED_MODE 0xc000
100 #define YT8521_DUPLEX 0x2000
101 #define YT8521_SPEED_MODE_BIT 14
102 #define YT8521_DUPLEX_BIT 13
103 #define YT8521_LINK_STATUS_BIT 10
104
105 /* YT8521 polling mode */
106 #define YT8521_PHY_MODE_FIBER 1 /* fiber mode only */
107 #define YT8521_PHY_MODE_UTP 2 /* utp mode only */
108 #define YT8521_PHY_MODE_POLL 3 /* fiber and utp, poll mode */
109
110 static int yt8521_hw_strap_polling(struct phy_device *phydev);
111 #define YT8521_PHY_MODE_CURR yt8521_hw_strap_polling(phydev)
112
yt8511_read_page(struct phy_device * phydev)113 static int yt8511_read_page(struct phy_device *phydev)
114 {
115 return __phy_read(phydev, YT8511_PAGE_SELECT);
116 };
117
yt8511_write_page(struct phy_device * phydev,int page)118 static int yt8511_write_page(struct phy_device *phydev, int page)
119 {
120 return __phy_write(phydev, YT8511_PAGE_SELECT, page);
121 };
122
yt8511_config_init(struct phy_device * phydev)123 static int yt8511_config_init(struct phy_device *phydev)
124 {
125 int oldpage, ret = 0;
126 unsigned int ge, fe;
127
128 oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE);
129 if (oldpage < 0)
130 goto err_restore_page;
131
132 /* set rgmii delay mode */
133 switch (phydev->interface) {
134 case PHY_INTERFACE_MODE_RGMII:
135 ge = YT8511_DELAY_GE_TX_DIS;
136 fe = YT8511_DELAY_FE_TX_DIS;
137 break;
138 case PHY_INTERFACE_MODE_RGMII_RXID:
139 ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_DIS;
140 fe = YT8511_DELAY_FE_TX_DIS;
141 break;
142 case PHY_INTERFACE_MODE_RGMII_TXID:
143 ge = YT8511_DELAY_GE_TX_EN;
144 fe = YT8511_DELAY_FE_TX_EN;
145 break;
146 case PHY_INTERFACE_MODE_RGMII_ID:
147 ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN;
148 fe = YT8511_DELAY_FE_TX_EN;
149 break;
150 default: /* do not support other modes */
151 ret = -EOPNOTSUPP;
152 goto err_restore_page;
153 }
154
155 ret = __phy_modify(phydev, YT8511_PAGE, (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge);
156 if (ret < 0)
157 goto err_restore_page;
158
159 /* set clock mode to 125mhz */
160 ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M);
161 if (ret < 0)
162 goto err_restore_page;
163
164 /* fast ethernet delay is in a separate page */
165 ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_DELAY_DRIVE);
166 if (ret < 0)
167 goto err_restore_page;
168
169 ret = __phy_modify(phydev, YT8511_PAGE, YT8511_DELAY_FE_TX_EN, fe);
170 if (ret < 0)
171 goto err_restore_page;
172
173 /* leave pll enabled in sleep */
174 ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_SLEEP_CTRL);
175 if (ret < 0)
176 goto err_restore_page;
177
178 ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_PLLON_SLP);
179 if (ret < 0)
180 goto err_restore_page;
181
182 err_restore_page:
183 return phy_restore_page(phydev, oldpage, ret);
184 }
185
ytphy_read_ext(struct phy_device * phydev,u32 regnum)186 static u32 ytphy_read_ext(struct phy_device *phydev, u32 regnum)
187 {
188 int ret;
189
190 phy_lock_mdio_bus(phydev);
191 ret = __phy_write(phydev, REG_DEBUG_ADDR_OFFSET, regnum);
192 if (ret < 0)
193 goto err_handle;
194
195 ret = __phy_read(phydev, REG_DEBUG_DATA);
196 if (ret < 0)
197 goto err_handle;
198
199 err_handle:
200 phy_unlock_mdio_bus(phydev);
201 return ret;
202 }
203
ytphy_write_ext(struct phy_device * phydev,u32 regnum,u16 val)204 static int ytphy_write_ext(struct phy_device *phydev, u32 regnum, u16 val)
205 {
206 int ret;
207
208 phy_lock_mdio_bus(phydev);
209 ret = __phy_write(phydev, REG_DEBUG_ADDR_OFFSET, regnum);
210 if (ret < 0)
211 goto err_handle;
212
213 ret = __phy_write(phydev, REG_DEBUG_DATA, val);
214 if (ret < 0)
215 goto err_handle;
216
217 err_handle:
218 phy_unlock_mdio_bus(phydev);
219 return ret;
220 }
221
ytphy_soft_reset(struct phy_device * phydev)222 static int ytphy_soft_reset(struct phy_device *phydev)
223 {
224 int ret = 0, val = 0;
225
226 val = phy_read(phydev, MII_BMCR);
227 if (val < 0)
228 return val;
229
230 ret = phy_write(phydev, MII_BMCR, val | BMCR_RESET);
231 if (ret < 0)
232 return ret;
233
234 return ret;
235 }
236
yt8512_clk_init(struct phy_device * phydev)237 static int yt8512_clk_init(struct phy_device *phydev)
238 {
239 struct device_node *node = phydev->mdio.dev.of_node;
240 const char *strings = NULL;
241 int ret;
242 int val;
243
244 if (node && node->parent && node->parent->parent) {
245 ret = of_property_read_string(node->parent->parent,
246 "clock_in_out", &strings);
247 if (!ret) {
248 if (!strcmp(strings, "input"))
249 return 0;
250 }
251 }
252
253 val = ytphy_read_ext(phydev, YT8512_EXTREG_AFE_PLL);
254 if (val < 0)
255 return val;
256
257 val |= YT8512_CONFIG_PLL_REFCLK_SEL_EN;
258
259 ret = ytphy_write_ext(phydev, YT8512_EXTREG_AFE_PLL, val);
260 if (ret < 0)
261 return ret;
262
263 val = ytphy_read_ext(phydev, YT8512_EXTREG_EXTEND_COMBO);
264 if (val < 0)
265 return val;
266
267 val |= YT8512_CONTROL1_RMII_EN;
268
269 ret = ytphy_write_ext(phydev, YT8512_EXTREG_EXTEND_COMBO, val);
270 if (ret < 0)
271 return ret;
272
273 val = phy_read(phydev, MII_BMCR);
274 if (val < 0)
275 return val;
276
277 val |= YT_SOFTWARE_RESET;
278 ret = phy_write(phydev, MII_BMCR, val);
279
280 return ret;
281 }
282
yt8512_led_init(struct phy_device * phydev)283 static int yt8512_led_init(struct phy_device *phydev)
284 {
285 int ret;
286 int val;
287 int mask;
288
289 val = ytphy_read_ext(phydev, YT8512_EXTREG_LED0);
290 if (val < 0)
291 return val;
292
293 val |= YT8512_LED0_ACT_BLK_IND;
294
295 mask = YT8512_LED0_DIS_LED_AN_TRY | YT8512_LED0_BT_BLK_EN |
296 YT8512_LED0_HT_BLK_EN | YT8512_LED0_COL_BLK_EN |
297 YT8512_LED0_BT_ON_EN;
298 val &= ~mask;
299
300 ret = ytphy_write_ext(phydev, YT8512_EXTREG_LED0, val);
301 if (ret < 0)
302 return ret;
303
304 val = ytphy_read_ext(phydev, YT8512_EXTREG_LED1);
305 if (val < 0)
306 return val;
307
308 val |= YT8512_LED1_BT_ON_EN;
309
310 mask = YT8512_LED1_TXACT_BLK_EN | YT8512_LED1_RXACT_BLK_EN;
311 val &= ~mask;
312
313 ret = ytphy_write_ext(phydev, YT8512_LED1_BT_ON_EN, val);
314
315 return ret;
316 }
317
yt8512_config_init(struct phy_device * phydev)318 static int yt8512_config_init(struct phy_device *phydev)
319 {
320 int ret;
321 int val;
322
323 ret = yt8512_clk_init(phydev);
324 if (ret < 0)
325 return ret;
326
327 ret = yt8512_led_init(phydev);
328 if (ret < 0)
329 return ret;
330
331 /* disable auto sleep */
332 val = ytphy_read_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1);
333 if (val < 0)
334 return val;
335
336 val &= (~BIT(YT8512_EN_SLEEP_SW_BIT));
337
338 ret = ytphy_write_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1, val);
339 if (ret < 0)
340 return ret;
341
342 return ret;
343 }
344
yt8512_read_status(struct phy_device * phydev)345 static int yt8512_read_status(struct phy_device *phydev)
346 {
347 int ret;
348 int val;
349 int speed, speed_mode, duplex;
350
351 ret = genphy_update_link(phydev);
352 if (ret)
353 return ret;
354
355 val = phy_read(phydev, REG_PHY_SPEC_STATUS);
356 if (val < 0)
357 return val;
358
359 duplex = (val & YT8512_DUPLEX) >> YT8512_DUPLEX_BIT;
360 speed_mode = (val & YT8512_SPEED_MODE) >> YT8512_SPEED_MODE_BIT;
361 switch (speed_mode) {
362 case 0:
363 speed = SPEED_10;
364 break;
365 case 1:
366 speed = SPEED_100;
367 break;
368 case 2:
369 case 3:
370 default:
371 speed = SPEED_UNKNOWN;
372 break;
373 }
374
375 phydev->speed = speed;
376 phydev->duplex = duplex;
377
378 return 0;
379 }
380
yt8521_soft_reset(struct phy_device * phydev)381 static int yt8521_soft_reset(struct phy_device *phydev)
382 {
383 int ret = 0, val;
384
385 if (YT8521_PHY_MODE_CURR == YT8521_PHY_MODE_UTP) {
386 ytphy_write_ext(phydev, 0xa000, 0);
387 ret = ytphy_soft_reset(phydev);
388 if (ret < 0)
389 return ret;
390 }
391
392 if (YT8521_PHY_MODE_CURR == YT8521_PHY_MODE_FIBER) {
393 ytphy_write_ext(phydev, 0xa000, 2);
394 ret = ytphy_soft_reset(phydev);
395 if (ret < 0)
396 return ret;
397
398 ytphy_write_ext(phydev, 0xa000, 0);
399 }
400
401 if (YT8521_PHY_MODE_CURR == YT8521_PHY_MODE_POLL) {
402 val = ytphy_read_ext(phydev, 0xa001);
403 ytphy_write_ext(phydev, 0xa001, (val & ~0x8000));
404
405 ytphy_write_ext(phydev, 0xa000, 0);
406 ret = ytphy_soft_reset(phydev);
407 if (ret < 0)
408 return ret;
409 }
410
411 return 0;
412 }
413
yt8521_hw_strap_polling(struct phy_device * phydev)414 static int yt8521_hw_strap_polling(struct phy_device *phydev)
415 {
416 int val = 0;
417
418 val = ytphy_read_ext(phydev, 0xa001) & 0x7;
419 switch (val) {
420 case 1:
421 case 4:
422 case 5:
423 return YT8521_PHY_MODE_FIBER;
424 case 2:
425 case 6:
426 case 7:
427 return YT8521_PHY_MODE_POLL;
428 case 3:
429 case 0:
430 default:
431 return YT8521_PHY_MODE_UTP;
432 }
433 }
434
yt8521_config_init(struct phy_device * phydev)435 static int yt8521_config_init(struct phy_device *phydev)
436 {
437 int ret, hw_strap_mode;
438 int val;
439
440 #if (YTPHY_WOL_FEATURE_ENABLE)
441 struct ethtool_wolinfo wol;
442
443 /* set phy wol enable */
444 memset(&wol, 0x0, sizeof(struct ethtool_wolinfo));
445 wol.wolopts |= WAKE_MAGIC;
446 ytphy_wol_feature_set(phydev, &wol);
447 #endif
448
449 phydev->irq = PHY_POLL;
450 /* NOTE: this function should not be called more than one for each chip. */
451 hw_strap_mode = ytphy_read_ext(phydev, 0xa001) & 0x7;
452
453 ytphy_write_ext(phydev, 0xa000, 0);
454
455 /* disable auto sleep */
456 val = ytphy_read_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1);
457 if (val < 0)
458 return val;
459
460 val &= (~BIT(YT8521_EN_SLEEP_SW_BIT));
461 ret = ytphy_write_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1, val);
462 if (ret < 0)
463 return ret;
464
465 /* enable RXC clock when no wire plug */
466 val = ytphy_read_ext(phydev, 0xc);
467 if (val < 0)
468 return val;
469 val &= ~(1 << 12);
470 ret = ytphy_write_ext(phydev, 0xc, val);
471 if (ret < 0)
472 return ret;
473
474 netdev_info(phydev->attached_dev, "%s done, phy addr: %d, strap mode = %d, polling mode = %d\n",
475 __func__, phydev->mdio.addr, hw_strap_mode, yt8521_hw_strap_polling(phydev));
476
477 return ret;
478 }
479
480 /* for fiber mode, there is no 10M speed mode and
481 * this function is for this purpose.
482 */
yt8521_adjust_status(struct phy_device * phydev,int val,int is_utp)483 static int yt8521_adjust_status(struct phy_device *phydev, int val, int is_utp)
484 {
485 int speed = SPEED_UNKNOWN;
486 int speed_mode, duplex;
487
488 if (is_utp)
489 duplex = (val & YT8521_DUPLEX) >> YT8521_DUPLEX_BIT;
490 else
491 duplex = 1;
492 speed_mode = (val & YT8521_SPEED_MODE) >> YT8521_SPEED_MODE_BIT;
493 switch (speed_mode) {
494 case 0:
495 if (is_utp)
496 speed = SPEED_10;
497 break;
498 case 1:
499 speed = SPEED_100;
500 break;
501 case 2:
502 speed = SPEED_1000;
503 break;
504 case 3:
505 break;
506 default:
507 speed = SPEED_UNKNOWN;
508 break;
509 }
510
511 phydev->speed = speed;
512 phydev->duplex = duplex;
513
514 return 0;
515 }
516
517 /* for fiber mode, when speed is 100M, there is no definition for
518 * autonegotiation, and this function handles this case and return
519 * 1 per linux kernel's polling.
520 */
yt8521_aneg_done(struct phy_device * phydev)521 static int yt8521_aneg_done(struct phy_device *phydev)
522 {
523 int link_fiber = 0, link_utp = 0;
524
525 /* reading Fiber */
526 ytphy_write_ext(phydev, 0xa000, 2);
527 link_fiber = !!(phy_read(phydev, REG_PHY_SPEC_STATUS) & (BIT(YT8521_LINK_STATUS_BIT)));
528
529 /* reading UTP */
530 ytphy_write_ext(phydev, 0xa000, 0);
531 if (!link_fiber)
532 link_utp = !!(phy_read(phydev, REG_PHY_SPEC_STATUS) & (BIT(YT8521_LINK_STATUS_BIT)));
533
534 netdev_info(phydev->attached_dev, "%s, phy addr: %d, link_fiber: %d, link_utp: %d\n",
535 __func__, phydev->mdio.addr, link_fiber, link_utp);
536 return !!(link_fiber | link_utp);
537 }
538
yt8521_read_status(struct phy_device * phydev)539 static int yt8521_read_status(struct phy_device *phydev)
540 {
541 int link_utp = 0, link_fiber = 0;
542 int yt8521_fiber_latch_val;
543 int yt8521_fiber_curr_val;
544 int link, ret;
545 int val;
546
547 if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) {
548 /* reading UTP */
549 ret = ytphy_write_ext(phydev, 0xa000, 0);
550 if (ret < 0)
551 return ret;
552
553 val = phy_read(phydev, REG_PHY_SPEC_STATUS);
554 if (val < 0)
555 return val;
556
557 link = val & (BIT(YT8521_LINK_STATUS_BIT));
558 if (link) {
559 link_utp = 1;
560 yt8521_adjust_status(phydev, val, 1);
561 } else {
562 link_utp = 0;
563 }
564 }
565
566 if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) {
567 /* reading Fiber */
568 ret = ytphy_write_ext(phydev, 0xa000, 2);
569 if (ret < 0)
570 return ret;
571
572 val = phy_read(phydev, REG_PHY_SPEC_STATUS);
573 if (val < 0)
574 return val;
575
576 /* note: below debug information is used to check multiple PHy ports. */
577
578 /* for fiber, from 1000m to 100m, there is not link down from 0x11,
579 * and check reg 1 to identify such case this is important for Linux
580 * kernel for that, missing linkdown event will cause problem.
581 */
582 yt8521_fiber_latch_val = phy_read(phydev, MII_BMSR);
583 yt8521_fiber_curr_val = phy_read(phydev, MII_BMSR);
584 link = val & (BIT(YT8521_LINK_STATUS_BIT));
585 if (link && yt8521_fiber_latch_val != yt8521_fiber_curr_val) {
586 link = 0;
587 netdev_info(phydev->attached_dev, "%s, phy addr: %d, fiber link down detect, latch = %04x, curr = %04x\n",
588 __func__, phydev->mdio.addr, yt8521_fiber_latch_val,
589 yt8521_fiber_curr_val);
590 }
591
592 if (link) {
593 link_fiber = 1;
594 yt8521_adjust_status(phydev, val, 0);
595 } else {
596 link_fiber = 0;
597 }
598 }
599
600 if (link_utp || link_fiber) {
601 if (phydev->link == 0)
602 netdev_info(phydev->attached_dev, "%s, phy addr: %d, link up, media: %s, mii reg 0x11 = 0x%x\n",
603 __func__, phydev->mdio.addr,
604 (link_utp && link_fiber) ? "UNKNOWN MEDIA" : (link_utp ? "UTP" : "Fiber"),
605 (unsigned int)val);
606 phydev->link = 1;
607 } else {
608 if (phydev->link == 1)
609 netdev_info(phydev->attached_dev, "%s, phy addr: %d, link down\n",
610 __func__, phydev->mdio.addr);
611 phydev->link = 0;
612 }
613
614 /* utp or combo */
615 if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) {
616 if (link_fiber)
617 ytphy_write_ext(phydev, 0xa000, 2);
618 if (link_utp)
619 ytphy_write_ext(phydev, 0xa000, 0);
620 }
621
622 return 0;
623 }
624
yt8521_suspend(struct phy_device * phydev)625 static int yt8521_suspend(struct phy_device *phydev)
626 {
627 #if !(SYS_WAKEUP_BASED_ON_ETH_PKT)
628 int value;
629
630 ytphy_write_ext(phydev, 0xa000, 0);
631 value = phy_read(phydev, MII_BMCR);
632 phy_write(phydev, MII_BMCR, value | BMCR_PDOWN);
633
634 ytphy_write_ext(phydev, 0xa000, 2);
635 value = phy_read(phydev, MII_BMCR);
636 phy_write(phydev, MII_BMCR, value | BMCR_PDOWN);
637
638 ytphy_write_ext(phydev, 0xa000, 0);
639 #endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/
640
641 return 0;
642 }
643
yt8521_resume(struct phy_device * phydev)644 static int yt8521_resume(struct phy_device *phydev)
645 {
646 int value, ret;
647
648 /* disable auto sleep */
649 value = ytphy_read_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1);
650 if (value < 0)
651 return value;
652
653 value &= (~BIT(YT8521_EN_SLEEP_SW_BIT));
654
655 ret = ytphy_write_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1, value);
656 if (ret < 0)
657 return ret;
658
659 #if !(SYS_WAKEUP_BASED_ON_ETH_PKT)
660 if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) {
661 ytphy_write_ext(phydev, 0xa000, 0);
662 value = phy_read(phydev, MII_BMCR);
663 phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN);
664 }
665
666 if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) {
667 ytphy_write_ext(phydev, 0xa000, 2);
668 value = phy_read(phydev, MII_BMCR);
669 phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN);
670
671 ytphy_write_ext(phydev, 0xa000, 0);
672 }
673 #endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/
674
675 return 0;
676 }
677
yt8531_rxclk_duty_init(struct phy_device * phydev)678 static int yt8531_rxclk_duty_init(struct phy_device *phydev)
679 {
680 unsigned int value = 0x9696;
681 int ret = 0;
682
683 ret = ytphy_write_ext(phydev, 0xa040, 0xffff);
684 if (ret < 0)
685 return ret;
686
687 ret = ytphy_write_ext(phydev, 0xa041, 0xff);
688 if (ret < 0)
689 return ret;
690
691 ret = ytphy_write_ext(phydev, 0xa039, 0xbf00);
692 if (ret < 0)
693 return ret;
694
695 /* nodelay duty = 0x9696 (default)
696 * fixed delay duty = 0x4040
697 * step delay 0xf duty = 0x4041
698 */
699 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
700 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
701 value = 0x4040;
702
703 ret = ytphy_write_ext(phydev, 0xa03a, value);
704 if (ret < 0)
705 return ret;
706 ret = ytphy_write_ext(phydev, 0xa03b, value);
707 if (ret < 0)
708 return ret;
709 ret = ytphy_write_ext(phydev, 0xa03c, value);
710 if (ret < 0)
711 return ret;
712 ret = ytphy_write_ext(phydev, 0xa03d, value);
713 if (ret < 0)
714 return ret;
715 ret = ytphy_write_ext(phydev, 0xa03e, value);
716 if (ret < 0)
717 return ret;
718 ret = ytphy_write_ext(phydev, 0xa03f, value);
719 if (ret < 0)
720 return ret;
721
722 return ret;
723 }
724
yt8531S_config_init(struct phy_device * phydev)725 static int yt8531S_config_init(struct phy_device *phydev)
726 {
727 #if (YTPHY8531A_XTAL_INIT)
728 int ret = 0;
729
730 ret = yt8531a_xtal_init(phydev);
731 if (ret < 0)
732 return ret;
733 #endif
734
735 return yt8521_config_init(phydev);
736 }
737
yt8531_config_init(struct phy_device * phydev)738 static int yt8531_config_init(struct phy_device *phydev)
739 {
740 int ret = 0, val;
741
742 #if (YTPHY8531A_XTAL_INIT)
743 ret = yt8531a_xtal_init(phydev);
744 if (ret < 0)
745 return ret;
746 #endif
747
748 /* PHY_CLK_OUT 125M enabled (default) */
749 ret = ytphy_write_ext(phydev, 0xa012, 0xd0);
750 if (ret < 0)
751 return ret;
752
753 ret = yt8531_rxclk_duty_init(phydev);
754 if (ret < 0)
755 return ret;
756
757 /* RXC, PHY_CLK_OUT and RXData Drive strength:
758 * Drive strength of RXC = 6, PHY_CLK_OUT = 3, RXD0 = 4 (default 1.8v)
759 * If the io voltage is 3.3v, PHY_CLK_OUT = 2, set 0xa010 = 0xdacf
760 */
761 ret = ytphy_write_ext(phydev, 0xa010, 0xdbcf);
762 if (ret < 0)
763 return ret;
764
765 /* Change 100M default BGS voltage from 0x294c to 0x274c */
766 val = ytphy_read_ext(phydev, 0x57);
767 val = (val & ~(0xf << 8)) | (7 << 8);
768 ret = ytphy_write_ext(phydev, 0x57, val);
769 if (ret < 0)
770 return ret;
771
772 return ret;
773 }
774
775 static struct phy_driver motorcomm_phy_drvs[] = {
776 {
777 PHY_ID_MATCH_EXACT(PHY_ID_YT8511),
778 .name = "YT8511 Gigabit Ethernet",
779 .config_init = yt8511_config_init,
780 .suspend = genphy_suspend,
781 .resume = genphy_resume,
782 .read_page = yt8511_read_page,
783 .write_page = yt8511_write_page,
784 }, {
785 PHY_ID_MATCH_EXACT(PHY_ID_YT8512),
786 .name = "YT8512 Ethernet",
787 .config_init = yt8512_config_init,
788 .read_status = yt8512_read_status,
789 .suspend = genphy_suspend,
790 .resume = genphy_resume,
791 }, {
792 PHY_ID_MATCH_EXACT(PHY_ID_YT8512B),
793 .name = "YT8512B Ethernet",
794 .config_init = yt8512_config_init,
795 .read_status = yt8512_read_status,
796 .suspend = genphy_suspend,
797 .resume = genphy_resume,
798 }, {
799 /* same as 8521 */
800 PHY_ID_MATCH_EXACT(PHY_ID_YT8531S),
801 .name = "YT8531S Gigabit Ethernet",
802 .features = PHY_GBIT_FEATURES,
803 .soft_reset = yt8521_soft_reset,
804 .aneg_done = yt8521_aneg_done,
805 .config_init = yt8531S_config_init,
806 .read_status = yt8521_read_status,
807 .suspend = yt8521_suspend,
808 .resume = yt8521_resume,
809 #if (YTPHY_WOL_FEATURE_ENABLE)
810 .get_wol = &ytphy_wol_feature_get,
811 .set_wol = &ytphy_wol_feature_set,
812 #endif
813 }, {
814 /* same as 8511 */
815 PHY_ID_MATCH_EXACT(PHY_ID_YT8531),
816 .name = "YT8531 Gigabit Ethernet",
817 .features = PHY_GBIT_FEATURES,
818 .config_init = yt8531_config_init,
819 .suspend = genphy_suspend,
820 .resume = genphy_resume,
821 #if (YTPHY_WOL_FEATURE_ENABLE)
822 .get_wol = &ytphy_wol_feature_get,
823 .set_wol = &ytphy_wol_feature_set,
824 #endif
825 },
826 };
827
828 module_phy_driver(motorcomm_phy_drvs);
829
830 MODULE_DESCRIPTION("Motorcomm PHY driver");
831 MODULE_AUTHOR("Peter Geis");
832 MODULE_LICENSE("GPL");
833
834 static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
835 { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
836 { PHY_ID_MATCH_EXACT(PHY_ID_YT8512) },
837 { PHY_ID_MATCH_EXACT(PHY_ID_YT8512B) },
838 { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
839 { PHY_ID_MATCH_EXACT(PHY_ID_YT8531) },
840 { /* sentinal */ }
841 };
842
843 MODULE_DEVICE_TABLE(mdio, motorcomm_tbl);
844