Add Realtek RTL8201BL PHY support, tested on U-Boot 1.3.4. Signed-off-by: Brilliantov Kirill Vladimirovich <brillian...@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 <brillian...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot