1 // SPDX-License-Identifier: GPL-2.0
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
27 struct __attribute__ ((__packed__
)) part
{
33 struct __attribute__ ((__packed__
)) fw_header
{
38 struct part parts
[10];
41 #define FIRMWARE_838X_8380_1 "rtl838x_phy/rtl838x_8380.fw"
42 #define FIRMWARE_838X_8214FC_1 "rtl838x_phy/rtl838x_8214fc.fw"
43 #define FIRMWARE_838X_8218b_1 "rtl838x_phy/rtl838x_8218b.fw"
45 static const struct firmware rtl838x_8380_fw
;
46 static const struct firmware rtl838x_8214fc_fw
;
47 static const struct firmware rtl838x_8218b_fw
;
49 struct rtl838x_phy_priv
{
53 static int read_phy(u32 port
, u32 page
, u32 reg
, u32
*val
)
55 if (soc_info
.family
== RTL8390_FAMILY_ID
)
56 return rtl839x_read_phy(port
, page
, reg
, val
);
58 return rtl838x_read_phy(port
, page
, reg
, val
);
61 static int write_phy(u32 port
, u32 page
, u32 reg
, u32 val
)
63 if (soc_info
.family
== RTL8390_FAMILY_ID
)
64 return rtl839x_write_phy(port
, page
, reg
, val
);
66 return rtl838x_write_phy(port
, page
, reg
, val
);
69 static void rtl8380_int_phy_on_off(int mac
, bool on
)
73 read_phy(mac
, 0, 0, &val
);
75 write_phy(mac
, 0, 0, val
& ~(1 << 11));
77 write_phy(mac
, 0, 0, val
| (1 << 11));
80 static void rtl8380_rtl8214fc_on_off(int mac
, bool on
)
85 write_phy(mac
, 4095, 30, 3);
86 read_phy(mac
, 0, 16, &val
);
88 write_phy(mac
, 0, 16, val
& ~(1 << 11));
90 write_phy(mac
, 0, 16, val
| (1 << 11));
93 write_phy(mac
, 4095, 30, 1);
94 read_phy(mac
, 0, 16, &val
);
96 write_phy(mac
, 0xa40, 16, val
& ~(1 << 11));
98 write_phy(mac
, 0xa40, 16, val
| (1 << 11));
101 static void rtl8380_phy_reset(int mac
)
105 read_phy(mac
, 0, 0, &val
);
106 write_phy(mac
, 0, 0, val
| (0x1 << 15));
109 void rtl8380_sds_rst(int mac
)
111 u32 offset
= (mac
== 24) ? 0 : 0x100;
113 sw_w32_mask(1 << 11, 0, RTL8380_SDS4_FIB_REG0
+ offset
);
114 sw_w32_mask(0x3, 0, RTL838X_SDS4_REG28
+ offset
);
115 sw_w32_mask(0x3, 0x3, RTL838X_SDS4_REG28
+ offset
);
116 sw_w32_mask(0, 0x1 << 6, RTL838X_SDS4_DUMMY0
+ offset
);
117 sw_w32_mask(0x1 << 6, 0, RTL838X_SDS4_DUMMY0
+ offset
);
118 pr_info("SERDES reset: %d\n", mac
);
121 static struct fw_header
*
122 rtl838x_request_fw(struct phy_device
*phydev
, const struct firmware
*fw
,
125 struct device
*dev
= &phydev
->mdio
.dev
;
128 uint32_t checksum
, my_checksum
;
130 err
= request_firmware(&fw
, name
, dev
);
134 if (fw
->size
< sizeof(struct fw_header
)) {
135 pr_err("Firmware size too small.\n");
140 h
= (struct fw_header
*) fw
->data
;
141 pr_info("Firmware loaded. Size %d, magic: %08x\n", fw
->size
, h
->magic
);
143 if (h
->phy
!= 0x83800000) {
144 pr_err("Wrong firmware file: PHY mismatch.\n");
148 checksum
= h
->checksum
;
150 my_checksum
= ~crc32(0xFFFFFFFFU
, fw
->data
, fw
->size
);
151 if (checksum
!= my_checksum
) {
152 pr_err("Firmware checksum mismatch.\n");
156 h
->checksum
= checksum
;
160 dev_err(dev
, "Unable to load firmware %s (%d)\n", name
, err
);
164 static int rtl8390_configure_generic(struct phy_device
*phydev
)
167 int mac
= phydev
->mdio
.addr
;
169 read_phy(mac
, 0, 2, &val
);
171 read_phy(mac
, 0, 3, &val
);
173 pr_debug("Phy on MAC %d: %x\n", mac
, phy_id
);
175 /* Read internal PHY ID */
176 write_phy(mac
, 31, 27, 0x0002);
177 read_phy(mac
, 31, 28, &val
);
179 /* Internal RTL8218B, version 2 */
180 phydev_info(phydev
, "Detected unknown %x\n", val
);
184 static int rtl8380_configure_int_rtl8218b(struct phy_device
*phydev
)
188 int mac
= phydev
->mdio
.addr
;
190 u32
*rtl838x_6275B_intPhy_perport
;
191 u32
*rtl8218b_6276B_hwEsd_perport
;
194 read_phy(mac
, 0, 2, &val
);
196 read_phy(mac
, 0, 3, &val
);
198 pr_debug("Phy on MAC %d: %x\n", mac
, phy_id
);
200 /* Read internal PHY ID */
201 write_phy(mac
, 31, 27, 0x0002);
202 read_phy(mac
, 31, 28, &val
);
204 phydev_err(phydev
, "Expected internal RTL8218B, found PHY-ID %x\n", val
);
208 /* Internal RTL8218B, version 2 */
209 phydev_info(phydev
, "Detected internal RTL8218B\n");
211 h
= rtl838x_request_fw(phydev
, &rtl838x_8380_fw
, FIRMWARE_838X_8380_1
);
215 if (h
->phy
!= 0x83800000) {
216 phydev_err(phydev
, "Wrong firmware file: PHY mismatch.\n");
220 rtl838x_6275B_intPhy_perport
= (void *)h
+ sizeof(struct fw_header
)
223 rtl8218b_6276B_hwEsd_perport
= (void *)h
+ sizeof(struct fw_header
)
226 if (sw_r32(RTL838X_DMY_REG31
) == 0x1)
229 read_phy(mac
, 0, 0, &val
);
231 rtl8380_int_phy_on_off(mac
, true);
233 rtl8380_phy_reset(mac
);
236 /* Ready PHY for patch */
237 for (p
= 0; p
< 8; p
++) {
238 write_phy(mac
+ p
, 0xfff, 0x1f, 0x0b82);
239 write_phy(mac
+ p
, 0xfff, 0x10, 0x0010);
242 for (p
= 0; p
< 8; p
++) {
243 for (i
= 0; i
< 100 ; i
++) {
244 read_phy(mac
+ p
, 0x0b80, 0x10, &val
);
250 "ERROR: Port %d not ready for patch.\n",
255 for (p
= 0; p
< 8; p
++) {
257 while (rtl838x_6275B_intPhy_perport
[i
* 2]) {
258 write_phy(mac
+ p
, 0xfff,
259 rtl838x_6275B_intPhy_perport
[i
* 2],
260 rtl838x_6275B_intPhy_perport
[i
* 2 + 1]);
264 while (rtl8218b_6276B_hwEsd_perport
[i
* 2]) {
265 write_phy(mac
+ p
, 0xfff,
266 rtl8218b_6276B_hwEsd_perport
[i
* 2],
267 rtl8218b_6276B_hwEsd_perport
[i
* 2 + 1]);
274 static int rtl8380_configure_ext_rtl8218b(struct phy_device
*phydev
)
276 u32 val
, ipd
, phy_id
;
278 int mac
= phydev
->mdio
.addr
;
280 u32
*rtl8380_rtl8218b_perchip
;
281 u32
*rtl8218B_6276B_rtl8380_perport
;
282 u32
*rtl8380_rtl8218b_perport
;
284 if (soc_info
.family
== RTL8380_FAMILY_ID
&& mac
!= 0 && mac
!= 16) {
285 phydev_err(phydev
, "External RTL8218B must have PHY-IDs 0 or 16!\n");
288 read_phy(mac
, 0, 2, &val
);
290 read_phy(mac
, 0, 3, &val
);
292 pr_info("Phy on MAC %d: %x\n", mac
, phy_id
);
294 /* Read internal PHY ID */
295 write_phy(mac
, 31, 27, 0x0002);
296 read_phy(mac
, 31, 28, &val
);
298 phydev_err(phydev
, "Expected external RTL8218B, found PHY-ID %x\n", val
);
301 phydev_info(phydev
, "Detected external RTL8218B\n");
303 h
= rtl838x_request_fw(phydev
, &rtl838x_8218b_fw
, FIRMWARE_838X_8218b_1
);
307 if (h
->phy
!= 0x8218b00) {
308 phydev_err(phydev
, "Wrong firmware file: PHY mismatch.\n");
312 rtl8380_rtl8218b_perchip
= (void *)h
+ sizeof(struct fw_header
)
315 rtl8218B_6276B_rtl8380_perport
= (void *)h
+ sizeof(struct fw_header
)
318 rtl8380_rtl8218b_perport
= (void *)h
+ sizeof(struct fw_header
)
321 read_phy(mac
, 0, 0, &val
);
323 rtl8380_int_phy_on_off(mac
, true);
325 rtl8380_phy_reset(mac
);
328 /* Get Chip revision */
329 write_phy(mac
, 0xfff, 0x1f, 0x0);
330 write_phy(mac
, 0xfff, 0x1b, 0x4);
331 read_phy(mac
, 0xfff, 0x1c, &val
);
334 while (rtl8380_rtl8218b_perchip
[i
* 3]
335 && rtl8380_rtl8218b_perchip
[i
* 3 + 1]) {
336 write_phy(mac
+ rtl8380_rtl8218b_perchip
[i
* 3],
337 0xfff, rtl8380_rtl8218b_perchip
[i
* 3 + 1],
338 rtl8380_rtl8218b_perchip
[i
* 3 + 2]);
343 for (i
= 0; i
< 8; i
++) {
344 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0000);
345 write_phy(mac
+ i
, 0xfff, 0x00, 0x1140);
350 for (i
= 0; i
< 8; i
++) {
351 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0b82);
352 write_phy(mac
+ i
, 0xfff, 0x10, 0x0010);
356 /* Verify patch readiness */
357 for (i
= 0; i
< 8; i
++) {
358 for (l
= 0; l
< 100; l
++) {
359 read_phy(mac
+ i
, 0xb80, 0x10, &val
);
364 phydev_err(phydev
, "Could not patch PHY\n");
369 /* Use Broadcast ID method for patching */
370 write_phy(mac
, 0xfff, 0x1f, 0x0000);
371 write_phy(mac
, 0xfff, 0x1d, 0x0008);
372 write_phy(mac
, 0xfff, 0x1f, 0x0266);
373 write_phy(mac
, 0xfff, 0x16, 0xff00 + mac
);
374 write_phy(mac
, 0xfff, 0x1f, 0x0000);
375 write_phy(mac
, 0xfff, 0x1d, 0x0000);
378 write_phy(mac
, 0xfff, 30, 8);
379 write_phy(mac
, 0x26e, 17, 0xb);
380 write_phy(mac
, 0x26e, 16, 0x2);
382 read_phy(mac
, 0x26e, 19, &ipd
);
383 write_phy(mac
, 0, 30, 0);
384 ipd
= (ipd
>> 4) & 0xf;
387 while (rtl8218B_6276B_rtl8380_perport
[i
* 2]) {
388 write_phy(mac
, 0xfff, rtl8218B_6276B_rtl8380_perport
[i
* 2],
389 rtl8218B_6276B_rtl8380_perport
[i
* 2 + 1]);
393 /*Disable broadcast ID*/
394 write_phy(mac
, 0xfff, 0x1f, 0x0000);
395 write_phy(mac
, 0xfff, 0x1d, 0x0008);
396 write_phy(mac
, 0xfff, 0x1f, 0x0266);
397 write_phy(mac
, 0xfff, 0x16, 0x00 + mac
);
398 write_phy(mac
, 0xfff, 0x1f, 0x0000);
399 write_phy(mac
, 0xfff, 0x1d, 0x0000);
405 static int rtl8218b_ext_match_phy_device(struct phy_device
*phydev
)
407 int addr
= phydev
->mdio
.addr
;
409 return phydev
->phy_id
== PHY_ID_RTL8218B_E
&& addr
< 8;
413 static int rtl8380_rtl8218b_write_mmd(struct phy_device
*phydev
,
414 int devnum
, u16 regnum
, u16 val
)
416 int addr
= phydev
->mdio
.addr
;
418 return rtl838x_write_mmd_phy(addr
, devnum
, regnum
, val
);
421 static int rtl8380_rtl8218b_read_mmd(struct phy_device
*phydev
,
422 int devnum
, u16 regnum
)
426 int addr
= phydev
->mdio
.addr
;
428 ret
= rtl838x_read_mmd_phy(addr
, devnum
, regnum
, &val
);
434 static void rtl8380_rtl8214fc_media_set(int mac
, bool set_fibre
)
436 int base
= mac
- (mac
% 4);
437 static int reg
[] = {16, 19, 20, 21};
438 int val
, media
, power
;
440 pr_info("%s: port %d, set_fibre: %d\n", __func__
, mac
, set_fibre
);
441 write_phy(base
, 0xfff, 29, 8);
442 read_phy(base
, 0x266, reg
[mac
% 4], &val
);
444 media
= (val
>> 10) & 0x3;
445 pr_info("Current media %x\n", media
);
447 pr_info("Powering off COPPER\n");
448 write_phy(base
, 0xfff, 29, 1);
449 /* Ensure power is off */
450 read_phy(base
, 0xa40, 16, &power
);
451 if (!(power
& (1 << 11)))
452 write_phy(base
, 0xa40, 16, power
| (1 << 11));
454 pr_info("Powering off FIBRE");
455 write_phy(base
, 0xfff, 29, 3);
456 /* Ensure power is off */
457 read_phy(base
, 0xa40, 16, &power
);
458 if (!(power
& (1 << 11)))
459 write_phy(base
, 0xa40, 16, power
| (1 << 11));
469 write_phy(base
, 0xfff, 29, 8);
470 write_phy(base
, 0x266, reg
[mac
% 4], val
);
471 write_phy(base
, 0xfff, 29, 0);
474 pr_info("Powering on FIBRE");
475 write_phy(base
, 0xfff, 29, 3);
476 /* Ensure power is off */
477 read_phy(base
, 0xa40, 16, &power
);
478 if (power
& (1 << 11))
479 write_phy(base
, 0xa40, 16, power
& ~(1 << 11));
481 pr_info("Powering on COPPER\n");
482 write_phy(base
, 0xfff, 29, 1);
483 /* Ensure power is off */
484 read_phy(base
, 0xa40, 16, &power
);
485 if (power
& (1 << 11))
486 write_phy(base
, 0xa40, 16, power
& ~(1 << 11));
489 write_phy(base
, 0xfff, 29, 0);
492 static bool rtl8380_rtl8214fc_media_is_fibre(int mac
)
494 int base
= mac
- (mac
% 4);
495 static int reg
[] = {16, 19, 20, 21};
498 write_phy(base
, 0xfff, 29, 8);
499 read_phy(base
, 0x266, reg
[mac
% 4], &val
);
500 write_phy(base
, 0xfff, 29, 0);
506 static int rtl8380_rtl8214fc_set_port(struct phy_device
*phydev
, int port
)
508 bool is_fibre
= (port
== PORT_FIBRE
? true : false);
509 int addr
= phydev
->mdio
.addr
;
511 pr_debug("%s port %d to %d\n", __func__
, addr
, port
);
513 rtl8380_rtl8214fc_media_set(addr
, is_fibre
);
517 static int rtl8380_rtl8214fc_get_port(struct phy_device
*phydev
)
519 int addr
= phydev
->mdio
.addr
;
521 pr_debug("%s: port %d\n", __func__
, addr
);
522 if (rtl8380_rtl8214fc_media_is_fibre(addr
))
527 void rtl8380_rtl8214fc_ldps_set(int mac
, struct ethtool_eee
*e
)
532 static void rtl8380_rtl8218b_eee_set_u_boot(int port
, bool enable
)
537 /* Set GPHY page to copper */
538 write_phy(port
, 0, 30, 0x0001);
539 read_phy(port
, 0, 0, &val
);
540 an_enabled
= val
& (1 << 12);
543 /* 100/1000M EEE Capability */
544 write_phy(port
, 0, 13, 0x0007);
545 write_phy(port
, 0, 14, 0x003C);
546 write_phy(port
, 0, 13, 0x4007);
547 write_phy(port
, 0, 14, 0x0006);
549 read_phy(port
, 0x0A43, 25, &val
);
551 write_phy(port
, 0x0A43, 25, val
);
553 /* 100/1000M EEE Capability */
554 write_phy(port
, 0, 13, 0x0007);
555 write_phy(port
, 0, 14, 0x003C);
556 write_phy(port
, 0, 13, 0x0007);
557 write_phy(port
, 0, 14, 0x0000);
559 read_phy(port
, 0x0A43, 25, &val
);
561 write_phy(port
, 0x0A43, 25, val
);
564 /* Restart AN if enabled */
566 read_phy(port
, 0, 0, &val
);
567 val
|= (1 << 12) | (1 << 9);
568 write_phy(port
, 0, 0, val
);
571 /* GPHY page back to auto*/
572 write_phy(port
, 0xa42, 29, 0);
575 static int rtl8380_rtl8218b_get_eee_u_boot(struct phy_device
*phydev
, struct ethtool_eee
*e
)
578 int addr
= phydev
->mdio
.addr
;
580 pr_debug("In %s %d\n", __func__
, addr
);
582 /* Set GPHY page to copper */
583 write_phy(addr
, 0xa42, 29, 0x0001);
585 read_phy(addr
, 0xa43, 25, &val
);
586 if (e
->eee_enabled
&& (!!(val
& (1 << 4))))
587 e
->eee_enabled
= !!(val
& (1 << 4));
591 /* GPHY page to auto */
592 write_phy(addr
, 0xa42, 29, 0x0000);
597 void rtl8380_rtl8218b_eee_set(int port
, bool enable
)
602 pr_debug("In %s %d, enable %d\n", __func__
, port
, enable
);
603 /* Set GPHY page to copper */
604 write_phy(port
, 0xa42, 29, 0x0001);
606 read_phy(port
, 0, 0, &val
);
607 an_enabled
= val
& (1 << 12);
610 read_phy(port
, 0xa43, 25, &val
);
612 write_phy(port
, 0xa43, 25, val
);
614 /* 100M / 1000M EEE */
616 rtl838x_write_mmd_phy(port
, 7, 60, 0x6);
618 rtl838x_write_mmd_phy(port
, 7, 60, 0);
620 /* 500M EEE ability */
621 read_phy(port
, 0xa42, 20, &val
);
626 write_phy(port
, 0xa42, 20, val
);
628 /* Restart AN if enabled */
630 read_phy(port
, 0, 0, &val
);
631 val
|= (1 << 12) | (1 << 9);
632 write_phy(port
, 0, 0, val
);
635 /* GPHY page back to auto*/
636 write_phy(port
, 0xa42, 29, 0);
639 int rtl8380_rtl8218b_get_eee(struct phy_device
*phydev
,
640 struct ethtool_eee
*e
)
643 int addr
= phydev
->mdio
.addr
;
645 pr_debug("In %s, port %d\n", __func__
, addr
);
647 /* Set GPHY page to copper */
648 write_phy(addr
, 0xa42, 29, 0x0001);
650 rtl838x_read_mmd_phy(addr
, 7, 60, &val
);
651 if (e
->eee_enabled
&& (!!(val
& (1 << 7))))
652 e
->eee_enabled
= !!(val
& (1 << 7));
656 /* GPHY page to auto */
657 write_phy(addr
, 0xa42, 29, 0x0000);
662 void rtl8380_rtl8218b_green_set(int mac
, bool enable
)
666 /* Set GPHY page to copper */
667 write_phy(mac
, 0xa42, 29, 0x0001);
669 write_phy(mac
, 0, 27, 0x8011);
670 read_phy(mac
, 0, 28, &val
);
673 write_phy(mac
, 0, 27, 0x8011);
674 write_phy(mac
, 0, 28, val
);
677 write_phy(mac
, 0, 27, 0x8011);
678 write_phy(mac
, 0, 28, val
);
681 /* GPHY page to auto */
682 write_phy(mac
, 0xa42, 29, 0x0000);
685 int rtl8380_rtl8214fc_get_green(struct phy_device
*phydev
, struct ethtool_eee
*e
)
688 int addr
= phydev
->mdio
.addr
;
690 pr_debug("In %s %d\n", __func__
, addr
);
691 /* Set GPHY page to copper */
692 write_phy(addr
, 0xa42, 29, 0x0001);
694 write_phy(addr
, 0, 27, 0x8011);
695 read_phy(addr
, 0, 28, &val
);
696 if (e
->eee_enabled
&& (!!(val
& (1 << 9))))
697 e
->eee_enabled
= !!(val
& (1 << 9));
701 /* GPHY page to auto */
702 write_phy(addr
, 0xa42, 29, 0x0000);
707 static int rtl8380_rtl8214fc_set_eee(struct phy_device
*phydev
,
708 struct ethtool_eee
*e
)
711 int addr
= phydev
->mdio
.addr
;
713 pr_debug("In %s port %d, enabled %d\n", __func__
, addr
, e
->eee_enabled
);
715 if (rtl8380_rtl8214fc_media_is_fibre(addr
)) {
716 netdev_err(phydev
->attached_dev
, "Port %d configured for FIBRE", addr
);
720 pollMask
= sw_r32(RTL838X_SMI_POLL_CTRL
);
721 sw_w32(0, RTL838X_SMI_POLL_CTRL
);
722 rtl8380_rtl8218b_eee_set_u_boot(addr
, (bool) e
->eee_enabled
);
723 sw_w32(pollMask
, RTL838X_SMI_POLL_CTRL
);
727 static int rtl8380_rtl8214fc_get_eee(struct phy_device
*phydev
,
728 struct ethtool_eee
*e
)
730 int addr
= phydev
->mdio
.addr
;
732 pr_debug("In %s port %d, enabled %d\n", __func__
, addr
, e
->eee_enabled
);
733 if (rtl8380_rtl8214fc_media_is_fibre(addr
)) {
734 netdev_err(phydev
->attached_dev
, "Port %d configured for FIBRE", addr
);
738 return rtl8380_rtl8218b_get_eee_u_boot(phydev
, e
);
741 static int rtl8380_rtl8218b_set_eee(struct phy_device
*phydev
,
742 struct ethtool_eee
*e
)
745 int addr
= phydev
->mdio
.addr
;
747 pr_debug("In %s, port %d, enabled %d\n", __func__
, addr
, e
->eee_enabled
);
749 pollMask
= sw_r32(RTL838X_SMI_POLL_CTRL
);
750 sw_w32(0, RTL838X_SMI_POLL_CTRL
);
751 rtl8380_rtl8218b_eee_set_u_boot(addr
, (bool) e
->eee_enabled
);
752 sw_w32(pollMask
, RTL838X_SMI_POLL_CTRL
);
757 static int rtl8214c_match_phy_device(struct phy_device
*phydev
)
759 return phydev
->phy_id
== PHY_ID_RTL8214C
;
762 static int rtl8380_configure_rtl8214c(struct phy_device
*phydev
)
765 int mac
= phydev
->mdio
.addr
;
767 read_phy(mac
, 0, 2, &val
);
769 read_phy(mac
, 0, 3, &val
);
771 pr_debug("Phy on MAC %d: %x\n", mac
, phy_id
);
773 phydev_info(phydev
, "Detected external RTL8214C\n");
776 write_phy(mac
, 0xa42, 29, 0);
780 static int rtl8380_configure_rtl8214fc(struct phy_device
*phydev
)
782 u32 phy_id
, val
, page
= 0;
784 int mac
= phydev
->mdio
.addr
;
786 u32
*rtl8380_rtl8214fc_perchip
;
787 u32
*rtl8380_rtl8214fc_perport
;
789 read_phy(mac
, 0, 2, &val
);
791 read_phy(mac
, 0, 3, &val
);
793 pr_debug("Phy on MAC %d: %x\n", mac
, phy_id
);
795 /* Read internal PHY id */
796 write_phy(mac
, 0, 30, 0x0001);
797 write_phy(mac
, 0, 31, 0x0a42);
798 write_phy(mac
, 31, 27, 0x0002);
799 read_phy(mac
, 31, 28, &val
);
801 phydev_err(phydev
, "Expected external RTL8214FC, found PHY-ID %x\n", val
);
804 phydev_info(phydev
, "Detected external RTL8214FC\n");
806 h
= rtl838x_request_fw(phydev
, &rtl838x_8214fc_fw
, FIRMWARE_838X_8214FC_1
);
810 if (h
->phy
!= 0x8214fc00) {
811 phydev_err(phydev
, "Wrong firmware file: PHY mismatch.\n");
815 rtl8380_rtl8214fc_perchip
= (void *)h
+ sizeof(struct fw_header
)
818 rtl8380_rtl8214fc_perport
= (void *)h
+ sizeof(struct fw_header
)
821 /* detect phy version */
822 write_phy(mac
, 0xfff, 27, 0x0004);
823 read_phy(mac
, 0xfff, 28, &val
);
825 read_phy(mac
, 0, 16, &val
);
827 rtl8380_rtl8214fc_on_off(mac
, true);
829 rtl8380_phy_reset(mac
);
832 write_phy(mac
, 0, 30, 0x0001);
835 while (rtl8380_rtl8214fc_perchip
[i
* 3]
836 && rtl8380_rtl8214fc_perchip
[i
* 3 + 1]) {
837 if (rtl8380_rtl8214fc_perchip
[i
* 3 + 1] == 0x1f)
838 page
= rtl8380_rtl8214fc_perchip
[i
* 3 + 2];
839 if (rtl8380_rtl8214fc_perchip
[i
* 3 + 1] == 0x13 && page
== 0x260) {
840 read_phy(mac
+ rtl8380_rtl8214fc_perchip
[i
* 3], 0x260, 13, &val
);
841 val
= (val
& 0x1f00) | (rtl8380_rtl8214fc_perchip
[i
* 3 + 2]
843 write_phy(mac
+ rtl8380_rtl8214fc_perchip
[i
* 3],
844 0xfff, rtl8380_rtl8214fc_perchip
[i
* 3 + 1], val
);
846 write_phy(mac
+ rtl8380_rtl8214fc_perchip
[i
* 3],
847 0xfff, rtl8380_rtl8214fc_perchip
[i
* 3 + 1],
848 rtl8380_rtl8214fc_perchip
[i
* 3 + 2]);
853 /* Force copper medium */
854 for (i
= 0; i
< 4; i
++) {
855 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0000);
856 write_phy(mac
+ i
, 0xfff, 0x1e, 0x0001);
860 for (i
= 0; i
< 4; i
++) {
861 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0000);
862 write_phy(mac
+ i
, 0xfff, 0x00, 0x1140);
866 /* Disable Autosensing */
867 for (i
= 0; i
< 4; i
++) {
868 for (l
= 0; l
< 100; l
++) {
869 read_phy(mac
+ i
, 0x0a42, 0x10, &val
);
870 if ((val
& 0x7) >= 3)
874 phydev_err(phydev
, "Could not disable autosensing\n");
880 for (i
= 0; i
< 4; i
++) {
881 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0b82);
882 write_phy(mac
+ i
, 0xfff, 0x10, 0x0010);
886 /* Verify patch readiness */
887 for (i
= 0; i
< 4; i
++) {
888 for (l
= 0; l
< 100; l
++) {
889 read_phy(mac
+ i
, 0xb80, 0x10, &val
);
894 phydev_err(phydev
, "Could not patch PHY\n");
899 /* Use Broadcast ID method for patching */
900 write_phy(mac
, 0xfff, 0x1f, 0x0000);
901 write_phy(mac
, 0xfff, 0x1d, 0x0008);
902 write_phy(mac
, 0xfff, 0x1f, 0x0266);
903 write_phy(mac
, 0xfff, 0x16, 0xff00 + mac
);
904 write_phy(mac
, 0xfff, 0x1f, 0x0000);
905 write_phy(mac
, 0xfff, 0x1d, 0x0000);
909 while (rtl8380_rtl8214fc_perport
[i
* 2]) {
910 write_phy(mac
, 0xfff, rtl8380_rtl8214fc_perport
[i
* 2],
911 rtl8380_rtl8214fc_perport
[i
* 2 + 1]);
915 /*Disable broadcast ID*/
916 write_phy(mac
, 0xfff, 0x1f, 0x0000);
917 write_phy(mac
, 0xfff, 0x1d, 0x0008);
918 write_phy(mac
, 0xfff, 0x1f, 0x0266);
919 write_phy(mac
, 0xfff, 0x16, 0x00 + mac
);
920 write_phy(mac
, 0xfff, 0x1f, 0x0000);
921 write_phy(mac
, 0xfff, 0x1d, 0x0000);
924 /* Auto medium selection */
925 for (i
= 0; i
< 4; i
++) {
926 write_phy(mac
+ i
, 0xfff, 0x1f, 0x0000);
927 write_phy(mac
+ i
, 0xfff, 0x1e, 0x0000);
933 static int rtl8214fc_match_phy_device(struct phy_device
*phydev
)
935 int addr
= phydev
->mdio
.addr
;
937 return phydev
->phy_id
== PHY_ID_RTL8214FC
&& addr
>= 24;
940 static int rtl8380_configure_serdes(struct phy_device
*phydev
)
946 u32
*rtl8380_sds_take_reset
;
947 u32
*rtl8380_sds_common
;
948 u32
*rtl8380_sds01_qsgmii_6275b
;
949 u32
*rtl8380_sds23_qsgmii_6275b
;
950 u32
*rtl8380_sds4_fiber_6275b
;
951 u32
*rtl8380_sds5_fiber_6275b
;
952 u32
*rtl8380_sds_reset
;
953 u32
*rtl8380_sds_release_reset
;
955 phydev_info(phydev
, "Detected internal RTL8380 SERDES\n");
957 h
= rtl838x_request_fw(phydev
, &rtl838x_8218b_fw
, FIRMWARE_838X_8380_1
);
961 if (h
->magic
!= 0x83808380) {
962 phydev_err(phydev
, "Wrong firmware file: magic number mismatch.\n");
966 rtl8380_sds_take_reset
= (void *)h
+ sizeof(struct fw_header
)
969 rtl8380_sds_common
= (void *)h
+ sizeof(struct fw_header
)
972 rtl8380_sds01_qsgmii_6275b
= (void *)h
+ sizeof(struct fw_header
)
975 rtl8380_sds23_qsgmii_6275b
= (void *)h
+ sizeof(struct fw_header
)
978 rtl8380_sds4_fiber_6275b
= (void *)h
+ sizeof(struct fw_header
)
981 rtl8380_sds5_fiber_6275b
= (void *)h
+ sizeof(struct fw_header
)
984 rtl8380_sds_reset
= (void *)h
+ sizeof(struct fw_header
)
987 rtl8380_sds_release_reset
= (void *)h
+ sizeof(struct fw_header
)
990 /* Back up serdes power off value */
991 sds_conf_value
= sw_r32(RTL838X_SDS_CFG_REG
);
992 pr_info("SDS power down value: %x\n", sds_conf_value
);
994 /* take serdes into reset */
996 while (rtl8380_sds_take_reset
[2 * i
]) {
997 sw_w32(rtl8380_sds_take_reset
[2 * i
+ 1], rtl8380_sds_take_reset
[2 * i
]);
1002 /* apply common serdes patch */
1004 while (rtl8380_sds_common
[2 * i
]) {
1005 sw_w32(rtl8380_sds_common
[2 * i
+ 1], rtl8380_sds_common
[2 * i
]);
1010 /* internal R/W enable */
1011 sw_w32(3, RTL838X_INT_RW_CTRL
);
1013 /* SerDes ports 4 and 5 are FIBRE ports */
1014 sw_w32_mask(0x7 | 0x38, 1 | (1 << 3), RTL838X_INT_MODE_CTRL
);
1016 /* SerDes module settings, SerDes 0-3 are QSGMII */
1017 v
= 0x6 << 25 | 0x6 << 20 | 0x6 << 15 | 0x6 << 10;
1018 /* SerDes 4 and 5 are 1000BX FIBRE */
1019 v
|= 0x4 << 5 | 0x4;
1020 sw_w32(v
, RTL838X_SDS_MODE_SEL
);
1022 pr_info("PLL control register: %x\n", sw_r32(RTL838X_PLL_CML_CTRL
));
1023 sw_w32_mask(0xfffffff0, 0xaaaaaaaf & 0xf, RTL838X_PLL_CML_CTRL
);
1025 while (rtl8380_sds01_qsgmii_6275b
[2 * i
]) {
1026 sw_w32(rtl8380_sds01_qsgmii_6275b
[2 * i
+ 1],
1027 rtl8380_sds01_qsgmii_6275b
[2 * i
]);
1032 while (rtl8380_sds23_qsgmii_6275b
[2 * i
]) {
1033 sw_w32(rtl8380_sds23_qsgmii_6275b
[2 * i
+ 1], rtl8380_sds23_qsgmii_6275b
[2 * i
]);
1038 while (rtl8380_sds4_fiber_6275b
[2 * i
]) {
1039 sw_w32(rtl8380_sds4_fiber_6275b
[2 * i
+ 1], rtl8380_sds4_fiber_6275b
[2 * i
]);
1044 while (rtl8380_sds5_fiber_6275b
[2 * i
]) {
1045 sw_w32(rtl8380_sds5_fiber_6275b
[2 * i
+ 1], rtl8380_sds5_fiber_6275b
[2 * i
]);
1050 while (rtl8380_sds_reset
[2 * i
]) {
1051 sw_w32(rtl8380_sds_reset
[2 * i
+ 1], rtl8380_sds_reset
[2 * i
]);
1056 while (rtl8380_sds_release_reset
[2 * i
]) {
1057 sw_w32(rtl8380_sds_release_reset
[2 * i
+ 1], rtl8380_sds_release_reset
[2 * i
]);
1061 pr_info("SDS power down value now: %x\n", sw_r32(RTL838X_SDS_CFG_REG
));
1062 sw_w32(sds_conf_value
, RTL838X_SDS_CFG_REG
);
1064 pr_info("Configuration of SERDES done\n");
1068 static int rtl8214fc_phy_probe(struct phy_device
*phydev
)
1070 struct device
*dev
= &phydev
->mdio
.dev
;
1071 struct rtl838x_phy_priv
*priv
;
1072 int addr
= phydev
->mdio
.addr
;
1074 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1078 priv
->name
= "RTL8214FC";
1080 /* All base addresses of the PHYs start at multiples of 8 */
1082 /* Configuration must be done whil patching still possible */
1083 return rtl8380_configure_rtl8214fc(phydev
);
1088 static int rtl8214c_phy_probe(struct phy_device
*phydev
)
1090 struct device
*dev
= &phydev
->mdio
.dev
;
1091 struct rtl838x_phy_priv
*priv
;
1092 int addr
= phydev
->mdio
.addr
;
1094 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1098 priv
->name
= "RTL8214C";
1100 /* All base addresses of the PHYs start at multiples of 8 */
1102 /* Configuration must be done whil patching still possible */
1103 return rtl8380_configure_rtl8214c(phydev
);
1108 static int rtl8218b_ext_phy_probe(struct phy_device
*phydev
)
1110 struct device
*dev
= &phydev
->mdio
.dev
;
1111 struct rtl838x_phy_priv
*priv
;
1112 int addr
= phydev
->mdio
.addr
;
1114 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1118 priv
->name
= "RTL8218B (external)";
1120 /* All base addresses of the PHYs start at multiples of 8 */
1122 /* Configuration must be done while patching still possible */
1123 return rtl8380_configure_ext_rtl8218b(phydev
);
1128 static int rtl8218b_int_phy_probe(struct phy_device
*phydev
)
1130 struct device
*dev
= &phydev
->mdio
.dev
;
1131 struct rtl838x_phy_priv
*priv
;
1132 int addr
= phydev
->mdio
.addr
;
1134 if (soc_info
.family
!= RTL8380_FAMILY_ID
)
1139 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1143 priv
->name
= "RTL8218B (internal)";
1145 /* All base addresses of the PHYs start at multiples of 8 */
1147 /* Configuration must be done while patching still possible */
1148 return rtl8380_configure_int_rtl8218b(phydev
);
1153 static int rtl838x_serdes_probe(struct phy_device
*phydev
)
1155 struct device
*dev
= &phydev
->mdio
.dev
;
1156 struct rtl838x_phy_priv
*priv
;
1157 int addr
= phydev
->mdio
.addr
;
1159 if (soc_info
.family
!= RTL8380_FAMILY_ID
)
1164 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1168 priv
->name
= "RTL8380 Serdes";
1170 /* On the RTL8380M, PHYs 24-27 connect to the internal SerDes */
1171 if (soc_info
.id
== 0x8380) {
1173 return rtl8380_configure_serdes(phydev
);
1179 static int rtl8390_serdes_probe(struct phy_device
*phydev
)
1181 struct device
*dev
= &phydev
->mdio
.dev
;
1182 struct rtl838x_phy_priv
*priv
;
1183 int addr
= phydev
->mdio
.addr
;
1185 if (soc_info
.family
!= RTL8390_FAMILY_ID
)
1191 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1195 priv
->name
= "RTL8390 Serdes";
1196 return rtl8390_configure_generic(phydev
);
1199 static struct phy_driver rtl838x_phy_driver
[] = {
1201 PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC
),
1202 .name
= "REATLTEK RTL8214C",
1203 .features
= PHY_GBIT_FEATURES
,
1204 .match_phy_device
= rtl8214c_match_phy_device
,
1205 .probe
= rtl8214c_phy_probe
,
1206 .suspend
= genphy_suspend
,
1207 .resume
= genphy_resume
,
1208 .set_loopback
= genphy_loopback
,
1211 PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC
),
1212 .name
= "REATLTEK RTL8214FC",
1213 .features
= PHY_GBIT_FIBRE_FEATURES
,
1214 .match_phy_device
= rtl8214fc_match_phy_device
,
1215 .probe
= rtl8214fc_phy_probe
,
1216 .suspend
= genphy_suspend
,
1217 .resume
= genphy_resume
,
1218 .set_loopback
= genphy_loopback
,
1219 .read_mmd
= rtl8380_rtl8218b_read_mmd
,
1220 .write_mmd
= rtl8380_rtl8218b_write_mmd
,
1221 .set_port
= rtl8380_rtl8214fc_set_port
,
1222 .get_port
= rtl8380_rtl8214fc_get_port
,
1223 .set_eee
= rtl8380_rtl8214fc_set_eee
,
1224 .get_eee
= rtl8380_rtl8214fc_get_eee
,
1227 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_E
),
1228 .name
= "REATLTEK RTL8218B (external)",
1229 .features
= PHY_GBIT_FEATURES
,
1230 .match_phy_device
= rtl8218b_ext_match_phy_device
,
1231 .probe
= rtl8218b_ext_phy_probe
,
1232 .suspend
= genphy_suspend
,
1233 .resume
= genphy_resume
,
1234 .set_loopback
= genphy_loopback
,
1235 .read_mmd
= rtl8380_rtl8218b_read_mmd
,
1236 .write_mmd
= rtl8380_rtl8218b_write_mmd
,
1237 .set_eee
= rtl8380_rtl8218b_set_eee
,
1238 .get_eee
= rtl8380_rtl8218b_get_eee_u_boot
,
1241 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I
),
1242 .name
= "REATLTEK RTL8218B (internal)",
1243 .features
= PHY_GBIT_FEATURES
,
1244 .probe
= rtl8218b_int_phy_probe
,
1245 .suspend
= genphy_suspend
,
1246 .resume
= genphy_resume
,
1247 .set_loopback
= genphy_loopback
,
1248 .read_mmd
= rtl8380_rtl8218b_read_mmd
,
1249 .write_mmd
= rtl8380_rtl8218b_write_mmd
,
1250 .set_eee
= rtl8380_rtl8218b_set_eee
,
1251 .get_eee
= rtl8380_rtl8218b_get_eee_u_boot
,
1254 PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I
),
1255 .name
= "REATLTEK RTL8380 SERDES",
1256 .features
= PHY_GBIT_FIBRE_FEATURES
,
1257 .probe
= rtl838x_serdes_probe
,
1258 .suspend
= genphy_suspend
,
1259 .resume
= genphy_resume
,
1260 .set_loopback
= genphy_loopback
,
1261 .read_mmd
= rtl8380_rtl8218b_read_mmd
,
1262 .write_mmd
= rtl8380_rtl8218b_write_mmd
,
1265 PHY_ID_MATCH_MODEL(PHY_ID_RTL8390_GENERIC
),
1266 .name
= "REATLTEK RTL8390 Generic",
1267 .features
= PHY_GBIT_FIBRE_FEATURES
,
1268 .probe
= rtl8390_serdes_probe
,
1269 .suspend
= genphy_suspend
,
1270 .resume
= genphy_resume
,
1271 .set_loopback
= genphy_loopback
,
1275 module_phy_driver(rtl838x_phy_driver
);
1277 static struct mdio_device_id __maybe_unused rtl838x_tbl
[] = {
1278 { PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC
) },
1282 MODULE_DEVICE_TABLE(mdio
, rtl838x_tbl
);
1284 MODULE_AUTHOR("B. Koblitz");
1285 MODULE_DESCRIPTION("RTL838x PHY driver");
1286 MODULE_LICENSE("GPL");