1 /* 2 * ET1011C PHY driver 3 * 4 * Derived from Linux kernel driver by Chaithrika U S 5 * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 #include <config.h> 10 #include <phy.h> 11 12 #define ET1011C_CONFIG_REG (0x16) 13 #define ET1011C_TX_FIFO_MASK (0x3 << 12) 14 #define ET1011C_TX_FIFO_DEPTH_8 (0x0 << 12) 15 #define ET1011C_TX_FIFO_DEPTH_16 (0x1 << 12) 16 #define ET1011C_INTERFACE_MASK (0x7 << 0) 17 #define ET1011C_GMII_INTERFACE (0x2 << 0) 18 #define ET1011C_SYS_CLK_EN (0x1 << 4) 19 #define ET1011C_TX_CLK_EN (0x1 << 5) 20 21 #define ET1011C_STATUS_REG (0x1A) 22 #define ET1011C_DUPLEX_STATUS (0x1 << 7) 23 #define ET1011C_SPEED_MASK (0x3 << 8) 24 #define ET1011C_SPEED_1000 (0x2 << 8) 25 #define ET1011C_SPEED_100 (0x1 << 8) 26 #define ET1011C_SPEED_10 (0x0 << 8) 27 28 static int et1011c_config(struct phy_device *phydev) 29 { 30 int ctl = 0; 31 ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); 32 if (ctl < 0) 33 return ctl; 34 ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | 35 BMCR_ANENABLE); 36 /* First clear the PHY */ 37 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl | BMCR_RESET); 38 39 return genphy_config_aneg(phydev); 40 } 41 42 static int et1011c_parse_status(struct phy_device *phydev) 43 { 44 int mii_reg; 45 int speed; 46 47 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, ET1011C_STATUS_REG); 48 49 if (mii_reg & ET1011C_DUPLEX_STATUS) 50 phydev->duplex = DUPLEX_FULL; 51 else 52 phydev->duplex = DUPLEX_HALF; 53 54 speed = mii_reg & ET1011C_SPEED_MASK; 55 switch (speed) { 56 case ET1011C_SPEED_1000: 57 phydev->speed = SPEED_1000; 58 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, ET1011C_CONFIG_REG); 59 mii_reg &= ~ET1011C_TX_FIFO_MASK; 60 phy_write(phydev, MDIO_DEVAD_NONE, ET1011C_CONFIG_REG, 61 mii_reg | 62 ET1011C_GMII_INTERFACE | 63 ET1011C_SYS_CLK_EN | 64 #ifdef CONFIG_PHY_ET1011C_TX_CLK_FIX 65 ET1011C_TX_CLK_EN | 66 #endif 67 ET1011C_TX_FIFO_DEPTH_16); 68 break; 69 case ET1011C_SPEED_100: 70 phydev->speed = SPEED_100; 71 break; 72 case ET1011C_SPEED_10: 73 phydev->speed = SPEED_10; 74 break; 75 } 76 77 return 0; 78 } 79 80 static int et1011c_startup(struct phy_device *phydev) 81 { 82 int ret; 83 84 ret = genphy_update_link(phydev); 85 if (ret) 86 return ret; 87 88 return et1011c_parse_status(phydev); 89 } 90 91 static struct phy_driver et1011c_driver = { 92 .name = "ET1011C", 93 .uid = 0x0282f014, 94 .mask = 0xfffffff0, 95 .features = PHY_GBIT_FEATURES, 96 .config = &et1011c_config, 97 .startup = &et1011c_startup, 98 }; 99 100 int phy_et1011c_init(void) 101 { 102 phy_register(&et1011c_driver); 103 104 return 0; 105 } 106