1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2601fbec7SMasahiro Yamada /* 3601fbec7SMasahiro Yamada * Intel LXT971/LXT972 PHY Driver for TI DaVinci 4601fbec7SMasahiro Yamada * (TMS320DM644x) based boards. 5601fbec7SMasahiro Yamada * 6601fbec7SMasahiro Yamada * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> 7601fbec7SMasahiro Yamada * 8601fbec7SMasahiro Yamada * -------------------------------------------------------- 9601fbec7SMasahiro Yamada */ 10601fbec7SMasahiro Yamada 11601fbec7SMasahiro Yamada #include <common.h> 12601fbec7SMasahiro Yamada #include <net.h> 13601fbec7SMasahiro Yamada #include <miiphy.h> 14601fbec7SMasahiro Yamada #include <lxt971a.h> 15601fbec7SMasahiro Yamada #include <asm/arch/emac_defs.h> 16601fbec7SMasahiro Yamada #include "../../../drivers/net/davinci_emac.h" 17601fbec7SMasahiro Yamada 18601fbec7SMasahiro Yamada #ifdef CONFIG_DRIVER_TI_EMAC 19601fbec7SMasahiro Yamada 20601fbec7SMasahiro Yamada #ifdef CONFIG_CMD_NET 21601fbec7SMasahiro Yamada 22601fbec7SMasahiro Yamada int lxt972_is_phy_connected(int phy_addr) 23601fbec7SMasahiro Yamada { 24601fbec7SMasahiro Yamada u_int16_t id1, id2; 25601fbec7SMasahiro Yamada 26601fbec7SMasahiro Yamada if (!davinci_eth_phy_read(phy_addr, MII_PHYSID1, &id1)) 27601fbec7SMasahiro Yamada return(0); 28601fbec7SMasahiro Yamada if (!davinci_eth_phy_read(phy_addr, MII_PHYSID2, &id2)) 29601fbec7SMasahiro Yamada return(0); 30601fbec7SMasahiro Yamada 31601fbec7SMasahiro Yamada if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0)) 32601fbec7SMasahiro Yamada return(1); 33601fbec7SMasahiro Yamada 34601fbec7SMasahiro Yamada return(0); 35601fbec7SMasahiro Yamada } 36601fbec7SMasahiro Yamada 37601fbec7SMasahiro Yamada int lxt972_get_link_speed(int phy_addr) 38601fbec7SMasahiro Yamada { 39601fbec7SMasahiro Yamada u_int16_t stat1, tmp; 40601fbec7SMasahiro Yamada volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; 41601fbec7SMasahiro Yamada 42601fbec7SMasahiro Yamada if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) 43601fbec7SMasahiro Yamada return(0); 44601fbec7SMasahiro Yamada 45601fbec7SMasahiro Yamada if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ 46601fbec7SMasahiro Yamada return(0); 47601fbec7SMasahiro Yamada 48601fbec7SMasahiro Yamada if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) 49601fbec7SMasahiro Yamada return(0); 50601fbec7SMasahiro Yamada 51601fbec7SMasahiro Yamada tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; 52601fbec7SMasahiro Yamada 53601fbec7SMasahiro Yamada davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); 54601fbec7SMasahiro Yamada /* Read back */ 55601fbec7SMasahiro Yamada if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) 56601fbec7SMasahiro Yamada return(0); 57601fbec7SMasahiro Yamada 58601fbec7SMasahiro Yamada /* Speed doesn't matter, there is no setting for it in EMAC... */ 59601fbec7SMasahiro Yamada if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { 60601fbec7SMasahiro Yamada /* set DM644x EMAC for Full Duplex */ 61601fbec7SMasahiro Yamada emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | 62601fbec7SMasahiro Yamada EMAC_MACCONTROL_FULLDUPLEX_ENABLE; 63601fbec7SMasahiro Yamada } else { 64601fbec7SMasahiro Yamada /*set DM644x EMAC for Half Duplex */ 65601fbec7SMasahiro Yamada emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; 66601fbec7SMasahiro Yamada } 67601fbec7SMasahiro Yamada 68601fbec7SMasahiro Yamada return(1); 69601fbec7SMasahiro Yamada } 70601fbec7SMasahiro Yamada 71601fbec7SMasahiro Yamada 72601fbec7SMasahiro Yamada int lxt972_init_phy(int phy_addr) 73601fbec7SMasahiro Yamada { 74601fbec7SMasahiro Yamada int ret = 1; 75601fbec7SMasahiro Yamada 76601fbec7SMasahiro Yamada if (!lxt972_get_link_speed(phy_addr)) { 77601fbec7SMasahiro Yamada /* Try another time */ 78601fbec7SMasahiro Yamada ret = lxt972_get_link_speed(phy_addr); 79601fbec7SMasahiro Yamada } 80601fbec7SMasahiro Yamada 81601fbec7SMasahiro Yamada /* Disable PHY Interrupts */ 82601fbec7SMasahiro Yamada davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); 83601fbec7SMasahiro Yamada 84601fbec7SMasahiro Yamada return(ret); 85601fbec7SMasahiro Yamada } 86601fbec7SMasahiro Yamada 87601fbec7SMasahiro Yamada 88601fbec7SMasahiro Yamada int lxt972_auto_negotiate(int phy_addr) 89601fbec7SMasahiro Yamada { 90601fbec7SMasahiro Yamada u_int16_t tmp; 91601fbec7SMasahiro Yamada 92601fbec7SMasahiro Yamada if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp)) 93601fbec7SMasahiro Yamada return(0); 94601fbec7SMasahiro Yamada 95601fbec7SMasahiro Yamada /* Restart Auto_negotiation */ 96601fbec7SMasahiro Yamada tmp |= BMCR_ANRESTART; 97601fbec7SMasahiro Yamada davinci_eth_phy_write(phy_addr, MII_BMCR, tmp); 98601fbec7SMasahiro Yamada 99601fbec7SMasahiro Yamada /*check AutoNegotiate complete */ 100601fbec7SMasahiro Yamada udelay (10000); 101601fbec7SMasahiro Yamada if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp)) 102601fbec7SMasahiro Yamada return(0); 103601fbec7SMasahiro Yamada 104601fbec7SMasahiro Yamada if (!(tmp & BMSR_ANEGCOMPLETE)) 105601fbec7SMasahiro Yamada return(0); 106601fbec7SMasahiro Yamada 107601fbec7SMasahiro Yamada return (lxt972_get_link_speed(phy_addr)); 108601fbec7SMasahiro Yamada } 109601fbec7SMasahiro Yamada 110601fbec7SMasahiro Yamada #endif /* CONFIG_CMD_NET */ 111601fbec7SMasahiro Yamada 112601fbec7SMasahiro Yamada #endif /* CONFIG_DRIVER_ETHER */ 113