xref: /rk3399_rockchip-uboot/drivers/net/phy/natsemi.c (revision dc557e9a1fe00ca9d884bd88feef5bebf23fede4)
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 
dp83630_config(struct phy_device * phydev)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 */
dp838xx_config(struct phy_device * phydev)565ea667eaSVincent 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 
dp83865_parse_status(struct phy_device * phydev)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 
dp83865_startup(struct phy_device * phydev)949082eeacSAndy Fleming static int dp83865_startup(struct phy_device *phydev)
959082eeacSAndy Fleming {
96*b733c278SMichal Simek 	int ret;
979082eeacSAndy Fleming 
98*b733c278SMichal Simek 	ret = genphy_update_link(phydev);
99*b733c278SMichal Simek 	if (ret)
100*b733c278SMichal Simek 		return ret;
101*b733c278SMichal Simek 
102*b733c278SMichal Simek 	return dp83865_parse_status(phydev);
1039082eeacSAndy Fleming }
1049082eeacSAndy Fleming 
1059082eeacSAndy Fleming 
1069082eeacSAndy Fleming static struct phy_driver DP83865_driver = {
1079082eeacSAndy Fleming 	.name = "NatSemi DP83865",
1089082eeacSAndy Fleming 	.uid = 0x20005c70,
1099082eeacSAndy Fleming 	.mask = 0xfffffff0,
1109082eeacSAndy Fleming 	.features = PHY_GBIT_FEATURES,
1115ea667eaSVincent BENOIT 	.config = &dp838xx_config,
1129082eeacSAndy Fleming 	.startup = &dp83865_startup,
1139082eeacSAndy Fleming 	.shutdown = &genphy_shutdown,
1149082eeacSAndy Fleming };
1159082eeacSAndy Fleming 
1165ea667eaSVincent BENOIT /* NatSemi DP83848 */
dp83848_parse_status(struct phy_device * phydev)1175ea667eaSVincent BENOIT static int dp83848_parse_status(struct phy_device *phydev)
1185ea667eaSVincent BENOIT {
1195ea667eaSVincent BENOIT 	int mii_reg;
1205ea667eaSVincent BENOIT 
1215ea667eaSVincent BENOIT 	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
1225ea667eaSVincent BENOIT 
1235ea667eaSVincent BENOIT 	if(mii_reg & (BMSR_100FULL | BMSR_100HALF)) {
1245ea667eaSVincent BENOIT 		phydev->speed = SPEED_100;
1255ea667eaSVincent BENOIT 	} else {
1265ea667eaSVincent BENOIT 		phydev->speed = SPEED_10;
1275ea667eaSVincent BENOIT 	}
1285ea667eaSVincent BENOIT 
1295ea667eaSVincent BENOIT 	if (mii_reg & (BMSR_10FULL | BMSR_100FULL)) {
1305ea667eaSVincent BENOIT 		phydev->duplex = DUPLEX_FULL;
1315ea667eaSVincent BENOIT 	} else {
1325ea667eaSVincent BENOIT 		phydev->duplex = DUPLEX_HALF;
1335ea667eaSVincent BENOIT 	}
1345ea667eaSVincent BENOIT 
1355ea667eaSVincent BENOIT 	return 0;
1365ea667eaSVincent BENOIT }
1375ea667eaSVincent BENOIT 
dp83848_startup(struct phy_device * phydev)1385ea667eaSVincent BENOIT static int dp83848_startup(struct phy_device *phydev)
1395ea667eaSVincent BENOIT {
140*b733c278SMichal Simek 	int ret;
1415ea667eaSVincent BENOIT 
142*b733c278SMichal Simek 	ret = genphy_update_link(phydev);
143*b733c278SMichal Simek 	if (ret)
144*b733c278SMichal Simek 		return ret;
145*b733c278SMichal Simek 
146*b733c278SMichal Simek 	return dp83848_parse_status(phydev);
1475ea667eaSVincent BENOIT }
1485ea667eaSVincent BENOIT 
1495ea667eaSVincent BENOIT static struct phy_driver DP83848_driver = {
1505ea667eaSVincent BENOIT 	.name = "NatSemi DP83848",
1515ea667eaSVincent BENOIT 	.uid = 0x20005c90,
1525ea667eaSVincent BENOIT 	.mask = 0x2000ff90,
1535ea667eaSVincent BENOIT 	.features = PHY_BASIC_FEATURES,
1545ea667eaSVincent BENOIT 	.config = &dp838xx_config,
1555ea667eaSVincent BENOIT 	.startup = &dp83848_startup,
1565ea667eaSVincent BENOIT 	.shutdown = &genphy_shutdown,
1575ea667eaSVincent BENOIT };
1585ea667eaSVincent BENOIT 
phy_natsemi_init(void)1599082eeacSAndy Fleming int phy_natsemi_init(void)
1609082eeacSAndy Fleming {
16196d0b9e1SHeiko Schocher 	phy_register(&DP83630_driver);
1629082eeacSAndy Fleming 	phy_register(&DP83865_driver);
1635ea667eaSVincent BENOIT 	phy_register(&DP83848_driver);
1649082eeacSAndy Fleming 
1659082eeacSAndy Fleming 	return 0;
1669082eeacSAndy Fleming }
167