1 /* 2 * TI PHY drivers 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 * 6 */ 7 #include <common.h> 8 #include <phy.h> 9 10 /* TI DP83867 */ 11 #define DP83867_DEVADDR 0x1f 12 13 #define MII_DP83867_PHYCTRL 0x10 14 #define MII_DP83867_MICR 0x12 15 #define MII_DP83867_CFG2 0x14 16 #define MII_DP83867_BISCR 0x16 17 #define DP83867_CTRL 0x1f 18 19 /* Extended Registers */ 20 #define DP83867_RGMIICTL 0x0032 21 #define DP83867_RGMIIDCTL 0x0086 22 23 #define DP83867_SW_RESET BIT(15) 24 #define DP83867_SW_RESTART BIT(14) 25 26 /* MICR Interrupt bits */ 27 #define MII_DP83867_MICR_AN_ERR_INT_EN BIT(15) 28 #define MII_DP83867_MICR_SPEED_CHNG_INT_EN BIT(14) 29 #define MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN BIT(13) 30 #define MII_DP83867_MICR_PAGE_RXD_INT_EN BIT(12) 31 #define MII_DP83867_MICR_AUTONEG_COMP_INT_EN BIT(11) 32 #define MII_DP83867_MICR_LINK_STS_CHNG_INT_EN BIT(10) 33 #define MII_DP83867_MICR_FALSE_CARRIER_INT_EN BIT(8) 34 #define MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4) 35 #define MII_DP83867_MICR_WOL_INT_EN BIT(3) 36 #define MII_DP83867_MICR_XGMII_ERR_INT_EN BIT(2) 37 #define MII_DP83867_MICR_POL_CHNG_INT_EN BIT(1) 38 #define MII_DP83867_MICR_JABBER_INT_EN BIT(0) 39 40 /* RGMIICTL bits */ 41 #define DP83867_RGMII_TX_CLK_DELAY_EN BIT(1) 42 #define DP83867_RGMII_RX_CLK_DELAY_EN BIT(0) 43 44 /* PHY CTRL bits */ 45 #define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14 46 #define DP83867_MDI_CROSSOVER 5 47 #define DP83867_MDI_CROSSOVER_AUTO 2 48 #define DP83867_MDI_CROSSOVER_MDIX 2 49 #define DP83867_PHYCTRL_SGMIIEN 0x0800 50 #define DP83867_PHYCTRL_RXFIFO_SHIFT 12 51 #define DP83867_PHYCTRL_TXFIFO_SHIFT 14 52 53 /* RGMIIDCTL bits */ 54 #define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4 55 56 /* CFG2 bits */ 57 #define MII_DP83867_CFG2_SPEEDOPT_10EN 0x0040 58 #define MII_DP83867_CFG2_SGMII_AUTONEGEN 0x0080 59 #define MII_DP83867_CFG2_SPEEDOPT_ENH 0x0100 60 #define MII_DP83867_CFG2_SPEEDOPT_CNT 0x0800 61 #define MII_DP83867_CFG2_SPEEDOPT_INTLOW 0x2000 62 #define MII_DP83867_CFG2_MASK 0x003F 63 64 #define MII_MMD_CTRL 0x0d /* MMD Access Control Register */ 65 #define MII_MMD_DATA 0x0e /* MMD Access Data Register */ 66 67 /* MMD Access Control register fields */ 68 #define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/ 69 #define MII_MMD_CTRL_ADDR 0x0000 /* Address */ 70 #define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */ 71 #define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */ 72 #define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */ 73 74 /** 75 * phy_read_mmd_indirect - reads data from the MMD registers 76 * @phydev: The PHY device bus 77 * @prtad: MMD Address 78 * @devad: MMD DEVAD 79 * @addr: PHY address on the MII bus 80 * 81 * Description: it reads data from the MMD registers (clause 22 to access to 82 * clause 45) of the specified phy address. 83 * To read these registers we have: 84 * 1) Write reg 13 // DEVAD 85 * 2) Write reg 14 // MMD Address 86 * 3) Write reg 13 // MMD Data Command for MMD DEVAD 87 * 3) Read reg 14 // Read MMD data 88 */ 89 int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, 90 int devad, int addr) 91 { 92 int value = -1; 93 94 /* Write the desired MMD Devad */ 95 phy_write(phydev, addr, MII_MMD_CTRL, devad); 96 97 /* Write the desired MMD register address */ 98 phy_write(phydev, addr, MII_MMD_DATA, prtad); 99 100 /* Select the Function : DATA with no post increment */ 101 phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); 102 103 /* Read the content of the MMD's selected register */ 104 value = phy_read(phydev, addr, MII_MMD_DATA); 105 return value; 106 } 107 108 /** 109 * phy_write_mmd_indirect - writes data to the MMD registers 110 * @phydev: The PHY device 111 * @prtad: MMD Address 112 * @devad: MMD DEVAD 113 * @addr: PHY address on the MII bus 114 * @data: data to write in the MMD register 115 * 116 * Description: Write data from the MMD registers of the specified 117 * phy address. 118 * To write these registers we have: 119 * 1) Write reg 13 // DEVAD 120 * 2) Write reg 14 // MMD Address 121 * 3) Write reg 13 // MMD Data Command for MMD DEVAD 122 * 3) Write reg 14 // Write MMD data 123 */ 124 void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, 125 int devad, int addr, u32 data) 126 { 127 /* Write the desired MMD Devad */ 128 phy_write(phydev, addr, MII_MMD_CTRL, devad); 129 130 /* Write the desired MMD register address */ 131 phy_write(phydev, addr, MII_MMD_DATA, prtad); 132 133 /* Select the Function : DATA with no post increment */ 134 phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); 135 136 /* Write the data into MMD's selected register */ 137 phy_write(phydev, addr, MII_MMD_DATA, data); 138 } 139 140 /** 141 * phy_interface_is_rgmii - Convenience function for testing if a PHY interface 142 * is RGMII (all variants) 143 * @phydev: the phy_device struct 144 */ 145 static inline bool phy_interface_is_rgmii(struct phy_device *phydev) 146 { 147 return phydev->interface >= PHY_INTERFACE_MODE_RGMII && 148 phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID; 149 } 150 151 /* User setting - can be taken from DTS */ 152 #define RX_ID_DELAY 8 153 #define TX_ID_DELAY 0xa 154 #define FIFO_DEPTH 1 155 156 static int dp83867_config(struct phy_device *phydev) 157 { 158 unsigned int val, delay, cfg2; 159 int ret; 160 161 /* Restart the PHY. */ 162 val = phy_read(phydev, MDIO_DEVAD_NONE, DP83867_CTRL); 163 phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL, 164 val | DP83867_SW_RESTART); 165 166 if (phy_interface_is_rgmii(phydev)) { 167 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL, 168 (DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) | 169 (FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT)); 170 if (ret) 171 return ret; 172 } else { 173 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, 174 (BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000)); 175 176 cfg2 = phy_read(phydev, phydev->addr, MII_DP83867_CFG2); 177 cfg2 &= MII_DP83867_CFG2_MASK; 178 cfg2 |= (MII_DP83867_CFG2_SPEEDOPT_10EN | 179 MII_DP83867_CFG2_SGMII_AUTONEGEN | 180 MII_DP83867_CFG2_SPEEDOPT_ENH | 181 MII_DP83867_CFG2_SPEEDOPT_CNT | 182 MII_DP83867_CFG2_SPEEDOPT_INTLOW); 183 phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG2, cfg2); 184 185 phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, 186 DP83867_DEVADDR, phydev->addr, 0x0); 187 188 phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL, 189 DP83867_PHYCTRL_SGMIIEN | 190 (DP83867_MDI_CROSSOVER_MDIX << 191 DP83867_MDI_CROSSOVER) | 192 (FIFO_DEPTH << DP83867_PHYCTRL_RXFIFO_SHIFT) | 193 (FIFO_DEPTH << DP83867_PHYCTRL_TXFIFO_SHIFT)); 194 phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_BISCR, 0x0); 195 } 196 197 if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) && 198 (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) { 199 val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL, 200 DP83867_DEVADDR, phydev->addr); 201 202 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 203 val |= (DP83867_RGMII_TX_CLK_DELAY_EN | 204 DP83867_RGMII_RX_CLK_DELAY_EN); 205 206 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 207 val |= DP83867_RGMII_TX_CLK_DELAY_EN; 208 209 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) 210 val |= DP83867_RGMII_RX_CLK_DELAY_EN; 211 212 phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, 213 DP83867_DEVADDR, phydev->addr, val); 214 215 delay = (RX_ID_DELAY | 216 (TX_ID_DELAY << DP83867_RGMII_TX_CLK_DELAY_SHIFT)); 217 218 phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL, 219 DP83867_DEVADDR, phydev->addr, delay); 220 } 221 222 genphy_config_aneg(phydev); 223 return 0; 224 } 225 226 static struct phy_driver DP83867_driver = { 227 .name = "TI DP83867", 228 .uid = 0x2000a231, 229 .mask = 0xfffffff0, 230 .features = PHY_GBIT_FEATURES, 231 .config = &dp83867_config, 232 .startup = &genphy_startup, 233 .shutdown = &genphy_shutdown, 234 }; 235 236 int phy_ti_init(void) 237 { 238 phy_register(&DP83867_driver); 239 return 0; 240 } 241