xref: /rk3399_rockchip-uboot/drivers/net/phy/natsemi.c (revision 5ea667ea2fcc662df11dc16f2fe492a424ff8759)
19082eeacSAndy Fleming /*
29082eeacSAndy Fleming  * National Semiconductor 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 <phy.h>
109082eeacSAndy Fleming 
1196d0b9e1SHeiko Schocher /* NatSemi DP83630 */
1296d0b9e1SHeiko Schocher 
1396d0b9e1SHeiko Schocher #define DP83630_PHY_PAGESEL_REG		0x13
1496d0b9e1SHeiko Schocher #define DP83630_PHY_PTP_COC_REG		0x14
1596d0b9e1SHeiko Schocher #define DP83630_PHY_PTP_CLKOUT_EN	(1<<15)
1696d0b9e1SHeiko Schocher #define DP83630_PHY_RBR_REG		0x17
1796d0b9e1SHeiko Schocher 
1896d0b9e1SHeiko Schocher static int dp83630_config(struct phy_device *phydev)
1996d0b9e1SHeiko Schocher {
2096d0b9e1SHeiko Schocher 	int ptp_coc_reg;
2196d0b9e1SHeiko Schocher 
2296d0b9e1SHeiko Schocher 	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
2396d0b9e1SHeiko Schocher 	phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PAGESEL_REG, 0x6);
2496d0b9e1SHeiko Schocher 	ptp_coc_reg = phy_read(phydev, MDIO_DEVAD_NONE,
2596d0b9e1SHeiko Schocher 			       DP83630_PHY_PTP_COC_REG);
2696d0b9e1SHeiko Schocher 	ptp_coc_reg &= ~DP83630_PHY_PTP_CLKOUT_EN;
2796d0b9e1SHeiko Schocher 	phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PTP_COC_REG,
2896d0b9e1SHeiko Schocher 		  ptp_coc_reg);
2996d0b9e1SHeiko Schocher 	phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PAGESEL_REG, 0);
3096d0b9e1SHeiko Schocher 
3196d0b9e1SHeiko Schocher 	genphy_config_aneg(phydev);
3296d0b9e1SHeiko Schocher 
3396d0b9e1SHeiko Schocher 	return 0;
3496d0b9e1SHeiko Schocher }
3596d0b9e1SHeiko Schocher 
3696d0b9e1SHeiko Schocher static struct phy_driver DP83630_driver = {
3796d0b9e1SHeiko Schocher 	.name = "NatSemi DP83630",
3896d0b9e1SHeiko Schocher 	.uid = 0x20005ce1,
3996d0b9e1SHeiko Schocher 	.mask = 0xfffffff0,
4096d0b9e1SHeiko Schocher 	.features = PHY_BASIC_FEATURES,
4196d0b9e1SHeiko Schocher 	.config = &dp83630_config,
4296d0b9e1SHeiko Schocher 	.startup = &genphy_startup,
4396d0b9e1SHeiko Schocher 	.shutdown = &genphy_shutdown,
4496d0b9e1SHeiko Schocher };
4596d0b9e1SHeiko Schocher 
4696d0b9e1SHeiko Schocher 
479082eeacSAndy Fleming /* DP83865 Link and Auto-Neg Status Register */
489082eeacSAndy Fleming #define MIIM_DP83865_LANR      0x11
499082eeacSAndy Fleming #define MIIM_DP83865_SPD_MASK  0x0018
509082eeacSAndy Fleming #define MIIM_DP83865_SPD_1000  0x0010
519082eeacSAndy Fleming #define MIIM_DP83865_SPD_100   0x0008
529082eeacSAndy Fleming #define MIIM_DP83865_DPX_FULL  0x0002
539082eeacSAndy Fleming 
549082eeacSAndy Fleming 
559082eeacSAndy Fleming /* NatSemi DP83865 */
56*5ea667eaSVincent BENOIT static int dp838xx_config(struct phy_device *phydev)
579082eeacSAndy Fleming {
589082eeacSAndy Fleming 	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
599082eeacSAndy Fleming 	genphy_config_aneg(phydev);
609082eeacSAndy Fleming 
619082eeacSAndy Fleming 	return 0;
629082eeacSAndy Fleming }
639082eeacSAndy Fleming 
649082eeacSAndy Fleming static int dp83865_parse_status(struct phy_device *phydev)
659082eeacSAndy Fleming {
669082eeacSAndy Fleming 	int mii_reg;
679082eeacSAndy Fleming 
689082eeacSAndy Fleming 	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_DP83865_LANR);
699082eeacSAndy Fleming 
709082eeacSAndy Fleming 	switch (mii_reg & MIIM_DP83865_SPD_MASK) {
719082eeacSAndy Fleming 
729082eeacSAndy Fleming 	case MIIM_DP83865_SPD_1000:
739082eeacSAndy Fleming 		phydev->speed = SPEED_1000;
749082eeacSAndy Fleming 		break;
759082eeacSAndy Fleming 
769082eeacSAndy Fleming 	case MIIM_DP83865_SPD_100:
779082eeacSAndy Fleming 		phydev->speed = SPEED_100;
789082eeacSAndy Fleming 		break;
799082eeacSAndy Fleming 
809082eeacSAndy Fleming 	default:
819082eeacSAndy Fleming 		phydev->speed = SPEED_10;
829082eeacSAndy Fleming 		break;
839082eeacSAndy Fleming 
849082eeacSAndy Fleming 	}
859082eeacSAndy Fleming 
869082eeacSAndy Fleming 	if (mii_reg & MIIM_DP83865_DPX_FULL)
879082eeacSAndy Fleming 		phydev->duplex = DUPLEX_FULL;
889082eeacSAndy Fleming 	else
899082eeacSAndy Fleming 		phydev->duplex = DUPLEX_HALF;
909082eeacSAndy Fleming 
919082eeacSAndy Fleming 	return 0;
929082eeacSAndy Fleming }
939082eeacSAndy Fleming 
949082eeacSAndy Fleming static int dp83865_startup(struct phy_device *phydev)
959082eeacSAndy Fleming {
969082eeacSAndy Fleming 	genphy_update_link(phydev);
979082eeacSAndy Fleming 	dp83865_parse_status(phydev);
989082eeacSAndy Fleming 
999082eeacSAndy Fleming 	return 0;
1009082eeacSAndy Fleming }
1019082eeacSAndy Fleming 
1029082eeacSAndy Fleming 
1039082eeacSAndy Fleming static struct phy_driver DP83865_driver = {
1049082eeacSAndy Fleming 	.name = "NatSemi DP83865",
1059082eeacSAndy Fleming 	.uid = 0x20005c70,
1069082eeacSAndy Fleming 	.mask = 0xfffffff0,
1079082eeacSAndy Fleming 	.features = PHY_GBIT_FEATURES,
108*5ea667eaSVincent BENOIT 	.config = &dp838xx_config,
1099082eeacSAndy Fleming 	.startup = &dp83865_startup,
1109082eeacSAndy Fleming 	.shutdown = &genphy_shutdown,
1119082eeacSAndy Fleming };
1129082eeacSAndy Fleming 
113*5ea667eaSVincent BENOIT /* NatSemi DP83848 */
114*5ea667eaSVincent BENOIT static int dp83848_parse_status(struct phy_device *phydev)
115*5ea667eaSVincent BENOIT {
116*5ea667eaSVincent BENOIT 	int mii_reg;
117*5ea667eaSVincent BENOIT 
118*5ea667eaSVincent BENOIT 	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
119*5ea667eaSVincent BENOIT 
120*5ea667eaSVincent BENOIT 	if(mii_reg & (BMSR_100FULL | BMSR_100HALF)) {
121*5ea667eaSVincent BENOIT 		phydev->speed = SPEED_100;
122*5ea667eaSVincent BENOIT 	} else {
123*5ea667eaSVincent BENOIT 		phydev->speed = SPEED_10;
124*5ea667eaSVincent BENOIT 	}
125*5ea667eaSVincent BENOIT 
126*5ea667eaSVincent BENOIT 	if (mii_reg & (BMSR_10FULL | BMSR_100FULL)) {
127*5ea667eaSVincent BENOIT 		phydev->duplex = DUPLEX_FULL;
128*5ea667eaSVincent BENOIT 	} else {
129*5ea667eaSVincent BENOIT 		phydev->duplex = DUPLEX_HALF;
130*5ea667eaSVincent BENOIT 	}
131*5ea667eaSVincent BENOIT 
132*5ea667eaSVincent BENOIT 	return 0;
133*5ea667eaSVincent BENOIT }
134*5ea667eaSVincent BENOIT 
135*5ea667eaSVincent BENOIT static int dp83848_startup(struct phy_device *phydev)
136*5ea667eaSVincent BENOIT {
137*5ea667eaSVincent BENOIT 	genphy_update_link(phydev);
138*5ea667eaSVincent BENOIT 	dp83848_parse_status(phydev);
139*5ea667eaSVincent BENOIT 
140*5ea667eaSVincent BENOIT 	return 0;
141*5ea667eaSVincent BENOIT }
142*5ea667eaSVincent BENOIT 
143*5ea667eaSVincent BENOIT static struct phy_driver DP83848_driver = {
144*5ea667eaSVincent BENOIT 	.name = "NatSemi DP83848",
145*5ea667eaSVincent BENOIT 	.uid = 0x20005c90,
146*5ea667eaSVincent BENOIT 	.mask = 0x2000ff90,
147*5ea667eaSVincent BENOIT 	.features = PHY_BASIC_FEATURES,
148*5ea667eaSVincent BENOIT 	.config = &dp838xx_config,
149*5ea667eaSVincent BENOIT 	.startup = &dp83848_startup,
150*5ea667eaSVincent BENOIT 	.shutdown = &genphy_shutdown,
151*5ea667eaSVincent BENOIT };
152*5ea667eaSVincent BENOIT 
1539082eeacSAndy Fleming int phy_natsemi_init(void)
1549082eeacSAndy Fleming {
15596d0b9e1SHeiko Schocher 	phy_register(&DP83630_driver);
1569082eeacSAndy Fleming 	phy_register(&DP83865_driver);
157*5ea667eaSVincent BENOIT 	phy_register(&DP83848_driver);
1589082eeacSAndy Fleming 
1599082eeacSAndy Fleming 	return 0;
1609082eeacSAndy Fleming }
161