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