xref: /rk3399_rockchip-uboot/drivers/net/phy/realtek.c (revision c624d168bf87e5558a58e99c58b162f5e5b6368e)
19082eeacSAndy Fleming /*
29082eeacSAndy Fleming  * RealTek PHY drivers
39082eeacSAndy Fleming  *
41a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
59082eeacSAndy Fleming  *
69082eeacSAndy Fleming  * Copyright 2010-2011 Freescale Semiconductor, Inc.
79082eeacSAndy Fleming  * author Andy Fleming
89082eeacSAndy Fleming  */
99082eeacSAndy Fleming #include <config.h>
109082eeacSAndy Fleming #include <common.h>
119082eeacSAndy Fleming #include <phy.h>
129082eeacSAndy Fleming 
139082eeacSAndy Fleming #define PHY_AUTONEGOTIATE_TIMEOUT 5000
149082eeacSAndy Fleming 
15*c624d168SBhupesh Sharma /* RTL8211x PHY Status Register */
16*c624d168SBhupesh Sharma #define MIIM_RTL8211x_PHY_STATUS       0x11
17*c624d168SBhupesh Sharma #define MIIM_RTL8211x_PHYSTAT_SPEED    0xc000
18*c624d168SBhupesh Sharma #define MIIM_RTL8211x_PHYSTAT_GBIT     0x8000
19*c624d168SBhupesh Sharma #define MIIM_RTL8211x_PHYSTAT_100      0x4000
20*c624d168SBhupesh Sharma #define MIIM_RTL8211x_PHYSTAT_DUPLEX   0x2000
21*c624d168SBhupesh Sharma #define MIIM_RTL8211x_PHYSTAT_SPDDONE  0x0800
22*c624d168SBhupesh Sharma #define MIIM_RTL8211x_PHYSTAT_LINK     0x0400
239082eeacSAndy Fleming 
249082eeacSAndy Fleming 
25*c624d168SBhupesh Sharma /* RealTek RTL8211x */
26*c624d168SBhupesh Sharma static int rtl8211x_config(struct phy_device *phydev)
279082eeacSAndy Fleming {
289082eeacSAndy Fleming 	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
299082eeacSAndy Fleming 
309082eeacSAndy Fleming 	genphy_config_aneg(phydev);
319082eeacSAndy Fleming 
329082eeacSAndy Fleming 	return 0;
339082eeacSAndy Fleming }
349082eeacSAndy Fleming 
35*c624d168SBhupesh Sharma static int rtl8211x_parse_status(struct phy_device *phydev)
369082eeacSAndy Fleming {
379082eeacSAndy Fleming 	unsigned int speed;
389082eeacSAndy Fleming 	unsigned int mii_reg;
399082eeacSAndy Fleming 
40*c624d168SBhupesh Sharma 	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS);
419082eeacSAndy Fleming 
42*c624d168SBhupesh Sharma 	if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
439082eeacSAndy Fleming 		int i = 0;
449082eeacSAndy Fleming 
459082eeacSAndy Fleming 		/* in case of timeout ->link is cleared */
469082eeacSAndy Fleming 		phydev->link = 1;
479082eeacSAndy Fleming 		puts("Waiting for PHY realtime link");
48*c624d168SBhupesh Sharma 		while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
499082eeacSAndy Fleming 			/* Timeout reached ? */
509082eeacSAndy Fleming 			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
519082eeacSAndy Fleming 				puts(" TIMEOUT !\n");
529082eeacSAndy Fleming 				phydev->link = 0;
539082eeacSAndy Fleming 				break;
549082eeacSAndy Fleming 			}
559082eeacSAndy Fleming 
569082eeacSAndy Fleming 			if ((i++ % 1000) == 0)
579082eeacSAndy Fleming 				putc('.');
589082eeacSAndy Fleming 			udelay(1000);	/* 1 ms */
599082eeacSAndy Fleming 			mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
60*c624d168SBhupesh Sharma 					MIIM_RTL8211x_PHY_STATUS);
619082eeacSAndy Fleming 		}
629082eeacSAndy Fleming 		puts(" done\n");
639082eeacSAndy Fleming 		udelay(500000);	/* another 500 ms (results in faster booting) */
649082eeacSAndy Fleming 	} else {
65*c624d168SBhupesh Sharma 		if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK)
669082eeacSAndy Fleming 			phydev->link = 1;
679082eeacSAndy Fleming 		else
689082eeacSAndy Fleming 			phydev->link = 0;
699082eeacSAndy Fleming 	}
709082eeacSAndy Fleming 
71*c624d168SBhupesh Sharma 	if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX)
729082eeacSAndy Fleming 		phydev->duplex = DUPLEX_FULL;
739082eeacSAndy Fleming 	else
749082eeacSAndy Fleming 		phydev->duplex = DUPLEX_HALF;
759082eeacSAndy Fleming 
76*c624d168SBhupesh Sharma 	speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED);
779082eeacSAndy Fleming 
789082eeacSAndy Fleming 	switch (speed) {
79*c624d168SBhupesh Sharma 	case MIIM_RTL8211x_PHYSTAT_GBIT:
809082eeacSAndy Fleming 		phydev->speed = SPEED_1000;
819082eeacSAndy Fleming 		break;
82*c624d168SBhupesh Sharma 	case MIIM_RTL8211x_PHYSTAT_100:
839082eeacSAndy Fleming 		phydev->speed = SPEED_100;
849082eeacSAndy Fleming 		break;
859082eeacSAndy Fleming 	default:
869082eeacSAndy Fleming 		phydev->speed = SPEED_10;
879082eeacSAndy Fleming 	}
889082eeacSAndy Fleming 
899082eeacSAndy Fleming 	return 0;
909082eeacSAndy Fleming }
919082eeacSAndy Fleming 
92*c624d168SBhupesh Sharma static int rtl8211x_startup(struct phy_device *phydev)
939082eeacSAndy Fleming {
949082eeacSAndy Fleming 	/* Read the Status (2x to make sure link is right) */
959082eeacSAndy Fleming 	genphy_update_link(phydev);
96*c624d168SBhupesh Sharma 	rtl8211x_parse_status(phydev);
979082eeacSAndy Fleming 
989082eeacSAndy Fleming 	return 0;
999082eeacSAndy Fleming }
1009082eeacSAndy Fleming 
101*c624d168SBhupesh Sharma /* Support for RTL8211B PHY */
1029082eeacSAndy Fleming static struct phy_driver RTL8211B_driver = {
1039082eeacSAndy Fleming 	.name = "RealTek RTL8211B",
1049082eeacSAndy Fleming 	.uid = 0x1cc910,
1059082eeacSAndy Fleming 	.mask = 0xfffff0,
1069082eeacSAndy Fleming 	.features = PHY_GBIT_FEATURES,
107*c624d168SBhupesh Sharma 	.config = &rtl8211x_config,
108*c624d168SBhupesh Sharma 	.startup = &rtl8211x_startup,
109*c624d168SBhupesh Sharma 	.shutdown = &genphy_shutdown,
110*c624d168SBhupesh Sharma };
111*c624d168SBhupesh Sharma 
112*c624d168SBhupesh Sharma /* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */
113*c624d168SBhupesh Sharma static struct phy_driver RTL8211E_driver = {
114*c624d168SBhupesh Sharma 	.name = "RealTek RTL8211E",
115*c624d168SBhupesh Sharma 	.uid = 0x1cc915,
116*c624d168SBhupesh Sharma 	.mask = 0xfffff0,
117*c624d168SBhupesh Sharma 	.features = PHY_GBIT_FEATURES,
118*c624d168SBhupesh Sharma 	.config = &rtl8211x_config,
119*c624d168SBhupesh Sharma 	.startup = &rtl8211x_startup,
120*c624d168SBhupesh Sharma 	.shutdown = &genphy_shutdown,
121*c624d168SBhupesh Sharma };
122*c624d168SBhupesh Sharma 
123*c624d168SBhupesh Sharma /* Support for RTL8211DN PHY */
124*c624d168SBhupesh Sharma static struct phy_driver RTL8211DN_driver = {
125*c624d168SBhupesh Sharma 	.name = "RealTek RTL8211DN",
126*c624d168SBhupesh Sharma 	.uid = 0x1cc914,
127*c624d168SBhupesh Sharma 	.mask = 0xfffff0,
128*c624d168SBhupesh Sharma 	.features = PHY_GBIT_FEATURES,
129*c624d168SBhupesh Sharma 	.config = &rtl8211x_config,
130*c624d168SBhupesh Sharma 	.startup = &rtl8211x_startup,
1319082eeacSAndy Fleming 	.shutdown = &genphy_shutdown,
1329082eeacSAndy Fleming };
1339082eeacSAndy Fleming 
1349082eeacSAndy Fleming int phy_realtek_init(void)
1359082eeacSAndy Fleming {
1369082eeacSAndy Fleming 	phy_register(&RTL8211B_driver);
137*c624d168SBhupesh Sharma 	phy_register(&RTL8211E_driver);
138*c624d168SBhupesh Sharma 	phy_register(&RTL8211DN_driver);
1399082eeacSAndy Fleming 
1409082eeacSAndy Fleming 	return 0;
1419082eeacSAndy Fleming }
142