blob: 595e3ca149bd39875b973b683fe75687a26bf14e [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Sergey Kubushync74b2102007-08-10 20:26:18 +02002/*
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 * --------------------------------------------------------
Sergey Kubushync74b2102007-08-10 20:26:18 +02009 */
10
11#include <common.h>
12#include <net.h>
13#include <dp83848.h>
14#include <asm/arch/emac_defs.h>
Masahiro Yamada601fbec2015-02-20 17:04:05 +090015#include "../../../drivers/net/davinci_emac.h"
Sergey Kubushync74b2102007-08-10 20:26:18 +020016
17#ifdef CONFIG_DRIVER_TI_EMAC
18
19#ifdef CONFIG_CMD_NET
20
21int dp83848_is_phy_connected(int phy_addr)
22{
23 u_int16_t id1, id2;
24
Sandeep Paulrajfcaac582008-08-31 00:39:46 +020025 if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1))
Sergey Kubushync74b2102007-08-10 20:26:18 +020026 return(0);
Sandeep Paulrajfcaac582008-08-31 00:39:46 +020027 if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2))
Sergey Kubushync74b2102007-08-10 20:26:18 +020028 return(0);
29
30 if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI))
31 return(1);
32
33 return(0);
34}
35
36int dp83848_get_link_speed(int phy_addr)
37{
38 u_int16_t tmp;
39 volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR;
40
Sandeep Paulrajfcaac582008-08-31 00:39:46 +020041 if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
Sergey Kubushync74b2102007-08-10 20:26:18 +020042 return(0);
43
44 if (!(tmp & DP83848_LINK_STATUS)) /* link up? */
45 return(0);
46
Sandeep Paulrajfcaac582008-08-31 00:39:46 +020047 if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp))
Sergey Kubushync74b2102007-08-10 20:26:18 +020048 return(0);
49
50 /* Speed doesn't matter, there is no setting for it in EMAC... */
Hugo Villeneuveb5b03442008-09-12 02:20:47 +020051 if (tmp & DP83848_DUPLEX) {
52 /* set DM644x EMAC for Full Duplex */
53 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
54 EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
Sergey Kubushync74b2102007-08-10 20:26:18 +020055 } else {
Hugo Villeneuveb5b03442008-09-12 02:20:47 +020056 /*set DM644x EMAC for Half Duplex */
57 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
Sergey Kubushync74b2102007-08-10 20:26:18 +020058 }
59
Hugo Villeneuveb5b03442008-09-12 02:20:47 +020060 return(1);
Sergey Kubushync74b2102007-08-10 20:26:18 +020061}
62
63
64int 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 */
Sandeep Paulrajfcaac582008-08-31 00:39:46 +020075 davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0);
Sergey Kubushync74b2102007-08-10 20:26:18 +020076
77 return(ret);
78}
79
80
81int dp83848_auto_negotiate(int phy_addr)
82{
83 u_int16_t tmp;
84
85
Sandeep Paulrajfcaac582008-08-31 00:39:46 +020086 if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
Sergey Kubushync74b2102007-08-10 20:26:18 +020087 return(0);
88
89 /* Restart Auto_negotiation */
90 tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */
91 tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */
Sandeep Paulrajfcaac582008-08-31 00:39:46 +020092 davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
Sergey Kubushync74b2102007-08-10 20:26:18 +020093
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 |
Wolfgang Denk53677ef2008-05-20 16:00:29 +020099 DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3;
Sandeep Paulrajfcaac582008-08-31 00:39:46 +0200100 davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp);
Sergey Kubushync74b2102007-08-10 20:26:18 +0200101
102
103 /* Read Control Register */
Sandeep Paulrajfcaac582008-08-31 00:39:46 +0200104 if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
Sergey Kubushync74b2102007-08-10 20:26:18 +0200105 return(0);
106
107 tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE;
Sandeep Paulrajfcaac582008-08-31 00:39:46 +0200108 davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
Sergey Kubushync74b2102007-08-10 20:26:18 +0200109
110 /* Restart Auto_negotiation */
111 tmp |= DP83848_RESTART_AUTONEG;
Sandeep Paulrajfcaac582008-08-31 00:39:46 +0200112 davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
Sergey Kubushync74b2102007-08-10 20:26:18 +0200113
114 /*check AutoNegotiate complete */
115 udelay(10000);
Sandeep Paulrajfcaac582008-08-31 00:39:46 +0200116 if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
Sergey Kubushync74b2102007-08-10 20:26:18 +0200117 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 */