Home | History | Annotate | Download | only in mach-davinci
      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