[U-Boot] [PATCH 2/3] add new PHY chips support

Brilliantov Kirill Vladimirovich brilliantov at byterg.ru
Tue Oct 4 08:28:00 CEST 2011


Add Realtek RTL8201BL PHY support, tested on U-Boot 1.3.4.

Signed-off-by: Brilliantov Kirill Vladimirovich <brilliantov at byterg.ru>
---
  cpu/arm926ejs/davinci/Makefile           |    1 +
  cpu/arm926ejs/davinci/ether.c            |    7 ++
  cpu/arm926ejs/davinci/realtek.c          |  154 
++++++++++++++++++++++++++++++
  include/asm-arm/arch-davinci/emac_defs.h |   10 ++-
  4 files changed, 170 insertions(+), 2 deletions(-)
  create mode 100644 cpu/arm926ejs/davinci/realtek.c

diff --git a/cpu/arm926ejs/davinci/Makefile b/cpu/arm926ejs/davinci/Makefile
index 0f77f40..0b6cbd2 100644
--- a/cpu/arm926ejs/davinci/Makefile
+++ b/cpu/arm926ejs/davinci/Makefile
@@ -28,6 +28,7 @@ include $(TOPDIR)/config.mk
  LIB    = $(obj)lib$(SOC).a

  COBJS  = timer.o ether.o lxt972.o dp83848.o i2c.o nand.o
+COBJS  += realtek.o
  SOBJS  = lowlevel_init.o reset.o

  SRCS   := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/arm926ejs/davinci/ether.c b/cpu/arm926ejs/davinci/ether.c
index 13292e1..09fe24e 100644
--- a/cpu/arm926ejs/davinci/ether.c
+++ b/cpu/arm926ejs/davinci/ether.c
@@ -399,6 +399,13 @@ static int davinci_eth_hw_init(void)
                         phy.get_link_speed = dp83848_get_link_speed;
                         phy.auto_negotiate = dp83848_auto_negotiate;
                         break;
+               case PHY_RTL8201:
+                       sprintf(phy.name, "RTL8201 @ 0x%02x", 
active_phy_addr);
+                       phy.init = rtl8201_init_phy;
+                       phy.is_phy_connected = rtl8201_is_phy_connected;
+                       phy.get_link_speed = rtl8201_get_link_speed;
+                       phy.auto_negotiate = rtl8201_auto_negotiate;
+                       break;
                 default:
                         sprintf(phy.name, "GENERIC @ 0x%02x", 
active_phy_addr);
                         phy.init = gen_init_phy;
diff --git a/cpu/arm926ejs/davinci/realtek.c 
b/cpu/arm926ejs/davinci/realtek.c
new file mode 100644
index 0000000..22884bd
--- /dev/null
+++ b/cpu/arm926ejs/davinci/realtek.c
@@ -0,0 +1,154 @@
+/*
+ * Realtek RTL8201 PHY Driver for TI DaVinci (TMS320DM635) based boards.
+ *
+ * Copyright (C) 2011 Brilliantov Kirill Vladimirovich 
<brilliantov at byterg.ru>
+ * References: Realtek Single Chip Single Port 10/100M
+ *              Fast Ethernet Phyceiver RTL8201BL,
+ *              Rev. 1.2, 2002-03-29
+ *
+ * --------------------------------------------------------
+ *
+ * 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("Realtek: " f "\n", ##a);\
+    } while (0)
+#define ERR(f, a...)   printf("Realtek: %s" f "\n", __func__, ##a)
+
+#define LINK_DOWN       (0 << 2)
+
+int rtl8201_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 == 0x0) && (id2 == 0x8201))
+               return (1);
+
+       ERR("ID1 or ID2 not corrected");
+
+       return (0);
+}
+
+int rtl8201_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 rtl8201_init_phy(int phy_addr)
+{
+       int ret = 1;
+
+       DBG("starting %s", __func__);
+
+       if (!rtl8201_get_link_speed(phy_addr))
+               ret = rtl8201_get_link_speed(phy_addr);
+
+       return (ret);
+}
+
+int rtl8201_auto_negotiate(int phy_addr)
+{
+       u_int16_t tmp;
+
+       DBG("starting %s", __func__);
+
+       if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) {
+               ERR("can't read PHY_BMCR register %#x", PHY_BMCR);
+               return (0);
+       }
+
+       DBG("set auto negotiation mode\n");
+       davinci_eth_phy_write(phy_addr, PHY_BMCR, tmp | PHY_BMCR_AUTON);
+
+       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 (rtl8201_get_link_speed(phy_addr));
+}
+
+#endif /* CONFIG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_ETHER */
diff --git a/include/asm-arm/arch-davinci/emac_defs.h 
b/include/asm-arm/arch-davinci/emac_defs.h
index 312d8ac..fafbce4 100644
--- a/include/asm-arm/arch-davinci/emac_defs.h
+++ b/include/asm-arm/arch-davinci/emac_defs.h
@@ -52,12 +52,12 @@

  #ifdef CFG_DM6467_EVM
  /* MDIO module input frequency */
-#define EMAC_MDIO_BUS_FREQ             76500000
+#define EMAC_MDIO_BUS_FREQ             76500000
  /* MDIO clock output frequency */
  #define EMAC_MDIO_CLOCK_FREQ           2500000         /* 2.5 MHz */
  #elif defined(CFG_DM365_EVM) || defined(CFG_DM365_IPNC) || 
defined(CFG_DM368_IPNC)
  /* MDIO module input frequency */
-#define EMAC_MDIO_BUS_FREQ             121500000
+#define EMAC_MDIO_BUS_FREQ             121500000
  /* MDIO clock output frequency */
  #define EMAC_MDIO_CLOCK_FREQ           2200000         /* 2.2 MHz */
  #else
@@ -343,4 +343,10 @@ int dp83848_get_link_speed(int phy_addr);
  int dp83848_init_phy(int phy_addr);
  int dp83848_auto_negotiate(int phy_addr);

+#define PHY_RTL8201 (0x8201)
+int rtl8201_is_phy_connected(int phy_addr);
+int rtl8201_get_link_speed(int phy_addr);
+int rtl8201_init_phy(int phy_addr);
+int rtl8201_auto_negotiate(int phy_addr);
+
  #endif  /* _DM644X_EMAC_H_ */
-- 



-- 
С уважением,
Бриллиантов Кирилл Владимирович
…………………………………………………………………
программист, технический отдел
ООО «БайтЭрг»
Видеокамеры МВК – Эффективность разумных решений
…………………………………………………………………
+7(495)221-66-22
http://www.byterg.ru    http://www.bestdvr.ru


More information about the U-Boot mailing list