]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-davinci/dp83848.c
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[u-boot] / arch / arm / mach-davinci / dp83848.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * National Semiconductor DP83848 PHY Driver for TI DaVinci
4  * (TMS320DM644x) based boards.
5  *
6  * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
7  *
8  * --------------------------------------------------------
9  */
10
11 #include <common.h>
12 #include <net.h>
13 #include <dp83848.h>
14 #include <asm/arch/emac_defs.h>
15 #include "../../../drivers/net/davinci_emac.h"
16
17 #ifdef CONFIG_DRIVER_TI_EMAC
18
19 #ifdef CONFIG_CMD_NET
20
21 int dp83848_is_phy_connected(int phy_addr)
22 {
23         u_int16_t       id1, id2;
24
25         if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1))
26                 return(0);
27         if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2))
28                 return(0);
29
30         if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI))
31                 return(1);
32
33         return(0);
34 }
35
36 int dp83848_get_link_speed(int phy_addr)
37 {
38         u_int16_t               tmp;
39         volatile emac_regs*     emac = (emac_regs *)EMAC_BASE_ADDR;
40
41         if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
42                 return(0);
43
44         if (!(tmp & DP83848_LINK_STATUS))       /* link up? */
45                 return(0);
46
47         if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp))
48                 return(0);
49
50         /* Speed doesn't matter, there is no setting for it in EMAC... */
51         if (tmp & DP83848_DUPLEX) {
52                 /* set DM644x EMAC for Full Duplex  */
53                 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
54                         EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
55         } else {
56                 /*set DM644x EMAC for Half Duplex  */
57                 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
58         }
59
60         return(1);
61 }
62
63
64 int dp83848_init_phy(int phy_addr)
65 {
66         int     ret = 1;
67
68         if (!dp83848_get_link_speed(phy_addr)) {
69                 /* Try another time */
70                 udelay(100000);
71                 ret = dp83848_get_link_speed(phy_addr);
72         }
73
74         /* Disable PHY Interrupts */
75         davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0);
76
77         return(ret);
78 }
79
80
81 int dp83848_auto_negotiate(int phy_addr)
82 {
83         u_int16_t       tmp;
84
85
86         if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
87                 return(0);
88
89         /* Restart Auto_negotiation  */
90         tmp &= ~DP83848_AUTONEG;        /* remove autonegotiation enable */
91         tmp |= DP83848_ISOLATE;         /* Electrically isolate PHY */
92         davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
93
94         /* Set the Auto_negotiation Advertisement Register
95          * MII advertising for Next page, 100BaseTxFD and HD,
96          * 10BaseTFD and HD, IEEE 802.3
97          */
98         tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX |
99                 DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3;
100         davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp);
101
102
103         /* Read Control Register */
104         if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
105                 return(0);
106
107         tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE;
108         davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
109
110         /* Restart Auto_negotiation  */
111         tmp |= DP83848_RESTART_AUTONEG;
112         davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
113
114         /*check AutoNegotiate complete */
115         udelay(10000);
116         if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
117                 return(0);
118
119         if (!(tmp & DP83848_AUTONEG_COMP))
120                 return(0);
121
122         return (dp83848_get_link_speed(phy_addr));
123 }
124
125 #endif  /* CONFIG_CMD_NET */
126
127 #endif  /* CONFIG_DRIVER_ETHER */