]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm926ejs/davinci/dp83848.c
davinci_emac: move arch-independent defines to separate header
[karo-tx-uboot.git] / arch / arm / cpu / arm926ejs / davinci / dp83848.c
1 /*
2  * National Semiconductor DP83848 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 <dp83848.h>
31 #include <asm/arch/emac_defs.h>
32 #include "../../../../../drivers/net/davinci_emac.h"
33
34 #ifdef CONFIG_DRIVER_TI_EMAC
35
36 #ifdef CONFIG_CMD_NET
37
38 int dp83848_is_phy_connected(int phy_addr)
39 {
40         u_int16_t       id1, id2;
41
42         if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1))
43                 return(0);
44         if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2))
45                 return(0);
46
47         if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI))
48                 return(1);
49
50         return(0);
51 }
52
53 int dp83848_get_link_speed(int phy_addr)
54 {
55         u_int16_t               tmp;
56         volatile emac_regs*     emac = (emac_regs *)EMAC_BASE_ADDR;
57
58         if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
59                 return(0);
60
61         if (!(tmp & DP83848_LINK_STATUS))       /* link up? */
62                 return(0);
63
64         if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp))
65                 return(0);
66
67         /* Speed doesn't matter, there is no setting for it in EMAC... */
68         if (tmp & DP83848_DUPLEX) {
69                 /* set DM644x EMAC for Full Duplex  */
70                 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
71                         EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
72         } else {
73                 /*set DM644x EMAC for Half Duplex  */
74                 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
75         }
76
77         return(1);
78 }
79
80
81 int dp83848_init_phy(int phy_addr)
82 {
83         int     ret = 1;
84
85         if (!dp83848_get_link_speed(phy_addr)) {
86                 /* Try another time */
87                 udelay(100000);
88                 ret = dp83848_get_link_speed(phy_addr);
89         }
90
91         /* Disable PHY Interrupts */
92         davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0);
93
94         return(ret);
95 }
96
97
98 int dp83848_auto_negotiate(int phy_addr)
99 {
100         u_int16_t       tmp;
101
102
103         if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
104                 return(0);
105
106         /* Restart Auto_negotiation  */
107         tmp &= ~DP83848_AUTONEG;        /* remove autonegotiation enable */
108         tmp |= DP83848_ISOLATE;         /* Electrically isolate PHY */
109         davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
110
111         /* Set the Auto_negotiation Advertisement Register
112          * MII advertising for Next page, 100BaseTxFD and HD,
113          * 10BaseTFD and HD, IEEE 802.3
114          */
115         tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX |
116                 DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3;
117         davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp);
118
119
120         /* Read Control Register */
121         if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
122                 return(0);
123
124         tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE;
125         davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
126
127         /* Restart Auto_negotiation  */
128         tmp |= DP83848_RESTART_AUTONEG;
129         davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
130
131         /*check AutoNegotiate complete */
132         udelay(10000);
133         if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
134                 return(0);
135
136         if (!(tmp & DP83848_AUTONEG_COMP))
137                 return(0);
138
139         return (dp83848_get_link_speed(phy_addr));
140 }
141
142 #endif  /* CONFIG_CMD_NET */
143
144 #endif  /* CONFIG_DRIVER_ETHER */