1 /* 2 * Intel LXT971/LXT972 PHY Driver for TI DaVinci 3 * (TMS320DM644x) based boards. 4 * 5 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> 6 * 7 * -------------------------------------------------------- 8 * 9 * SPDX-License-Identifier: GPL-2.0+ 10 */ 11 12 #include <common.h> 13 #include <net.h> 14 #include <miiphy.h> 15 #include <lxt971a.h> 16 #include <asm/arch/emac_defs.h> 17 #include "../../../drivers/net/davinci_emac.h" 18 19 #ifdef CONFIG_DRIVER_TI_EMAC 20 21 #ifdef CONFIG_CMD_NET 22 23 int lxt972_is_phy_connected(int phy_addr) 24 { 25 u_int16_t id1, id2; 26 27 if (!davinci_eth_phy_read(phy_addr, MII_PHYSID1, &id1)) 28 return(0); 29 if (!davinci_eth_phy_read(phy_addr, MII_PHYSID2, &id2)) 30 return(0); 31 32 if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0)) 33 return(1); 34 35 return(0); 36 } 37 38 int lxt972_get_link_speed(int phy_addr) 39 { 40 u_int16_t stat1, tmp; 41 volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; 42 43 if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) 44 return(0); 45 46 if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ 47 return(0); 48 49 if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) 50 return(0); 51 52 tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; 53 54 davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); 55 /* Read back */ 56 if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) 57 return(0); 58 59 /* Speed doesn't matter, there is no setting for it in EMAC... */ 60 if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { 61 /* set DM644x EMAC for Full Duplex */ 62 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | 63 EMAC_MACCONTROL_FULLDUPLEX_ENABLE; 64 } else { 65 /*set DM644x EMAC for Half Duplex */ 66 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; 67 } 68 69 return(1); 70 } 71 72 73 int lxt972_init_phy(int phy_addr) 74 { 75 int ret = 1; 76 77 if (!lxt972_get_link_speed(phy_addr)) { 78 /* Try another time */ 79 ret = lxt972_get_link_speed(phy_addr); 80 } 81 82 /* Disable PHY Interrupts */ 83 davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); 84 85 return(ret); 86 } 87 88 89 int lxt972_auto_negotiate(int phy_addr) 90 { 91 u_int16_t tmp; 92 93 if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp)) 94 return(0); 95 96 /* Restart Auto_negotiation */ 97 tmp |= BMCR_ANRESTART; 98 davinci_eth_phy_write(phy_addr, MII_BMCR, tmp); 99 100 /*check AutoNegotiate complete */ 101 udelay (10000); 102 if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp)) 103 return(0); 104 105 if (!(tmp & BMSR_ANEGCOMPLETE)) 106 return(0); 107 108 return (lxt972_get_link_speed(phy_addr)); 109 } 110 111 #endif /* CONFIG_CMD_NET */ 112 113 #endif /* CONFIG_DRIVER_ETHER */ 114