]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/arm926ejs/davinci/lxt972.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[u-boot] / arch / arm / cpu / arm926ejs / davinci / lxt972.c
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  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 #include <common.h>
29 #include <net.h>
30 #include <miiphy.h>
31 #include <lxt971a.h>
32 #include <asm/arch/emac_defs.h>
33 #include "../../../../../drivers/net/davinci_emac.h"
34
35 #ifdef CONFIG_DRIVER_TI_EMAC
36
37 #ifdef CONFIG_CMD_NET
38
39 int lxt972_is_phy_connected(int phy_addr)
40 {
41         u_int16_t id1, id2;
42
43         if (!davinci_eth_phy_read(phy_addr, MII_PHYSID1, &id1))
44                 return(0);
45         if (!davinci_eth_phy_read(phy_addr, MII_PHYSID2, &id2))
46                 return(0);
47
48         if ((id1 == (0x0013)) && ((id2  & 0xfff0) == 0x78e0))
49                 return(1);
50
51         return(0);
52 }
53
54 int lxt972_get_link_speed(int phy_addr)
55 {
56         u_int16_t stat1, tmp;
57         volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR;
58
59         if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1))
60                 return(0);
61
62         if (!(stat1 & PHY_LXT971_STAT2_LINK))   /* link up? */
63                 return(0);
64
65         if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp))
66                 return(0);
67
68         tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE;
69
70         davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp);
71         /* Read back */
72         if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp))
73                 return(0);
74
75         /* Speed doesn't matter, there is no setting for it in EMAC... */
76         if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) {
77                 /* set DM644x EMAC for Full Duplex  */
78                 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
79                         EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
80         } else {
81                 /*set DM644x EMAC for Half Duplex  */
82                 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
83         }
84
85         return(1);
86 }
87
88
89 int lxt972_init_phy(int phy_addr)
90 {
91         int ret = 1;
92
93         if (!lxt972_get_link_speed(phy_addr)) {
94                 /* Try another time */
95                 ret = lxt972_get_link_speed(phy_addr);
96         }
97
98         /* Disable PHY Interrupts */
99         davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0);
100
101         return(ret);
102 }
103
104
105 int lxt972_auto_negotiate(int phy_addr)
106 {
107         u_int16_t tmp;
108
109         if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
110                 return(0);
111
112         /* Restart Auto_negotiation  */
113         tmp |= BMCR_ANRESTART;
114         davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
115
116         /*check AutoNegotiate complete */
117         udelay (10000);
118         if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
119                 return(0);
120
121         if (!(tmp & BMSR_ANEGCOMPLETE))
122                 return(0);
123
124         return (lxt972_get_link_speed(phy_addr));
125 }
126
127 #endif  /* CONFIG_CMD_NET */
128
129 #endif  /* CONFIG_DRIVER_ETHER */