add new PHY chips support
PATCH 3/3 add new PHY chips support
Add Marvell 88E1111 PHY support, tested on U-Boot 1.3.4.
--- cpu/arm926ejs/davinci/Makefile | 1 + cpu/arm926ejs/davinci/ether.c | 14 +++ cpu/arm926ejs/davinci/marvell.c | 189 ++++++++++++++++++++++++++++++ include/asm-arm/arch-davinci/emac_defs.h | 6 + 4 files changed, 210 insertions(+), 0 deletions(-)
create mode 100644 cpu/arm926ejs/davinci/marvell.c
cpu/arm926ejs/davinci/Makefile +1 -0
@@ -29,6 +29,7 @@ LIB = $(obj)lib$(SOC).a COBJS = timer.o ether.o lxt972.o dp83848.o i2c.o nand.o COBJS += realtek.o +COBJS += marvell.o SOBJS = lowlevel_init.o reset.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
cpu/arm926ejs/davinci/ether.c +5 -0
@@ -406,6 +406,14 @@ static int davinci_eth_hw_init(void) phy.get_link_speed = rtl8201_get_link_speed; phy.auto_negotiate = rtl8201_auto_negotiate;break ; +case PHY_MARVEL88E1111 : +sprintf (phy.name,"MARVELL88E1111 @ 0x%02x" , + active_phy_addr); + phy.init = marvell88e1111_init_phy; + phy.is_phy_connected =
marvell88e1111_is_phy_connected;
+ phy.get_link_speed = marvell88e1111_get_link_speed;
+ phy.auto_negotiate = marvell88e1111_auto_negotiate;
+ break;
default:
sprintf(phy.name, "GENERIC @ 0x%02x",
active_phy_addr);
phy.init = gen_init_phy;@@ -416,6 +424,12 @@ static int davinci_eth_hw_init(void)
printf("Ethernet PHY: %s\n", phy.name);+ /* disable 1000Mb/s autonegotiation */
+ if (PHY_MARVEL88E1111 == phy_id) {
+ if (!phy.init(active_phy_addr))
+ return(0);
+ }
+
return(1);
}
(quoted diff) +0 -0
b/cpu/arm926ejs/davinci/marvell.c
new file mode 100644
index 0000000..6918bef
cpu/arm926ejs/davinci/marvell.c new file +4 -0
@@ -0,0 +1,189 @@ +/* +* Marvel 88E1111 Driver for TI DaVinci (TMS320DM635) based boards. +* +* Copyright (C) 2011 Brilliantov Kirill Vladimirovich
<[email protected]>
+ * References: 88E1111 Datasheet Integrated 10/100/1000
+ * Ultra Gigabit Ethernet Transceiver
+ * Doc. No. MV-S100649-00, Rev. F
+ * December, 3, 2004
+ * --------------------------------------------------------
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <net.h>
+#include <miiphy.h>
+#include <asm/arch/emac_defs.h>
+
+#ifdef CONFIG_DRIVER_TI_EMAC
+
+#ifdef CONFIG_CMD_NET
+
+#define DEBUG 0
+#define DBG(f, a...) \
+ do {\
+ if (DEBUG) \
+ printf("Marvell: " f "\n", ##a);\
+ } while (0)
+#define ERR(f, a...) printf("Marvell: %s: " f "\n", __func__, ##a)
+
+#define LINK_DOWN (0 << 2)
+#define EXTENDED_PHY_SPECIFIC_STATUS_REGISTER 27
+
+int marvell88e1111_is_phy_connected(int phy_addr)
+{
+ u_int16_t id1, id2;
+
+ DBG("starting %s", __func__);
+
+ if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR1, &id1)) {
+ ERR("can't read PHY_PHYIDR1 register %#x", PHY_PHYIDR1);
+ return (0);
+ }
+
+ if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR2, &id2)) {
+ ERR("can't read PHY_PHYIDR2 register %#x", PHY_PHYIDR2);
+ return (0);
+ }
+
+ DBG("ID1 %#x, ID2 %#x\n", id1, id2);
+
+ if ((id1 == 0x141) && ((id2 & 0xFFF0) == 0x0CC0))
+ return (1);
+
+ ERR("ID1 or ID2 not corrected");
+
+ return (0);
+}
+
+int marvell88e1111_get_link_speed(int phy_addr)
+{
+ u_int16_t val;
+ volatile emac_regs *emac = (emac_regs *) EMAC_BASE_ADDR;
+
+ DBG("starting %s", __func__);
+
+ if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &val)) {
+ ERR("can't read PHY_BMSR register %#x", PHY_BMSR);
+ return (0);
+ }
+
+ if (val & LINK_DOWN) {
+ ERR("link down");
+ return (0);
+ }
+ DBG("link up");
+
+ if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &val)) {
+ ERR("can't read PHY_BMCR register %#x", PHY_BMCR);
+ return (0);
+ }
+
+ if (val & PHY_BMCR_DPLX) {
+ DBG("set emac full duplex mode");
+ emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
+ EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+ } else {
+ DBG("set emac half duplex mode");
+ emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
+ }
+
+ return (1);
+}
+
+int marvell88e1111_init_phy(int phy_addr)
+{
+ int ret = 1;
+
+ DBG("starting %s\n", __func__);
+
+#if defined(CFG_DM365_EVM) || defined(CFG_DM365_IPNC) || defined(CFG_DM368_IPNC)
+ u_int16_t tmp;
+
+ if (!davinci_eth_phy_read(phy_addr,
+ EXTENDED_PHY_SPECIFIC_STATUS_REGISTER, &tmp)) {
+ ERR("can't read Extended PHY Status register %#x",
+ EXTENDED_PHY_SPECIFIC_STATUS_REGISTER);
+ return (0);
+ }
+ if (!davinci_eth_phy_write(phy_addr,
+ EXTENDED_PHY_SPECIFIC_STATUS_REGISTER, tmp | 0xF)) {
+ ERR("can't set GMII to cooper mode");
+ return (0);
+ }
+ DBG("hardware configred set in GMII to cooper mode");
+
+ if (!marvell88e1111_auto_negotiate(phy_addr))
+ ret = marvell88e1111_auto_negotiate(phy_addr);
+#else
+ if (!marvell88e1111_get_link_speed(phy_addr))
+ ret = marvell88e1111_get_link_speed(phy_addr);
+#endif
+
+ return (ret);
+}
+
+int marvell88e1111_auto_negotiate(int phy_addr)
+{
+ u_int16_t tmp;
+
+ DBG("starting %s", __func__);
+
+#if defined(CFG_DM365_EVM) || defined(CFG_DM365_IPNC) || defined(CFG_DM368_IPNC)
+ /* disable autonegotiation 1000Mb/s */
+ if (!davinci_eth_phy_read(phy_addr, PHY_1000BTCR, &tmp)) {
+ ERR("can't read PHY_1000BTCR register %#x", PHY_1000BTCR);
+ return (0);
+ }
+ if (!davinci_eth_phy_write(phy_addr, PHY_1000BTCR,
+ tmp & (~(PHY_1000BTCR_1000FD | PHY_1000BTCR_1000HD)))) {
+ ERR("can't disable 1000Mb/s autonegotiation");
+ return (0);
+ }
+ DBG("1000Mb/s autonegotiation disabled");
+#endif
+
+ if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) {
+ ERR("can't read PHY_BMCR register %#x", PHY_BMCR);
+ return (0);
+ }
+
+ tmp |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG | PHY_BMCR_RESET);
+ davinci_eth_phy_write(phy_addr, PHY_BMCR, tmp);
+
+ udelay(10000);
+ if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) {
+ ERR("can't read PHY_BMSR register %#x", PHY_BMSR);
+ return (0);
+ }
+
+ if (tmp & PHY_BMSR_AUTN_COMP)
+ DBG("autonegotiation completed");
+ else {
+ ERR("autonegotiation not completed");
+ return (0);
+ }
+
+ return (marvell88e1111_get_link_speed(phy_addr));
+}
+
+#endif /* CONFIG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_ETHER */
(quoted diff) +0 -0
b/include/asm-arm/arch-davinci/emac_defs.h
index fafbce4..b0aca7c 100644
include/asm-arm/arch-davinci/emac_defs.h +6 -0
@@ -349,4 +349,10 @@ int rtl8201_get_link_speed(int phy_addr);int rtl8201_init_phy (int phy_addr);int rtl8201_auto_negotiate (int phy_addr); +#define PHY_MARVEL88E1111 (0x1410CC2) +int marvell88e1111_is_phy_connected (int phy_addr); +int marvell88e1111_get_link_speed (int phy_addr); +int marvell88e1111_init_phy (int phy_addr); +int marvell88e1111_auto_negotiate (int phy_addr); +#endif /* _DM644X_EMAC_H_ */
Signature · 10 lines
-- ? ?????????, ??????????? ?????? ???????????? ????????????????????????? ???????????, ??????????? ????? ??? ????????? ??????????? ??? ? ????????????? ???????? ??????? ????????????????????????? +7(495)221-66-22 http://www.byterg.ru http://www.bestdvr.ru
PATCH 3/3 add new PHY chips support
your patch is line wrapped
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20111004/20d4e6e0/attachment.pgp