1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Realtek RTL838X Ethernet MDIO interface driver
4 * Copyright (C) 2020 B. Koblitz
7 #include <linux/delay.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/of_address.h>
11 #include <linux/of_mdio.h>
12 #include <linux/phy.h>
13 #include <linux/platform_device.h>
14 #include <linux/firmware.h>
15 #include <linux/crc32.h>
17 #include <asm/mach-rtl838x/mach-rtl838x.h>
20 /* External RTL8218B and RTL8214FC IDs are identical */
21 #define PHY_ID_RTL8214C 0x001cc942
22 #define PHY_ID_RTL8214FC 0x001cc981
23 #define PHY_ID_RTL8218B_E 0x001cc981
24 #define PHY_ID_RTL8218B_I 0x001cca40
25 #define PHY_ID_RTL8390_GENERIC 0x001ccab0
26 #define PHY_ID_RTL8393_I 0x001c8393
28 struct __attribute__ ((__packed__
)) part
{
34 struct __attribute__ ((__packed__
)) fw_header
{
39 struct part parts
[10];
42 #define FIRMWARE_838X_8380_1 "rtl838x_phy/rtl838x_8380.fw"
43 #define FIRMWARE_838X_8214FC_1 "rtl838x_phy/rtl838x_8214fc.fw"
44 #define FIRMWARE_838X_8218b_1 "rtl838x_phy/rtl838x_8218b.fw"
46 static const struct firmware rtl838x_8380_fw
;
47 static const struct firmware rtl838x_8214fc_fw
;
48 static const struct firmware rtl838x_8218b_fw
;
50 struct rtl838x_phy_priv
{
54 static int read_phy(u32 port
, u32 page
, u32 reg
, u32
*val
)
56 if (soc_info
.family
== RTL8390_FAMILY_ID
)
57 return rtl839x_read_phy(port
, page
, reg
, val
);
59 return rtl838x_read_phy(port
, page
, reg
, val
);
62 static int write_phy(u32 port
, u32 page
, u32 reg
, u32 val
)
64 if (soc_info
.family
== RTL8390_FAMILY_ID
)
65 return rtl839x_write_phy(port
, page
, reg
, val
);
67 return rtl838x_write_phy(port
, page
, reg
, val
);
70 static void rtl8380_int_phy_on_off(int mac
, bool on
)
74 read_phy(mac
, 0, 0, &val
);
76 write_phy(mac
, 0, 0, val
& ~(1 << 11));
78 write_phy(mac
, 0, 0, val
| (1 << 11));
81 static void rtl8380_rtl8214fc_on_off(int mac
, bool on
)
86 write_phy(mac
, 4095, 30, 3);
87 read_phy(mac
, 0, 16, &val
);
89 write_phy(mac
, 0, 16, val
& ~(1 << 11));
91 write_phy(mac
, 0, 16, val
| (1 << 11));
94 write_phy(mac
, 4095, 30, 1);
95 read_phy(mac
, 0, 16, &val
);
97 write_phy(mac
, 0xa40, 16, val
& ~(1 << 11));
99 write_phy(mac
, 0xa40, 16, val
| (1 << 11));
102 static void rtl8380_phy_reset(int mac
)
106 read_phy(mac
, 0, 0, &val
);
107 write_phy(mac
, 0, 0, val
| (0x1 << 15));
110 void rtl8380_sds_rst(int mac
)
112 u32 offset
= (mac
== 24) ? 0 : 0x100;
114 sw_w32_mask(1 << 11, 0, RTL8380_SDS4_FIB_REG0
+ offset
);
115 sw_w32_mask(0x3, 0, RTL838X_SDS4_REG28
+ offset
);
116 sw_w32_mask(0x3, 0x3, RTL838X_SDS4_REG28
+ offset
);
117 sw_w32_mask(0, 0x1 << 6, RTL838X_SDS4_DUMMY0
+ offset
);
118 sw_w32_mask(0x1 << 6, 0, RTL838X_SDS4_DUMMY0
+ offset
);
119 pr_info("SERDES reset: %d\n", mac
);
122 int rtl839x_read_sds_phy(int phy_addr
, int phy_reg
)
131 /* For the RTL8393 internal SerDes, we simulate a PHY ID in registers 2/3
132 * which would otherwise read as 0
134 if (soc_info
.id
== 0x8393) {
141 reg
= (phy_reg
<< 1) & 0xfc;
142 val
= sw_r32(RTL839X_SDS12_13_XSG0
+ offset
+ 0x80 + reg
);
145 val
= (val
>> 16) & 0xffff;
151 int rtl838x_read_sds_phy(int phy_addr
, int phy_reg
)
158 val
= sw_r32(MAPLE_SDS4_FIB_REG0r
+ offset
+ (phy_reg
<< 2)) & 0xffff;
163 int rtl839x_write_sds_phy(int phy_addr
, int phy_reg
, u16 v
)
172 reg
= (phy_reg
<< 1) & 0xfc;
176 sw_w32_mask(0xffff0000, val
,
177 RTL839X_SDS12_13_XSG0
+ offset
+ 0x80 + reg
);
179 sw_w32_mask(0xffff, val
,
180 RTL839X_SDS12_13_XSG0
+ offset
+ 0x80 + reg
);
186 /* Read the link and speed status of the 2 internal SGMII/1000Base-X
187 * ports of the RTL838x SoCs
189 static int rtl8380_read_status(struct phy_device
*phydev
)
192 int phy_addr
= phydev
->mdio
.addr
;
194 err
= genphy_read_status(phydev
);
197 phydev
->speed
= SPEED_1000
;
198 phydev
->duplex
= DUPLEX_FULL
;
204 /* Read the link and speed status of the 2 internal SGMII/1000Base-X
205 * ports of the RTL8393 SoC
207 static int rtl8393_read_status(struct phy_device
*phydev
)
211 int phy_addr
= phydev
->mdio
.addr
;
214 err
= genphy_read_status(phydev
);
219 phydev
->speed
= SPEED_100
;
220 /* Read SPD_RD_00 (bit 13) and SPD_RD_01 (bit 6) out of the internal
223 v
= sw_r32(RTL839X_SDS12_13_XSG0
+ offset
+ 0x80);
224 if (!(v
& (1 << 13)) && (v
& (1 << 6)))
225 phydev
->speed
= SPEED_1000
;
226 phydev
->duplex
= DUPLEX_FULL
;
232 static struct fw_header
*
233 rtl838x_request_fw(struct phy_device
*phydev
, const struct firmware
*fw
,
236 struct device
*dev
= &phydev
->mdio
.dev
;
239 uint32_t checksum
, my_checksum
;
241 err
= request_firmware(&fw
, name
, dev
);
245 if (fw
->size
< sizeof(struct fw_header
)) {
246 pr_err("Firmware size too small.\n");
251 h
= (struct fw_header
*) fw
->data
;
252 pr_info("Firmware loaded. Size %d, magic: %08x\n", fw
->size
, h
->magic
);
254 if (h
->phy
!= 0x83800000) {
255 pr_err("Wrong firmware file: PHY mismatch.\n");
259 checksum
= h
->checksum
;
261 my_checksum
= ~crc32(0xFFFFFFFFU
, fw
->data
, fw
->size
);
262 if (checksum
!= my_checksum
) {
263 pr_err("Firmware checksum mismatch.\n");
267 h
->checksum
= checksum
;
271 dev_err(dev
, "Unable to load firmware %s (%d)\n", name
, err
);
275 static int rtl8390_configure_generic(struct phy_device
*phydev
)
278 int mac
= phydev
->mdio
.addr
;
280 read_phy(mac
, 0, 2, &val
);
282 read_phy(mac
, 0, 3, &val
);
284 pr_debug("Phy on MAC %d: %x\n", mac
, phy_id
);
286 /* Read internal PHY ID */
287 write_phy(mac
, 31, 27, 0x0002);
288 read_phy(mac
, 31, 28, &val
);
290 /* Internal RTL8218B, version 2 */
291 phydev_info(phydev
, "Detected unknown %x\n", val
);
295 static int rtl8380_configure_int_rtl8218b(struct phy_device
*phydev
)
299 int mac
= phydev
->mdio
.addr
;
301 u32
*rtl838x_6275B_intPhy_perport
;
302 u32
*rtl8218b_6276B_hwEsd_perport
;
305 read_phy(mac
, 0, 2, &val
);
307 read_phy(mac
, 0, 3, &val
);
309 pr_debug("Phy on MAC %d: %x\n", mac
, phy_id
);
311 /* Read internal PHY ID */
312 write_phy(mac
, 31, 27, 0x0002);
313 read_phy(mac
, 31, 28, &val
);
315 phydev_err(phydev
, "Expected internal RTL8218B, found PHY-ID %x\n", val
);
319 /* Internal RTL8218B, version 2 */
320 phydev_info(phydev
, "Detected internal RTL8218B\n");
322 h
= rtl838x_request_fw(phydev
, &rtl838x_8380_fw
, FIRMWARE_838X_8380_1
);
326 if (h
->phy
!= 0x83800000) {
327 phydev_err(phydev
, "Wrong firmware file: PHY mismatch.\n");
331 rtl838x_6275B_intPhy_perport
= (void *)h
+ sizeof(struct fw_header
)
334 rtl8218b_6276B_hwEsd_perport
= (void *)h
+ sizeof(struct fw_header
)
337 if (sw_r32(RTL838X_DMY_REG31
) == 0x1)
340 read_phy(mac
, 0, 0, &val
);
342 rtl8380_int_phy_on_off(mac
, true);
344 rtl8380_phy_reset(mac
);
347 /* Ready PHY for patch */
348 for (p
= 0; p
< 8; p
++) {
349 write_phy(mac
+ p
, 0xfff, 0x1f, 0x0b82);
350 write_phy(mac
+ p
, 0xfff, 0x10, 0x0010);
353 for (p
= 0; p
< 8; p
++) {
354 for (i
= 0; i
< 100 ; i
++) {
355 read_phy(mac
+ p
, 0x0b80, 0x10, &val
);
361 "ERROR: Port %d not ready for patch.\n",
366 for (p
= 0; p
< 8; p
++) {
368 while (rtl838x_6275B_intPhy_perport
[i
* 2]) {
369 write_phy(mac
+ p
, 0xfff,
370 rtl838x_6275B_intPhy_perport
[i
* 2],
371 rtl838x_6275B_intPhy_perport
[i
* 2 + 1]);
375 while (rtl8218b_6276B_hwEsd_perport
[i
* 2]) {
376 write_phy(mac
+ p
, 0xfff,
377 rtl8218b_6276B_hwEsd_perport
[i
* 2],
378 rtl8218b_6276B_hwEsd_perport
[i
* 2 + 1]);
385 static int rtl8380_configure_ext_rtl8218b(struct phy_device
*phydev
)
387 u32 val
, ipd
, phy_id
;
389 int mac
= phydev
->mdio
.addr
;
391 u32
*rtl8380_rtl8218b_perchip
;
392 u32
*rtl8218B_6276B_rtl8380_perport
;
393 u32
*rtl8380_rtl8218b_perport
;
395 if (soc_info
.family
== RTL8380_FAMILY_ID
&& mac
!= 0 && mac
!= 16) {
396 phydev_err(phydev
, "External RTL8218B must have PHY-IDs 0 or 16!\n");
399 read_phy(mac
, 0, 2, &val
);
401 read_phy(mac
, 0, 3, &val
);
403 pr_info("Phy on MAC %d: %x\n", mac
, phy_id
);
405 /* Read internal PHY ID */
406 write_phy(mac
, 31, 27, 0x0002);
407 read_phy(mac
, 31, 28, &val
);
409 phydev_err(phydev
, "Expected external RTL8218B, found PHY-ID %x\n", val
);
412 phydev_info(phydev
, "Detected external RTL8218B\n");
414 h
= rtl838x_request_fw(phydev
, &rtl838x_8218b_fw
, FIRMWARE_838X_8218b_1
);
418 if (h
->phy
!= 0x8218b00) {
419 phydev_err(phydev
, "Wrong firmware file: PHY mismatch.\n");
423 rtl8380_rtl8218b_perchip
= (void *)h
+ sizeof(struct fw_header
)
426 rtl8218B_6276B_rtl8380_perport
= (void *)h
+ sizeof(struct fw_header
)
429 rtl8380_rtl8218b_perport
= (void *)h
+ sizeof(struct fw_header
)
432 read_phy(mac
, 0, 0, &val
);
434 rtl8380_int_phy_on_off(mac
, true);
436 rtl8380_phy_reset(mac
);
439 /* Get Chip revision */
440 write_phy(mac
, 0xfff, 0x1f, 0x0);
441 write_phy(mac
, 0xfff, 0x1b, 0x4);
442 read_phy(mac
, 0xfff, 0x1c, &val
);
445 while (rtl8380_rtl8218b_perchip
[i
* 3]
446 && rtl8380_rtl8218b_perchip
[i
* 3 + 1]) {
447 write_phy(mac
+ rtl8380_rtl8218b_perchip
[i
* 3],
448 0xfff, rtl8380_rtl8218b_perchip
[i
* 3 + 1],
449 rtl8380_rtl8218b_perchip
[i
* 3 + 2]);
454 for (i
= 0; i
< 8; i
++) {
455 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0000);
456 write_phy(mac
+ i
, 0xfff, 0x00, 0x1140);
461 for (i
= 0; i
< 8; i
++) {
462 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0b82);
463 write_phy(mac
+ i
, 0xfff, 0x10, 0x0010);
467 /* Verify patch readiness */
468 for (i
= 0; i
< 8; i
++) {
469 for (l
= 0; l
< 100; l
++) {
470 read_phy(mac
+ i
, 0xb80, 0x10, &val
);
475 phydev_err(phydev
, "Could not patch PHY\n");
480 /* Use Broadcast ID method for patching */
481 write_phy(mac
, 0xfff, 0x1f, 0x0000);
482 write_phy(mac
, 0xfff, 0x1d, 0x0008);
483 write_phy(mac
, 0xfff, 0x1f, 0x0266);
484 write_phy(mac
, 0xfff, 0x16, 0xff00 + mac
);
485 write_phy(mac
, 0xfff, 0x1f, 0x0000);
486 write_phy(mac
, 0xfff, 0x1d, 0x0000);
489 write_phy(mac
, 0xfff, 30, 8);
490 write_phy(mac
, 0x26e, 17, 0xb);
491 write_phy(mac
, 0x26e, 16, 0x2);
493 read_phy(mac
, 0x26e, 19, &ipd
);
494 write_phy(mac
, 0, 30, 0);
495 ipd
= (ipd
>> 4) & 0xf;
498 while (rtl8218B_6276B_rtl8380_perport
[i
* 2]) {
499 write_phy(mac
, 0xfff, rtl8218B_6276B_rtl8380_perport
[i
* 2],
500 rtl8218B_6276B_rtl8380_perport
[i
* 2 + 1]);
504 /*Disable broadcast ID*/
505 write_phy(mac
, 0xfff, 0x1f, 0x0000);
506 write_phy(mac
, 0xfff, 0x1d, 0x0008);
507 write_phy(mac
, 0xfff, 0x1f, 0x0266);
508 write_phy(mac
, 0xfff, 0x16, 0x00 + mac
);
509 write_phy(mac
, 0xfff, 0x1f, 0x0000);
510 write_phy(mac
, 0xfff, 0x1d, 0x0000);
516 static int rtl8218b_ext_match_phy_device(struct phy_device
*phydev
)
518 int addr
= phydev
->mdio
.addr
;
520 /* Both the RTL8214FC and the external RTL8218B have the same
521 * PHY ID. On the RTL838x, the RTL8218B can only be attached_dev
522 * at PHY IDs 0-7, while the RTL8214FC must be attached via
523 * the pair of SGMII/1000Base-X with higher PHY-IDs
525 if (soc_info
.family
== RTL8380_FAMILY_ID
)
526 return phydev
->phy_id
== PHY_ID_RTL8218B_E
&& addr
< 8;
528 return phydev
->phy_id
== PHY_ID_RTL8218B_E
;
532 static int rtl8380_rtl8218b_write_mmd(struct phy_device
*phydev
,
533 int devnum
, u16 regnum
, u16 val
)
535 int addr
= phydev
->mdio
.addr
;
537 return rtl838x_write_mmd_phy(addr
, devnum
, regnum
, val
);
540 static int rtl8380_rtl8218b_read_mmd(struct phy_device
*phydev
,
541 int devnum
, u16 regnum
)
545 int addr
= phydev
->mdio
.addr
;
547 ret
= rtl838x_read_mmd_phy(addr
, devnum
, regnum
, &val
);
553 static void rtl8380_rtl8214fc_media_set(int mac
, bool set_fibre
)
555 int base
= mac
- (mac
% 4);
556 static int reg
[] = {16, 19, 20, 21};
557 int val
, media
, power
;
559 pr_info("%s: port %d, set_fibre: %d\n", __func__
, mac
, set_fibre
);
560 write_phy(base
, 0xfff, 29, 8);
561 read_phy(base
, 0x266, reg
[mac
% 4], &val
);
563 media
= (val
>> 10) & 0x3;
564 pr_info("Current media %x\n", media
);
566 pr_info("Powering off COPPER\n");
567 write_phy(base
, 0xfff, 29, 1);
568 /* Ensure power is off */
569 read_phy(base
, 0xa40, 16, &power
);
570 if (!(power
& (1 << 11)))
571 write_phy(base
, 0xa40, 16, power
| (1 << 11));
573 pr_info("Powering off FIBRE");
574 write_phy(base
, 0xfff, 29, 3);
575 /* Ensure power is off */
576 read_phy(base
, 0xa40, 16, &power
);
577 if (!(power
& (1 << 11)))
578 write_phy(base
, 0xa40, 16, power
| (1 << 11));
588 write_phy(base
, 0xfff, 29, 8);
589 write_phy(base
, 0x266, reg
[mac
% 4], val
);
590 write_phy(base
, 0xfff, 29, 0);
593 pr_info("Powering on FIBRE");
594 write_phy(base
, 0xfff, 29, 3);
595 /* Ensure power is off */
596 read_phy(base
, 0xa40, 16, &power
);
597 if (power
& (1 << 11))
598 write_phy(base
, 0xa40, 16, power
& ~(1 << 11));
600 pr_info("Powering on COPPER\n");
601 write_phy(base
, 0xfff, 29, 1);
602 /* Ensure power is off */
603 read_phy(base
, 0xa40, 16, &power
);
604 if (power
& (1 << 11))
605 write_phy(base
, 0xa40, 16, power
& ~(1 << 11));
608 write_phy(base
, 0xfff, 29, 0);
611 static bool rtl8380_rtl8214fc_media_is_fibre(int mac
)
613 int base
= mac
- (mac
% 4);
614 static int reg
[] = {16, 19, 20, 21};
617 write_phy(base
, 0xfff, 29, 8);
618 read_phy(base
, 0x266, reg
[mac
% 4], &val
);
619 write_phy(base
, 0xfff, 29, 0);
625 static int rtl8380_rtl8214fc_set_port(struct phy_device
*phydev
, int port
)
627 bool is_fibre
= (port
== PORT_FIBRE
? true : false);
628 int addr
= phydev
->mdio
.addr
;
630 pr_debug("%s port %d to %d\n", __func__
, addr
, port
);
632 rtl8380_rtl8214fc_media_set(addr
, is_fibre
);
636 static int rtl8380_rtl8214fc_get_port(struct phy_device
*phydev
)
638 int addr
= phydev
->mdio
.addr
;
640 pr_debug("%s: port %d\n", __func__
, addr
);
641 if (rtl8380_rtl8214fc_media_is_fibre(addr
))
646 void rtl8380_rtl8214fc_ldps_set(int mac
, struct ethtool_eee
*e
)
651 static void rtl8380_rtl8218b_eee_set_u_boot(int port
, bool enable
)
656 /* Set GPHY page to copper */
657 write_phy(port
, 0, 30, 0x0001);
658 read_phy(port
, 0, 0, &val
);
659 an_enabled
= val
& (1 << 12);
662 /* 100/1000M EEE Capability */
663 write_phy(port
, 0, 13, 0x0007);
664 write_phy(port
, 0, 14, 0x003C);
665 write_phy(port
, 0, 13, 0x4007);
666 write_phy(port
, 0, 14, 0x0006);
668 read_phy(port
, 0x0A43, 25, &val
);
670 write_phy(port
, 0x0A43, 25, val
);
672 /* 100/1000M EEE Capability */
673 write_phy(port
, 0, 13, 0x0007);
674 write_phy(port
, 0, 14, 0x003C);
675 write_phy(port
, 0, 13, 0x0007);
676 write_phy(port
, 0, 14, 0x0000);
678 read_phy(port
, 0x0A43, 25, &val
);
680 write_phy(port
, 0x0A43, 25, val
);
683 /* Restart AN if enabled */
685 read_phy(port
, 0, 0, &val
);
686 val
|= (1 << 12) | (1 << 9);
687 write_phy(port
, 0, 0, val
);
690 /* GPHY page back to auto*/
691 write_phy(port
, 0xa42, 29, 0);
694 static int rtl8380_rtl8218b_get_eee_u_boot(struct phy_device
*phydev
, struct ethtool_eee
*e
)
697 int addr
= phydev
->mdio
.addr
;
699 pr_debug("In %s %d\n", __func__
, addr
);
701 /* Set GPHY page to copper */
702 write_phy(addr
, 0xa42, 29, 0x0001);
704 read_phy(addr
, 0xa43, 25, &val
);
705 if (e
->eee_enabled
&& (!!(val
& (1 << 4))))
706 e
->eee_enabled
= !!(val
& (1 << 4));
710 /* GPHY page to auto */
711 write_phy(addr
, 0xa42, 29, 0x0000);
716 void rtl8380_rtl8218b_eee_set(int port
, bool enable
)
721 pr_debug("In %s %d, enable %d\n", __func__
, port
, enable
);
722 /* Set GPHY page to copper */
723 write_phy(port
, 0xa42, 29, 0x0001);
725 read_phy(port
, 0, 0, &val
);
726 an_enabled
= val
& (1 << 12);
729 read_phy(port
, 0xa43, 25, &val
);
731 write_phy(port
, 0xa43, 25, val
);
733 /* 100M / 1000M EEE */
735 rtl838x_write_mmd_phy(port
, 7, 60, 0x6);
737 rtl838x_write_mmd_phy(port
, 7, 60, 0);
739 /* 500M EEE ability */
740 read_phy(port
, 0xa42, 20, &val
);
745 write_phy(port
, 0xa42, 20, val
);
747 /* Restart AN if enabled */
749 read_phy(port
, 0, 0, &val
);
750 val
|= (1 << 12) | (1 << 9);
751 write_phy(port
, 0, 0, val
);
754 /* GPHY page back to auto*/
755 write_phy(port
, 0xa42, 29, 0);
758 int rtl8380_rtl8218b_get_eee(struct phy_device
*phydev
,
759 struct ethtool_eee
*e
)
762 int addr
= phydev
->mdio
.addr
;
764 pr_debug("In %s, port %d\n", __func__
, addr
);
766 /* Set GPHY page to copper */
767 write_phy(addr
, 0xa42, 29, 0x0001);
769 rtl838x_read_mmd_phy(addr
, 7, 60, &val
);
770 if (e
->eee_enabled
&& (!!(val
& (1 << 7))))
771 e
->eee_enabled
= !!(val
& (1 << 7));
775 /* GPHY page to auto */
776 write_phy(addr
, 0xa42, 29, 0x0000);
781 void rtl8380_rtl8218b_green_set(int mac
, bool enable
)
785 /* Set GPHY page to copper */
786 write_phy(mac
, 0xa42, 29, 0x0001);
788 write_phy(mac
, 0, 27, 0x8011);
789 read_phy(mac
, 0, 28, &val
);
792 write_phy(mac
, 0, 27, 0x8011);
793 write_phy(mac
, 0, 28, val
);
796 write_phy(mac
, 0, 27, 0x8011);
797 write_phy(mac
, 0, 28, val
);
800 /* GPHY page to auto */
801 write_phy(mac
, 0xa42, 29, 0x0000);
804 int rtl8380_rtl8214fc_get_green(struct phy_device
*phydev
, struct ethtool_eee
*e
)
807 int addr
= phydev
->mdio
.addr
;
809 pr_debug("In %s %d\n", __func__
, addr
);
810 /* Set GPHY page to copper */
811 write_phy(addr
, 0xa42, 29, 0x0001);
813 write_phy(addr
, 0, 27, 0x8011);
814 read_phy(addr
, 0, 28, &val
);
815 if (e
->eee_enabled
&& (!!(val
& (1 << 9))))
816 e
->eee_enabled
= !!(val
& (1 << 9));
820 /* GPHY page to auto */
821 write_phy(addr
, 0xa42, 29, 0x0000);
826 static int rtl8380_rtl8214fc_set_eee(struct phy_device
*phydev
,
827 struct ethtool_eee
*e
)
830 int addr
= phydev
->mdio
.addr
;
832 pr_debug("In %s port %d, enabled %d\n", __func__
, addr
, e
->eee_enabled
);
834 if (rtl8380_rtl8214fc_media_is_fibre(addr
)) {
835 netdev_err(phydev
->attached_dev
, "Port %d configured for FIBRE", addr
);
839 pollMask
= sw_r32(RTL838X_SMI_POLL_CTRL
);
840 sw_w32(0, RTL838X_SMI_POLL_CTRL
);
841 rtl8380_rtl8218b_eee_set_u_boot(addr
, (bool) e
->eee_enabled
);
842 sw_w32(pollMask
, RTL838X_SMI_POLL_CTRL
);
846 static int rtl8380_rtl8214fc_get_eee(struct phy_device
*phydev
,
847 struct ethtool_eee
*e
)
849 int addr
= phydev
->mdio
.addr
;
851 pr_debug("In %s port %d, enabled %d\n", __func__
, addr
, e
->eee_enabled
);
852 if (rtl8380_rtl8214fc_media_is_fibre(addr
)) {
853 netdev_err(phydev
->attached_dev
, "Port %d configured for FIBRE", addr
);
857 return rtl8380_rtl8218b_get_eee_u_boot(phydev
, e
);
860 static int rtl8380_rtl8218b_set_eee(struct phy_device
*phydev
,
861 struct ethtool_eee
*e
)
864 int addr
= phydev
->mdio
.addr
;
866 pr_debug("In %s, port %d, enabled %d\n", __func__
, addr
, e
->eee_enabled
);
868 pollMask
= sw_r32(RTL838X_SMI_POLL_CTRL
);
869 sw_w32(0, RTL838X_SMI_POLL_CTRL
);
870 rtl8380_rtl8218b_eee_set_u_boot(addr
, (bool) e
->eee_enabled
);
871 sw_w32(pollMask
, RTL838X_SMI_POLL_CTRL
);
876 static int rtl8214c_match_phy_device(struct phy_device
*phydev
)
878 return phydev
->phy_id
== PHY_ID_RTL8214C
;
881 static int rtl8380_configure_rtl8214c(struct phy_device
*phydev
)
884 int mac
= phydev
->mdio
.addr
;
886 read_phy(mac
, 0, 2, &val
);
888 read_phy(mac
, 0, 3, &val
);
890 pr_debug("Phy on MAC %d: %x\n", mac
, phy_id
);
892 phydev_info(phydev
, "Detected external RTL8214C\n");
895 write_phy(mac
, 0xa42, 29, 0);
899 static int rtl8380_configure_rtl8214fc(struct phy_device
*phydev
)
901 u32 phy_id
, val
, page
= 0;
903 int mac
= phydev
->mdio
.addr
;
905 u32
*rtl8380_rtl8214fc_perchip
;
906 u32
*rtl8380_rtl8214fc_perport
;
908 read_phy(mac
, 0, 2, &val
);
910 read_phy(mac
, 0, 3, &val
);
912 pr_debug("Phy on MAC %d: %x\n", mac
, phy_id
);
914 /* Read internal PHY id */
915 write_phy(mac
, 0, 30, 0x0001);
916 write_phy(mac
, 0, 31, 0x0a42);
917 write_phy(mac
, 31, 27, 0x0002);
918 read_phy(mac
, 31, 28, &val
);
920 phydev_err(phydev
, "Expected external RTL8214FC, found PHY-ID %x\n", val
);
923 phydev_info(phydev
, "Detected external RTL8214FC\n");
925 h
= rtl838x_request_fw(phydev
, &rtl838x_8214fc_fw
, FIRMWARE_838X_8214FC_1
);
929 if (h
->phy
!= 0x8214fc00) {
930 phydev_err(phydev
, "Wrong firmware file: PHY mismatch.\n");
934 rtl8380_rtl8214fc_perchip
= (void *)h
+ sizeof(struct fw_header
)
937 rtl8380_rtl8214fc_perport
= (void *)h
+ sizeof(struct fw_header
)
940 /* detect phy version */
941 write_phy(mac
, 0xfff, 27, 0x0004);
942 read_phy(mac
, 0xfff, 28, &val
);
944 read_phy(mac
, 0, 16, &val
);
946 rtl8380_rtl8214fc_on_off(mac
, true);
948 rtl8380_phy_reset(mac
);
951 write_phy(mac
, 0, 30, 0x0001);
954 while (rtl8380_rtl8214fc_perchip
[i
* 3]
955 && rtl8380_rtl8214fc_perchip
[i
* 3 + 1]) {
956 if (rtl8380_rtl8214fc_perchip
[i
* 3 + 1] == 0x1f)
957 page
= rtl8380_rtl8214fc_perchip
[i
* 3 + 2];
958 if (rtl8380_rtl8214fc_perchip
[i
* 3 + 1] == 0x13 && page
== 0x260) {
959 read_phy(mac
+ rtl8380_rtl8214fc_perchip
[i
* 3], 0x260, 13, &val
);
960 val
= (val
& 0x1f00) | (rtl8380_rtl8214fc_perchip
[i
* 3 + 2]
962 write_phy(mac
+ rtl8380_rtl8214fc_perchip
[i
* 3],
963 0xfff, rtl8380_rtl8214fc_perchip
[i
* 3 + 1], val
);
965 write_phy(mac
+ rtl8380_rtl8214fc_perchip
[i
* 3],
966 0xfff, rtl8380_rtl8214fc_perchip
[i
* 3 + 1],
967 rtl8380_rtl8214fc_perchip
[i
* 3 + 2]);
972 /* Force copper medium */
973 for (i
= 0; i
< 4; i
++) {
974 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0000);
975 write_phy(mac
+ i
, 0xfff, 0x1e, 0x0001);
979 for (i
= 0; i
< 4; i
++) {
980 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0000);
981 write_phy(mac
+ i
, 0xfff, 0x00, 0x1140);
985 /* Disable Autosensing */
986 for (i
= 0; i
< 4; i
++) {
987 for (l
= 0; l
< 100; l
++) {
988 read_phy(mac
+ i
, 0x0a42, 0x10, &val
);
989 if ((val
& 0x7) >= 3)
993 phydev_err(phydev
, "Could not disable autosensing\n");
999 for (i
= 0; i
< 4; i
++) {
1000 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0b82);
1001 write_phy(mac
+ i
, 0xfff, 0x10, 0x0010);
1005 /* Verify patch readiness */
1006 for (i
= 0; i
< 4; i
++) {
1007 for (l
= 0; l
< 100; l
++) {
1008 read_phy(mac
+ i
, 0xb80, 0x10, &val
);
1013 phydev_err(phydev
, "Could not patch PHY\n");
1018 /* Use Broadcast ID method for patching */
1019 write_phy(mac
, 0xfff, 0x1f, 0x0000);
1020 write_phy(mac
, 0xfff, 0x1d, 0x0008);
1021 write_phy(mac
, 0xfff, 0x1f, 0x0266);
1022 write_phy(mac
, 0xfff, 0x16, 0xff00 + mac
);
1023 write_phy(mac
, 0xfff, 0x1f, 0x0000);
1024 write_phy(mac
, 0xfff, 0x1d, 0x0000);
1028 while (rtl8380_rtl8214fc_perport
[i
* 2]) {
1029 write_phy(mac
, 0xfff, rtl8380_rtl8214fc_perport
[i
* 2],
1030 rtl8380_rtl8214fc_perport
[i
* 2 + 1]);
1034 /*Disable broadcast ID*/
1035 write_phy(mac
, 0xfff, 0x1f, 0x0000);
1036 write_phy(mac
, 0xfff, 0x1d, 0x0008);
1037 write_phy(mac
, 0xfff, 0x1f, 0x0266);
1038 write_phy(mac
, 0xfff, 0x16, 0x00 + mac
);
1039 write_phy(mac
, 0xfff, 0x1f, 0x0000);
1040 write_phy(mac
, 0xfff, 0x1d, 0x0000);
1043 /* Auto medium selection */
1044 for (i
= 0; i
< 4; i
++) {
1045 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0000);
1046 write_phy(mac
+ i
, 0xfff, 0x1e, 0x0000);
1052 static int rtl8214fc_match_phy_device(struct phy_device
*phydev
)
1054 int addr
= phydev
->mdio
.addr
;
1056 return phydev
->phy_id
== PHY_ID_RTL8214FC
&& addr
>= 24;
1059 static int rtl8380_configure_serdes(struct phy_device
*phydev
)
1064 struct fw_header
*h
;
1065 u32
*rtl8380_sds_take_reset
;
1066 u32
*rtl8380_sds_common
;
1067 u32
*rtl8380_sds01_qsgmii_6275b
;
1068 u32
*rtl8380_sds23_qsgmii_6275b
;
1069 u32
*rtl8380_sds4_fiber_6275b
;
1070 u32
*rtl8380_sds5_fiber_6275b
;
1071 u32
*rtl8380_sds_reset
;
1072 u32
*rtl8380_sds_release_reset
;
1074 phydev_info(phydev
, "Detected internal RTL8380 SERDES\n");
1076 h
= rtl838x_request_fw(phydev
, &rtl838x_8218b_fw
, FIRMWARE_838X_8380_1
);
1080 if (h
->magic
!= 0x83808380) {
1081 phydev_err(phydev
, "Wrong firmware file: magic number mismatch.\n");
1085 rtl8380_sds_take_reset
= (void *)h
+ sizeof(struct fw_header
)
1086 + h
->parts
[0].start
;
1088 rtl8380_sds_common
= (void *)h
+ sizeof(struct fw_header
)
1089 + h
->parts
[1].start
;
1091 rtl8380_sds01_qsgmii_6275b
= (void *)h
+ sizeof(struct fw_header
)
1092 + h
->parts
[2].start
;
1094 rtl8380_sds23_qsgmii_6275b
= (void *)h
+ sizeof(struct fw_header
)
1095 + h
->parts
[3].start
;
1097 rtl8380_sds4_fiber_6275b
= (void *)h
+ sizeof(struct fw_header
)
1098 + h
->parts
[4].start
;
1100 rtl8380_sds5_fiber_6275b
= (void *)h
+ sizeof(struct fw_header
)
1101 + h
->parts
[5].start
;
1103 rtl8380_sds_reset
= (void *)h
+ sizeof(struct fw_header
)
1104 + h
->parts
[6].start
;
1106 rtl8380_sds_release_reset
= (void *)h
+ sizeof(struct fw_header
)
1107 + h
->parts
[7].start
;
1109 /* Back up serdes power off value */
1110 sds_conf_value
= sw_r32(RTL838X_SDS_CFG_REG
);
1111 pr_info("SDS power down value: %x\n", sds_conf_value
);
1113 /* take serdes into reset */
1115 while (rtl8380_sds_take_reset
[2 * i
]) {
1116 sw_w32(rtl8380_sds_take_reset
[2 * i
+ 1], rtl8380_sds_take_reset
[2 * i
]);
1121 /* apply common serdes patch */
1123 while (rtl8380_sds_common
[2 * i
]) {
1124 sw_w32(rtl8380_sds_common
[2 * i
+ 1], rtl8380_sds_common
[2 * i
]);
1129 /* internal R/W enable */
1130 sw_w32(3, RTL838X_INT_RW_CTRL
);
1132 /* SerDes ports 4 and 5 are FIBRE ports */
1133 sw_w32_mask(0x7 | 0x38, 1 | (1 << 3), RTL838X_INT_MODE_CTRL
);
1135 /* SerDes module settings, SerDes 0-3 are QSGMII */
1136 v
= 0x6 << 25 | 0x6 << 20 | 0x6 << 15 | 0x6 << 10;
1137 /* SerDes 4 and 5 are 1000BX FIBRE */
1138 v
|= 0x4 << 5 | 0x4;
1139 sw_w32(v
, RTL838X_SDS_MODE_SEL
);
1141 pr_info("PLL control register: %x\n", sw_r32(RTL838X_PLL_CML_CTRL
));
1142 sw_w32_mask(0xfffffff0, 0xaaaaaaaf & 0xf, RTL838X_PLL_CML_CTRL
);
1144 while (rtl8380_sds01_qsgmii_6275b
[2 * i
]) {
1145 sw_w32(rtl8380_sds01_qsgmii_6275b
[2 * i
+ 1],
1146 rtl8380_sds01_qsgmii_6275b
[2 * i
]);
1151 while (rtl8380_sds23_qsgmii_6275b
[2 * i
]) {
1152 sw_w32(rtl8380_sds23_qsgmii_6275b
[2 * i
+ 1], rtl8380_sds23_qsgmii_6275b
[2 * i
]);
1157 while (rtl8380_sds4_fiber_6275b
[2 * i
]) {
1158 sw_w32(rtl8380_sds4_fiber_6275b
[2 * i
+ 1], rtl8380_sds4_fiber_6275b
[2 * i
]);
1163 while (rtl8380_sds5_fiber_6275b
[2 * i
]) {
1164 sw_w32(rtl8380_sds5_fiber_6275b
[2 * i
+ 1], rtl8380_sds5_fiber_6275b
[2 * i
]);
1169 while (rtl8380_sds_reset
[2 * i
]) {
1170 sw_w32(rtl8380_sds_reset
[2 * i
+ 1], rtl8380_sds_reset
[2 * i
]);
1175 while (rtl8380_sds_release_reset
[2 * i
]) {
1176 sw_w32(rtl8380_sds_release_reset
[2 * i
+ 1], rtl8380_sds_release_reset
[2 * i
]);
1180 pr_info("SDS power down value now: %x\n", sw_r32(RTL838X_SDS_CFG_REG
));
1181 sw_w32(sds_conf_value
, RTL838X_SDS_CFG_REG
);
1183 pr_info("Configuration of SERDES done\n");
1187 static int rtl8390_configure_serdes(struct phy_device
*phydev
)
1189 phydev_info(phydev
, "Detected internal RTL8390 SERDES\n");
1191 /* In autoneg state, force link, set SR4_CFG_EN_LINK_FIB1G */
1192 sw_w32_mask(0, 1 << 18, RTL839X_SDS12_13_XSG0
+ 0x0a);
1194 /* Disable EEE: Clear FRE16_EEE_RSG_FIB1G, FRE16_EEE_STD_FIB1G,
1195 * FRE16_C1_PWRSAV_EN_FIB1G, FRE16_C2_PWRSAV_EN_FIB1G
1196 * and FRE16_EEE_QUIET_FIB1G
1198 sw_w32_mask(0x1f << 10, 0, RTL839X_SDS12_13_XSG0
+ 0xe0);
1203 static int rtl8214fc_phy_probe(struct phy_device
*phydev
)
1205 struct device
*dev
= &phydev
->mdio
.dev
;
1206 struct rtl838x_phy_priv
*priv
;
1207 int addr
= phydev
->mdio
.addr
;
1209 /* 839x has internal SerDes */
1210 if (soc_info
.id
== 0x8393)
1213 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1217 priv
->name
= "RTL8214FC";
1219 /* All base addresses of the PHYs start at multiples of 8 */
1221 /* Configuration must be done whil patching still possible */
1222 return rtl8380_configure_rtl8214fc(phydev
);
1227 static int rtl8214c_phy_probe(struct phy_device
*phydev
)
1229 struct device
*dev
= &phydev
->mdio
.dev
;
1230 struct rtl838x_phy_priv
*priv
;
1231 int addr
= phydev
->mdio
.addr
;
1233 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1237 priv
->name
= "RTL8214C";
1239 /* All base addresses of the PHYs start at multiples of 8 */
1241 /* Configuration must be done whil patching still possible */
1242 return rtl8380_configure_rtl8214c(phydev
);
1247 static int rtl8218b_ext_phy_probe(struct phy_device
*phydev
)
1249 struct device
*dev
= &phydev
->mdio
.dev
;
1250 struct rtl838x_phy_priv
*priv
;
1251 int addr
= phydev
->mdio
.addr
;
1253 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1257 priv
->name
= "RTL8218B (external)";
1259 /* All base addresses of the PHYs start at multiples of 8 */
1260 if (!(addr
% 8) && soc_info
.family
== RTL8380_FAMILY_ID
) {
1261 /* Configuration must be done while patching still possible */
1262 return rtl8380_configure_ext_rtl8218b(phydev
);
1267 static int rtl8218b_int_phy_probe(struct phy_device
*phydev
)
1269 struct device
*dev
= &phydev
->mdio
.dev
;
1270 struct rtl838x_phy_priv
*priv
;
1271 int addr
= phydev
->mdio
.addr
;
1273 if (soc_info
.family
!= RTL8380_FAMILY_ID
)
1278 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1282 priv
->name
= "RTL8218B (internal)";
1284 /* All base addresses of the PHYs start at multiples of 8 */
1286 /* Configuration must be done while patching still possible */
1287 return rtl8380_configure_int_rtl8218b(phydev
);
1292 static int rtl838x_serdes_probe(struct phy_device
*phydev
)
1294 struct device
*dev
= &phydev
->mdio
.dev
;
1295 struct rtl838x_phy_priv
*priv
;
1296 int addr
= phydev
->mdio
.addr
;
1298 if (soc_info
.family
!= RTL8380_FAMILY_ID
)
1303 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1307 priv
->name
= "RTL8380 Serdes";
1309 /* On the RTL8380M, PHYs 24-27 connect to the internal SerDes */
1310 if (soc_info
.id
== 0x8380) {
1312 return rtl8380_configure_serdes(phydev
);
1318 static int rtl8393_serdes_probe(struct phy_device
*phydev
)
1320 struct device
*dev
= &phydev
->mdio
.dev
;
1321 struct rtl838x_phy_priv
*priv
;
1322 int addr
= phydev
->mdio
.addr
;
1324 pr_info("%s: id: %d\n", __func__
, addr
);
1325 if (soc_info
.family
!= RTL8390_FAMILY_ID
)
1331 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1335 priv
->name
= "RTL8393 Serdes";
1336 return rtl8390_configure_serdes(phydev
);
1339 static int rtl8390_serdes_probe(struct phy_device
*phydev
)
1341 struct device
*dev
= &phydev
->mdio
.dev
;
1342 struct rtl838x_phy_priv
*priv
;
1343 int addr
= phydev
->mdio
.addr
;
1345 if (soc_info
.family
!= RTL8390_FAMILY_ID
)
1351 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1355 priv
->name
= "RTL8390 Serdes";
1356 return rtl8390_configure_generic(phydev
);
1359 static struct phy_driver rtl838x_phy_driver
[] = {
1361 PHY_ID_MATCH_MODEL(PHY_ID_RTL8214C
),
1362 .name
= "REALTEK RTL8214C",
1363 .features
= PHY_GBIT_FEATURES
,
1364 .match_phy_device
= rtl8214c_match_phy_device
,
1365 .probe
= rtl8214c_phy_probe
,
1366 .suspend
= genphy_suspend
,
1367 .resume
= genphy_resume
,
1368 .set_loopback
= genphy_loopback
,
1371 PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC
),
1372 .name
= "REALTEK RTL8214FC",
1373 .features
= PHY_GBIT_FIBRE_FEATURES
,
1374 .match_phy_device
= rtl8214fc_match_phy_device
,
1375 .probe
= rtl8214fc_phy_probe
,
1376 .suspend
= genphy_suspend
,
1377 .resume
= genphy_resume
,
1378 .set_loopback
= genphy_loopback
,
1379 .read_mmd
= rtl8380_rtl8218b_read_mmd
,
1380 .write_mmd
= rtl8380_rtl8218b_write_mmd
,
1381 .set_port
= rtl8380_rtl8214fc_set_port
,
1382 .get_port
= rtl8380_rtl8214fc_get_port
,
1383 .set_eee
= rtl8380_rtl8214fc_set_eee
,
1384 .get_eee
= rtl8380_rtl8214fc_get_eee
,
1387 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_E
),
1388 .name
= "REALTEK RTL8218B (external)",
1389 .features
= PHY_GBIT_FEATURES
,
1390 .match_phy_device
= rtl8218b_ext_match_phy_device
,
1391 .probe
= rtl8218b_ext_phy_probe
,
1392 .suspend
= genphy_suspend
,
1393 .resume
= genphy_resume
,
1394 .set_loopback
= genphy_loopback
,
1395 .read_mmd
= rtl8380_rtl8218b_read_mmd
,
1396 .write_mmd
= rtl8380_rtl8218b_write_mmd
,
1397 .set_eee
= rtl8380_rtl8218b_set_eee
,
1398 .get_eee
= rtl8380_rtl8218b_get_eee_u_boot
,
1401 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I
),
1402 .name
= "REALTEK RTL8218B (internal)",
1403 .features
= PHY_GBIT_FEATURES
,
1404 .probe
= rtl8218b_int_phy_probe
,
1405 .suspend
= genphy_suspend
,
1406 .resume
= genphy_resume
,
1407 .set_loopback
= genphy_loopback
,
1408 .read_mmd
= rtl8380_rtl8218b_read_mmd
,
1409 .write_mmd
= rtl8380_rtl8218b_write_mmd
,
1410 .set_eee
= rtl8380_rtl8218b_set_eee
,
1411 .get_eee
= rtl8380_rtl8218b_get_eee_u_boot
,
1414 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I
),
1415 .name
= "REALTEK RTL8380 SERDES",
1416 .features
= PHY_GBIT_FIBRE_FEATURES
,
1417 .probe
= rtl838x_serdes_probe
,
1418 .suspend
= genphy_suspend
,
1419 .resume
= genphy_resume
,
1420 .set_loopback
= genphy_loopback
,
1421 .read_mmd
= rtl8380_rtl8218b_read_mmd
,
1422 .write_mmd
= rtl8380_rtl8218b_write_mmd
,
1423 .read_status
= rtl8380_read_status
,
1426 PHY_ID_MATCH_MODEL(PHY_ID_RTL8393_I
),
1427 .name
= "REALTEK RTL8393 SERDES",
1428 .features
= PHY_GBIT_FIBRE_FEATURES
,
1429 .probe
= rtl8393_serdes_probe
,
1430 .suspend
= genphy_suspend
,
1431 .resume
= genphy_resume
,
1432 .set_loopback
= genphy_loopback
,
1433 .read_status
= rtl8393_read_status
,
1436 PHY_ID_MATCH_MODEL(PHY_ID_RTL8390_GENERIC
),
1437 .name
= "REALTEK RTL8390 Generic",
1438 .features
= PHY_GBIT_FIBRE_FEATURES
,
1439 .probe
= rtl8390_serdes_probe
,
1440 .suspend
= genphy_suspend
,
1441 .resume
= genphy_resume
,
1442 .set_loopback
= genphy_loopback
,
1446 module_phy_driver(rtl838x_phy_driver
);
1448 static struct mdio_device_id __maybe_unused rtl838x_tbl
[] = {
1449 { PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC
) },
1453 MODULE_DEVICE_TABLE(mdio
, rtl838x_tbl
);
1455 MODULE_AUTHOR("B. Koblitz");
1456 MODULE_DESCRIPTION("RTL838x PHY driver");
1457 MODULE_LICENSE("GPL");