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