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