public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
@ 2007-08-07 21:11 ksi at koi8.net
  2007-08-08 15:57 ` Dirk Behme
  0 siblings, 1 reply; 10+ messages in thread
From: ksi at koi8.net @ 2007-08-07 21:11 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Sergey Kubushyn <ksi@koi8.net>

diff -purN u-boot.git.orig/common/cmd_nvedit.c u-boot.git/common/cmd_nvedit.c
--- u-boot.git.orig/common/cmd_nvedit.c	2007-08-06 18:05:59.000000000 -0700
+++ u-boot.git/common/cmd_nvedit.c	2007-08-07 10:15:34.000000000 -0700
@@ -193,7 +193,12 @@ int _do_setenv (int flag, int argc, char
  		 * Ethernet Address and serial# can be set only once,
  		 * ver is readonly.
  		 */
+#ifdef CONFIG_HAS_UID
+		/* Allow serial# forced overwrite with 0xdeaf4add flag */
+		if ( ((strcmp (name, "serial#") == 0) && (flag != 0xdeaf4add)) ||
+#else
  		if ( (strcmp (name, "serial#") == 0) ||
+#endif
  		    ((strcmp (name, "ethaddr") == 0)
  #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
  		     && (strcmp ((char *)env_get_addr(oldval),MK_STR(CONFIG_ETHADDR)) != 0)
@@ -397,7 +402,15 @@ void setenv (char *varname, char *varval
  		_do_setenv (0, 3, argv);
  }

-int do_setenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+#ifdef CONFIG_HAS_UID
+void forceenv (char *varname, char *varvalue)
+{
+	char *argv[4] = { "forceenv", varname, varvalue, NULL };
+	_do_setenv (0xdeaf4add, 3, argv);
+}
+#endif
+
+int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  {
  	if (argc < 2) {
  		printf ("Usage:\n%s\n", cmdtp->usage);
diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/dp83848.c u-boot.git/cpu/arm926ejs/davinci/dp83848.c
--- u-boot.git.orig/cpu/arm926ejs/davinci/dp83848.c	1969-12-31 16:00:00.000000000 -0800
+++ u-boot.git/cpu/arm926ejs/davinci/dp83848.c	2007-08-07 10:22:28.000000000 -0700
@@ -0,0 +1,156 @@
+/*
+ * National Semiconductor DP83848 PHY Driver for TI DaVinci
+ * (TMS320DM644x) based boards.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * --------------------------------------------------------
+ *
+ * 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 <dp83848.h>
+#include <asm/arch/emac_defs.h>
+
+#ifdef CONFIG_DRIVER_TI_EMAC
+
+#ifdef CONFIG_CMD_NET
+
+int dp83848_is_phy_connected(int phy_addr)
+{
+	u_int16_t	id1, id2;
+
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1))
+		return(0);
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2))
+		return(0);
+
+	if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI))
+		return(1);
+
+	return(0);
+}
+
+int dp83848_get_link_speed(int phy_addr)
+{
+	u_int16_t		tmp;
+	volatile emac_regs*	emac = (emac_regs *)EMAC_BASE_ADDR;
+
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
+		return(0);
+
+	if (!(tmp & DP83848_LINK_STATUS))	/* link up? */
+		return(0);
+
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp))
+		return(0);
+
+	/* Speed doesn't matter, there is no setting for it in EMAC... */
+	if (tmp & DP83848_SPEED) {
+		if (tmp & DP83848_DUPLEX) {
+			/* set DM644x EMAC for Full Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+		} else {
+			/*set DM644x EMAC for Half Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
+		}
+
+		return(1);
+	} else {
+		if (tmp & DP83848_DUPLEX) {
+			/* set DM644x EMAC for Full Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+		} else {
+			/*set DM644x EMAC for Half Duplex  */
+			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
+		}
+
+		return(1);
+	}
+
+	return(0);
+}
+
+
+int dp83848_init_phy(int phy_addr)
+{
+	int	ret = 1;
+
+	if (!dp83848_get_link_speed(phy_addr)) {
+		/* Try another time */
+		udelay(100000);
+		ret = dp83848_get_link_speed(phy_addr);
+	}
+
+	/* Disable PHY Interrupts */
+	dm644x_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0);
+
+	return(ret);
+}
+
+
+int dp83848_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
+		return(0);
+
+	/* Restart Auto_negotiation  */
+	tmp &= ~DP83848_AUTONEG;	/* remove autonegotiation enable */
+	tmp |= DP83848_ISOLATE;		/* Electrically isolate PHY */
+	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
+
+	/* Set the Auto_negotiation Advertisement Register
+	 * MII advertising for Next page, 100BaseTxFD and HD,
+	 * 10BaseTFD and HD, IEEE 802.3
+	 */
+	tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX |
+	 	DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3;
+	dm644x_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp);
+
+
+	/* Read Control Register */
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
+		return(0);
+
+	tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE;
+	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
+
+	/* Restart Auto_negotiation  */
+	tmp |= DP83848_RESTART_AUTONEG;
+	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay(10000);
+	if (!dm644x_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
+		return(0);
+
+	if (!(tmp & DP83848_AUTONEG_COMP))
+		return(0);
+
+	return (dp83848_get_link_speed(phy_addr));
+}
+
+#endif	/* CONFIG_CMD_NET */
+
+#endif	/* CONFIG_DRIVER_ETHER */
diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/ether.c u-boot.git/cpu/arm926ejs/davinci/ether.c
--- u-boot.git.orig/cpu/arm926ejs/davinci/ether.c	1969-12-31 16:00:00.000000000 -0800
+++ u-boot.git/cpu/arm926ejs/davinci/ether.c	2007-08-07 10:23:13.000000000 -0700
@@ -0,0 +1,652 @@
+/*
+ * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
+ * follows:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.c
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+
+ * Modifications:
+ * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
+ * ver  1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
+ *
+ */
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <miiphy.h>
+#include <asm/arch/emac_defs.h>
+
+#ifdef CONFIG_DRIVER_TI_EMAC
+
+#ifdef CONFIG_CMD_NET
+
+unsigned int	emac_dbg = 0;
+#define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)
+
+/* Internal static functions */
+static int dm644x_eth_hw_init (void);
+static int dm644x_eth_open (void);
+static int dm644x_eth_close (void);
+static int dm644x_eth_send_packet (volatile void *packet, int length);
+static int dm644x_eth_rcv_packet (void);
+static void dm644x_eth_mdio_enable(void);
+
+static int gen_init_phy(int phy_addr);
+static int gen_is_phy_connected(int phy_addr);
+static int gen_get_link_speed(int phy_addr);
+static int gen_auto_negotiate(int phy_addr);
+
+/* Wrappers exported to the U-Boot proper */
+int eth_hw_init(void)
+{
+	return(dm644x_eth_hw_init());
+}
+
+int eth_init(bd_t * bd)
+{
+	return(dm644x_eth_open());
+}
+
+void eth_halt(void)
+{
+	dm644x_eth_close();
+}
+
+int eth_send(volatile void *packet, int length)
+{
+	return(dm644x_eth_send_packet(packet, length));
+}
+
+int eth_rx(void)
+{
+	return(dm644x_eth_rcv_packet());
+}
+
+void eth_mdio_enable(void)
+{
+	dm644x_eth_mdio_enable();
+}
+/* End of wrappers */
+
+
+static u_int8_t dm644x_eth_mac_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+/*
+ * This function must be called before emac_open() if you want to override
+ * the default mac address.
+ */
+void dm644x_eth_set_mac_addr(const u_int8_t *addr)
+{
+	int i;
+
+	for (i = 0; i < sizeof (dm644x_eth_mac_addr); i++) {
+		dm644x_eth_mac_addr[i] = addr[i];
+	}
+}
+
+/* EMAC Addresses */
+static volatile emac_regs	*adap_emac = (emac_regs *)EMAC_BASE_ADDR;
+static volatile ewrap_regs	*adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
+static volatile mdio_regs	*adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;
+
+/* EMAC descriptors */
+static volatile emac_desc	*emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
+static volatile emac_desc	*emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
+static volatile emac_desc	*emac_rx_active_head = 0;
+static volatile emac_desc	*emac_rx_active_tail = 0;
+static int			emac_rx_queue_active = 0;
+
+/* Receive packet buffers */
+static unsigned char		emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
+
+/* PHY address for a discovered PHY (0xff - not found) */
+static volatile u_int8_t	active_phy_addr = 0xff;
+
+phy_t				phy;
+
+static void dm644x_eth_mdio_enable(void)
+{
+	u_int32_t	clkdiv;
+
+	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+
+	adap_mdio->CONTROL = (clkdiv & 0xff) |
+		MDIO_CONTROL_ENABLE |
+		MDIO_CONTROL_FAULT |
+		MDIO_CONTROL_FAULT_ENABLE;
+
+	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
+}
+
+/*
+ * Tries to find an active connected PHY. Returns 1 if address if found.
+ * If no active PHY (or more than one PHY) found returns 0.
+ * Sets active_phy_addr variable.
+ */
+static int dm644x_eth_phy_detect(void)
+{
+	u_int32_t	phy_act_state;
+	int		i;
+
+	active_phy_addr = 0xff;
+
+	if ((phy_act_state = adap_mdio->ALIVE) == 0)
+		return(0);				/* No active PHYs */
+
+	debug_emac("dm644x_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
+
+	for (i = 0; i < 32; i++) {
+		if (phy_act_state & (1 << i)) {
+			if (phy_act_state & ~(1 << i))
+				return(0);		/* More than one PHY */
+			else {
+				active_phy_addr = i;
+				return(1);
+			}
+		}
+	}
+
+	return(0);	/* Just to make GCC happy */
+}
+
+
+/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
+int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+{
+	int	tmp;
+
+	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+				MDIO_USERACCESS0_WRITE_READ |
+				((reg_num & 0x1f) << 21) |
+				((phy_addr & 0x1f) << 16);
+
+	/* Wait for command to complete */
+	while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;}
+
+	if (tmp & MDIO_USERACCESS0_ACK) {
+		*data = tmp & 0xffff;
+		return(1);
+	}
+
+	*data = -1;
+	return(0);
+}
+
+/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
+int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+{
+
+	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+				MDIO_USERACCESS0_WRITE_WRITE |
+				((reg_num & 0x1f) << 21) |
+				((phy_addr & 0x1f) << 16) |
+				(data & 0xffff);
+
+	/* Wait for command to complete */
+	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+
+	return(1);
+}
+
+/* PHY functions for a generic PHY */
+static int gen_init_phy(int phy_addr)
+{
+	int	ret = 1;
+
+	if (gen_get_link_speed(phy_addr)) {
+		/* Try another time */
+		ret = gen_get_link_speed(phy_addr);
+	}
+
+	return(ret);
+}
+
+static int gen_is_phy_connected(int phy_addr)
+{
+	u_int16_t	dummy;
+
+	return(dm644x_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy));
+}
+
+static int gen_get_link_speed(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if (dm644x_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04))
+		return(1);
+
+	return(0);
+}
+
+static int gen_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+
+	if (!dm644x_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
+		return(0);
+
+	/* Restart Auto_negotiation  */
+	tmp |= PHY_BMCR_AUTON;
+	dm644x_eth_phy_write(phy_addr, PHY_BMCR, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay (10000);
+	if (!dm644x_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
+		return(0);
+
+	if (!(tmp & PHY_BMSR_AUTN_COMP))
+		return(0);
+
+	return(gen_get_link_speed(phy_addr));
+}
+/* End of generic PHY functions */
+
+
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+static int dm644x_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
+{
+	return(dm644x_eth_phy_read(addr, reg, value) ? 0 : 1);
+}
+
+static int dm644x_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
+{
+	return(dm644x_eth_phy_write(addr, reg, value) ? 0 : 1);
+}
+
+int dm644x_eth_miiphy_initialize(bd_t *bis)
+{
+	miiphy_register(phy.name, dm644x_mii_phy_read, dm644x_mii_phy_write);
+
+	return(1);
+}
+#endif
+
+/*
+ * This function initializes the emac hardware. It does NOT initialize
+ * EMAC modules power or pin multiplexors, that is done by board_init()
+ * much earlier in bootup process. Returns 1 on success, 0 otherwise.
+ */
+static int dm644x_eth_hw_init(void)
+{
+	u_int32_t	phy_id;
+	u_int16_t	tmp;
+	int		i;
+
+	dm644x_eth_mdio_enable();
+
+	for (i = 0; i < 256; i++) {
+		if (adap_mdio->ALIVE)
+			break;
+		udelay(10);
+	}
+
+	if (i >= 256) {
+		printf("No ETH PHY detected!!!\n");
+		return(0);
+	}
+
+	/* Find if a PHY is connected and get it's address */
+	if (!dm644x_eth_phy_detect())
+		return(0);
+
+	/* Get PHY ID and initialize phy_ops for a detected PHY */
+	if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) {
+		active_phy_addr = 0xff;
+		return(0);
+	}
+
+	phy_id = (tmp << 16) & 0xffff0000;
+
+	if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) {
+		active_phy_addr = 0xff;
+		return(0);
+	}
+
+	phy_id |= tmp & 0x0000ffff;
+
+	switch (phy_id) {
+		case PHY_LXT972:
+			sprintf(phy.name, "LXT972 @ 0x%02x", active_phy_addr);
+			phy.init = lxt972_init_phy;
+			phy.is_phy_connected = lxt972_is_phy_connected;
+			phy.get_link_speed = lxt972_get_link_speed;
+			phy.auto_negotiate = lxt972_auto_negotiate;
+			break;
+		case PHY_DP83848:
+			sprintf(phy.name, "DP83848 @ 0x%02x", active_phy_addr);
+			phy.init = dp83848_init_phy;
+			phy.is_phy_connected = dp83848_is_phy_connected;
+			phy.get_link_speed = dp83848_get_link_speed;
+			phy.auto_negotiate = dp83848_auto_negotiate;
+			break;
+		default:
+			sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
+			phy.init = gen_init_phy;
+			phy.is_phy_connected = gen_is_phy_connected;
+			phy.get_link_speed = gen_get_link_speed;
+			phy.auto_negotiate = gen_auto_negotiate;
+	}
+
+	return(1);
+}
+
+
+/* Eth device open */
+static int dm644x_eth_open(void)
+{
+	dv_reg_p		addr;
+	u_int32_t		clkdiv, cnt;
+	volatile emac_desc	*rx_desc;
+
+	debug_emac("+ emac_open\n");
+
+	/* Reset EMAC module and disable interrupts in wrapper */
+	adap_emac->SOFTRESET = 1;
+	while (adap_emac->SOFTRESET != 0) {;}
+	adap_ewrap->EWCTL = 0;
+	for (cnt = 0; cnt < 5; cnt++) {
+		clkdiv = adap_ewrap->EWCTL;
+	}
+
+	rx_desc = emac_rx_desc;
+
+	adap_emac->TXCONTROL = 0x01;
+	adap_emac->RXCONTROL = 0x01;
+
+	/* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
+	/* Using channel 0 only - other channels are disabled */
+	adap_emac->MACINDEX = 0;
+	adap_emac->MACADDRHI =
+		(dm644x_eth_mac_addr[3] << 24) |
+		(dm644x_eth_mac_addr[2] << 16) |
+		(dm644x_eth_mac_addr[1] << 8)  |
+		(dm644x_eth_mac_addr[0]);
+	adap_emac->MACADDRLO =
+		(dm644x_eth_mac_addr[5] << 8) |
+		(dm644x_eth_mac_addr[4]);
+
+	adap_emac->MACHASH1 = 0;
+	adap_emac->MACHASH2 = 0;
+
+	/* Set source MAC address - REQUIRED */
+	adap_emac->MACSRCADDRHI =
+		(dm644x_eth_mac_addr[3] << 24) |
+		(dm644x_eth_mac_addr[2] << 16) |
+		(dm644x_eth_mac_addr[1] << 8)  |
+		(dm644x_eth_mac_addr[0]);
+	adap_emac->MACSRCADDRLO =
+		(dm644x_eth_mac_addr[4] << 8) |
+		(dm644x_eth_mac_addr[5]);
+
+	/* Set DMA 8 TX / 8 RX Head pointers to 0 */
+	addr = &adap_emac->TX0HDP;
+	for(cnt = 0; cnt < 16; cnt++)
+		*addr++ = 0;
+
+	addr = &adap_emac->RX0HDP;
+	for(cnt = 0; cnt < 16; cnt++)
+		*addr++ = 0;
+
+	/* Clear Statistics (do this before setting MacControl register) */
+	addr = &adap_emac->RXGOODFRAMES;
+	for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
+		*addr++ = 0;
+
+	/* No multicast addressing */
+	adap_emac->MACHASH1 = 0;
+	adap_emac->MACHASH2 = 0;
+
+	/* Create RX queue and set receive process in place */
+	emac_rx_active_head = emac_rx_desc;
+	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
+		rx_desc->next = (u_int32_t)(rx_desc + 1);
+		rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
+		rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
+		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
+		rx_desc++;
+	}
+
+	/* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
+	rx_desc--;
+	rx_desc->next = 0;
+	emac_rx_active_tail = rx_desc;
+	emac_rx_queue_active = 1;
+
+	/* Enable TX/RX */
+	adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
+	adap_emac->RXBUFFEROFFSET = 0;
+
+	/* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
+	adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;
+
+	/* Enable ch 0 only */
+	adap_emac->RXUNICASTSET = 0x01;
+
+	/* Enable MII interface and Full duplex mode */
+	adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE);
+
+	/* Init MDIO & get link state */
+	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
+
+	if (!phy.get_link_speed(active_phy_addr))
+		return(0);
+
+	/* Start receive process */
+	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
+
+	debug_emac("- emac_open\n");
+
+	return(1);
+}
+
+/* EMAC Channel Teardown */
+static void dm644x_eth_ch_teardown(int ch)
+{
+	dv_reg		dly = 0xff;
+	dv_reg		cnt;
+
+	debug_emac("+ emac_ch_teardown\n");
+
+	if (ch == EMAC_CH_TX) {
+		/* Init TX channel teardown */
+		adap_emac->TXTEARDOWN = 1;
+		for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) {
+			/* Wait here for Tx teardown completion interrupt to occur
+			 * Note: A task delay can be called here to pend rather than
+			 * occupying CPU cycles - anyway it has been found that teardown
+			 * takes very few cpu cycles and does not affect functionality */
+			 dly--;
+			 udelay(1);
+			 if (dly == 0)
+			 	break;
+		}
+		adap_emac->TX0CP = cnt;
+		adap_emac->TX0HDP = 0;
+	} else {
+		/* Init RX channel teardown */
+		adap_emac->RXTEARDOWN = 1;
+		for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) {
+			/* Wait here for Rx teardown completion interrupt to occur
+			 * Note: A task delay can be called here to pend rather than
+			 * occupying CPU cycles - anyway it has been found that teardown
+			 * takes very few cpu cycles and does not affect functionality */
+			 dly--;
+			 udelay(1);
+			 if (dly == 0)
+			 	break;
+		}
+		adap_emac->RX0CP = cnt;
+		adap_emac->RX0HDP = 0;
+	}
+
+	debug_emac("- emac_ch_teardown\n");
+}
+
+/* Eth device close */
+static int dm644x_eth_close(void)
+{
+	debug_emac("+ emac_close\n");
+
+	dm644x_eth_ch_teardown(EMAC_CH_TX);	/* TX Channel teardown */
+	dm644x_eth_ch_teardown(EMAC_CH_RX);	/* RX Channel teardown */
+
+	/* Reset EMAC module and disable interrupts in wrapper */
+	adap_emac->SOFTRESET = 1;
+	adap_ewrap->EWCTL = 0;
+
+	debug_emac("- emac_close\n");
+	return(1);
+}
+
+static int tx_send_loop = 0;
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int dm644x_eth_send_packet(volatile void *packet, int length)
+{
+	int ret_status = -1;
+	tx_send_loop = 0;
+
+	/* Return error if no link */
+	if (!phy.get_link_speed(active_phy_addr))
+	{
+		printf("WARN: emac_send_packet: No link\n");
+		return (ret_status);
+	}
+
+	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
+	if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
+	{
+		length = EMAC_MIN_ETHERNET_PKT_SIZE;
+	}
+
+	/* Populate the TX descriptor */
+	emac_tx_desc->next         = 0;
+	emac_tx_desc->buffer       = (u_int8_t *)packet;
+	emac_tx_desc->buff_off_len = (length & 0xffff);
+	emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
+			EMAC_CPPI_SOP_BIT |
+			EMAC_CPPI_OWNERSHIP_BIT |
+			EMAC_CPPI_EOP_BIT);
+	/* Send the packet */
+	adap_emac->TX0HDP = (unsigned int)emac_tx_desc;
+
+	/* Wait for packet to complete or link down */
+	while (1) {
+	        if (!phy.get_link_speed(active_phy_addr)) {
+	        	dm644x_eth_ch_teardown(EMAC_CH_TX);
+	        	return (ret_status);
+	        }
+	        if (adap_emac->TXINTSTATRAW & 0x01) {
+	        	ret_status = length;
+	        	break;
+		}
+	        tx_send_loop++;
+	}
+
+	return(ret_status);
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int dm644x_eth_rcv_packet(void)
+{
+	volatile emac_desc	*rx_curr_desc;
+	volatile emac_desc	*curr_desc;
+	volatile emac_desc	*tail_desc;
+	int			status, ret = -1;
+
+	rx_curr_desc = emac_rx_active_head;
+	status = rx_curr_desc->pkt_flag_len;
+	if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
+	        if (status & EMAC_CPPI_RX_ERROR_FRAME) {
+	        	/* Error in packet - discard it and requeue desc */
+	        	printf("WARN: emac_rcv_pkt: Error in packet\n");
+		} else {
+			NetReceive(rx_curr_desc->buffer, (rx_curr_desc->buff_off_len & 0xffff));
+			ret = rx_curr_desc->buff_off_len & 0xffff;
+	        }
+
+	        /* Ack received packet descriptor */
+	        adap_emac->RX0CP = (unsigned int)rx_curr_desc;
+	        curr_desc = rx_curr_desc;
+	        emac_rx_active_head = (volatile emac_desc *)rx_curr_desc->next;
+
+	        if (status & EMAC_CPPI_EOQ_BIT) {
+	        	if (emac_rx_active_head) {
+	        		adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
+			} else {
+				emac_rx_queue_active = 0;
+				printf("INFO:emac_rcv_packet: RX Queue not active\n");
+			}
+		}
+
+		/* Recycle RX descriptor */
+		rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
+		rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
+		rx_curr_desc->next = 0;
+
+		if (emac_rx_active_head == 0) {
+			printf("INFO: emac_rcv_pkt: active queue head = 0\n");
+			emac_rx_active_head = curr_desc;
+			emac_rx_active_tail = curr_desc;
+			if (emac_rx_queue_active != 0) {
+				adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
+				printf("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
+				emac_rx_queue_active = 1;
+			}
+		} else {
+			tail_desc = emac_rx_active_tail;
+			emac_rx_active_tail = curr_desc;
+			tail_desc->next = (unsigned int)curr_desc;
+			status = tail_desc->pkt_flag_len;
+			if (status & EMAC_CPPI_EOQ_BIT) {
+				adap_emac->RX0HDP = (unsigned int)curr_desc;
+				status &= ~EMAC_CPPI_EOQ_BIT;
+				tail_desc->pkt_flag_len = status;
+			}
+		}
+		return(ret);
+	}
+	return(0);
+}
+
+#endif /* CONFIG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_TI_EMAC */
diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/i2c.c u-boot.git/cpu/arm926ejs/davinci/i2c.c
--- u-boot.git.orig/cpu/arm926ejs/davinci/i2c.c	1969-12-31 16:00:00.000000000 -0800
+++ u-boot.git/cpu/arm926ejs/davinci/i2c.c	2007-08-07 10:15:34.000000000 -0700
@@ -0,0 +1,351 @@
+/*
+ * TI DaVinci (TMS320DM644x) I2C driver.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * --------------------------------------------------------
+ *
+ * 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>
+
+#ifdef CONFIG_DRIVER_DAVINCI_I2C
+
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/i2c_defs.h>
+
+#define CHECK_NACK() \
+	do {\
+		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
+			REG(I2C_CON) = 0;\
+			return(1);\
+		}\
+	} while (0)
+
+
+static int wait_for_bus(void)
+{
+	int	stat, timeout;
+
+	REG(I2C_STAT) = 0xffff;
+
+	for (timeout = 0; timeout < 10; timeout++) {
+		if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
+			REG(I2C_STAT) = 0xffff;
+			return(0);
+		}
+
+		REG(I2C_STAT) = stat;
+		udelay(50000);
+	}
+
+	REG(I2C_STAT) = 0xffff;
+	return(1);
+}
+
+
+static int poll_i2c_irq(int mask)
+{
+	int	stat, timeout;
+
+	for (timeout = 0; timeout < 10; timeout++) {
+		udelay(1000);
+		stat = REG(I2C_STAT);
+		if (stat & mask) {
+			return(stat);
+		}
+	}
+
+	REG(I2C_STAT) = 0xffff;
+	return(stat | I2C_TIMEOUT);
+}
+
+
+void flush_rx(void)
+{
+	int	dummy;
+
+	while (1) {
+		if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
+			break;
+
+		dummy = REG(I2C_DRR);
+		REG(I2C_STAT) = I2C_STAT_RRDY;
+		udelay(1000);
+	}
+}
+
+
+void i2c_init(int speed, int slaveadd)
+{
+	u_int32_t	div, psc;
+
+	if (REG(I2C_CON) & I2C_CON_EN) {
+		REG(I2C_CON) = 0;
+		udelay (50000);
+	}
+
+	psc = 2;
+	div = (CFG_HZ_CLOCK / ((psc + 1) * speed)) - 10;	/* SCLL + SCLH */
+	REG(I2C_PSC) = psc;			/* 27MHz / (2 + 1) = 9MHz */
+	REG(I2C_SCLL) = (div * 50) / 100;	/* 50% Duty */
+	REG(I2C_SCLH) = div - REG(I2C_SCLL);
+
+	REG(I2C_OA) = slaveadd;
+	REG(I2C_CNT) = 0;
+
+	/* Interrupts must be enabled or I2C module won't work */
+	REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
+
+	/* Now enable I2C controller (get it out of reset) */
+	REG(I2C_CON) = I2C_CON_EN;
+
+	udelay(1000);
+}
+
+
+int i2c_probe(u_int8_t chip)
+{
+	int	rc = 1;
+
+	if (chip == REG(I2C_OA)) {
+		return(rc);
+	}
+
+	REG(I2C_CON) = 0;
+	if (wait_for_bus()) {return(1);}
+
+	/* try to read one byte from current (or only) address */
+	REG(I2C_CNT) = 1;
+	REG(I2C_SA) = chip;
+	REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP);
+	udelay (50000);
+
+	if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
+		rc = 0;
+		flush_rx();
+		REG(I2C_STAT) = 0xffff;
+	} else {
+		REG(I2C_STAT) = 0xffff;
+		REG(I2C_CON) |= I2C_CON_STP;
+		udelay(20000);
+		if (wait_for_bus()) {return(1);}
+	}
+
+	flush_rx();
+	REG(I2C_STAT) = 0xffff;
+	REG(I2C_CNT) = 0;
+	return(rc);
+}
+
+
+int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+	u_int32_t	tmp;
+	int		i;
+
+	if ((alen < 0) || (alen > 2)) {
+		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
+		return(1);
+	}
+
+	if (wait_for_bus()) {return(1);}
+
+	if (alen != 0) {
+		/* Start address phase */
+		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
+		REG(I2C_CNT) = alen;
+		REG(I2C_SA) = chip;
+		REG(I2C_CON) = tmp;
+
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		switch (alen) {
+			case 2:
+				/* Send address MSByte */
+				if (tmp & I2C_STAT_XRDY) {
+					REG(I2C_DXR) = (addr >> 8) & 0xff;
+				} else {
+					REG(I2C_CON) = 0;
+					return(1);
+				}
+
+				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+				CHECK_NACK();
+				/* No break, fall through */
+			case 1:
+				/* Send address LSByte */
+				if (tmp & I2C_STAT_XRDY) {
+					REG(I2C_DXR) = addr & 0xff;
+				} else {
+					REG(I2C_CON) = 0;
+					return(1);
+				}
+
+				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
+
+				CHECK_NACK();
+
+				if (!(tmp & I2C_STAT_ARDY)) {
+					REG(I2C_CON) = 0;
+					return(1);
+				}
+		}
+	}
+
+	/* Address phase is over, now read 'len' bytes and stop */
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
+	REG(I2C_CNT) = len & 0xffff;
+	REG(I2C_SA) = chip;
+	REG(I2C_CON) = tmp;
+
+	for (i = 0; i < len; i++) {
+		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_RRDY) {
+			buf[i] = REG(I2C_DRR);
+		} else {
+			REG(I2C_CON) = 0;
+			return(1);
+		}
+	}
+
+	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+	CHECK_NACK();
+
+	if (!(tmp & I2C_STAT_SCD)) {
+		REG(I2C_CON) = 0;
+		return(1);
+	}
+
+	flush_rx();
+	REG(I2C_STAT) = 0xffff;
+	REG(I2C_CNT) = 0;
+	REG(I2C_CON) = 0;
+
+	return(0);
+}
+
+
+int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+	u_int32_t	tmp;
+	int		i;
+
+	if ((alen < 0) || (alen > 2)) {
+		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
+		return(1);
+	}
+	if (len < 0) {
+		printf("%s(): bogus length %x\n", __FUNCTION__, len);
+		return(1);
+	}
+
+	if (wait_for_bus()) {return(1);}
+
+	/* Start address phase */
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
+	REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
+	REG(I2C_SA) = chip;
+	REG(I2C_CON) = tmp;
+
+	switch (alen) {
+		case 2:
+			/* Send address MSByte */
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+			CHECK_NACK();
+
+			if (tmp & I2C_STAT_XRDY) {
+				REG(I2C_DXR) = (addr >> 8) & 0xff;
+			} else {
+				REG(I2C_CON) = 0;
+				return(1);
+			}
+			/* No break, fall through */
+		case 1:
+			/* Send address LSByte */
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+			CHECK_NACK();
+
+			if (tmp & I2C_STAT_XRDY) {
+				REG(I2C_DXR) = addr & 0xff;
+			} else {
+				REG(I2C_CON) = 0;
+				return(1);
+			}
+	}
+
+	for (i = 0; i < len; i++) {
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_XRDY) {
+			REG(I2C_DXR) = buf[i];
+		} else {
+			return(1);
+		}
+	}
+
+	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+	CHECK_NACK();
+
+	if (!(tmp & I2C_STAT_SCD)) {
+		REG(I2C_CON) = 0;
+		return(1);
+	}
+
+	flush_rx();
+	REG(I2C_STAT) = 0xffff;
+	REG(I2C_CNT) = 0;
+	REG(I2C_CON) = 0;
+
+	return(0);
+}
+
+
+u_int8_t i2c_reg_read(u_int8_t chip, u_int8_t reg)
+{
+	u_int8_t	tmp;
+
+	i2c_read(chip, reg, 1, &tmp, 1);
+	return(tmp);
+}
+
+
+void i2c_reg_write(u_int8_t chip, u_int8_t reg, u_int8_t val)
+{
+	u_int8_t	tmp;
+
+	i2c_write(chip, reg, 1, &tmp, 1);
+}
+
+#endif /* CONFIG_DRIVER_DAVINCI_I2C */
diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/Makefile u-boot.git/cpu/arm926ejs/davinci/Makefile
--- u-boot.git.orig/cpu/arm926ejs/davinci/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ u-boot.git/cpu/arm926ejs/davinci/Makefile	2007-08-07 10:15:34.000000000 -0700
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).a
+
+COBJS	= timer.o ether.o lxt972.o dp83848.o i2c.o nand.o
+SOBJS	= lowlevel_init.o reset.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff -purN u-boot.git.orig/CREDITS u-boot.git/CREDITS
--- u-boot.git.orig/CREDITS	2007-04-04 12:28:34.000000000 -0700
+++ u-boot.git/CREDITS	2007-08-07 10:15:34.000000000 -0700
@@ -252,6 +252,10 @@ E: Raghu.Krishnaprasad at fci.com
  D: Support for Adder-II MPC852T evaluation board
  W: http://www.forcecomputers.com

+N: Sergey Kubushyn
+E: ksi at koi8.net
+D: Support for various TI DaVinci based boards.
+
  N: Bernhard Kuhn
  E: bkuhn at metrowerks.com
  D Support for Coldfire CPU; Support for Motorola M5272C3 and M5282EVB boards
diff -purN u-boot.git.orig/lib_arm/board.c u-boot.git/lib_arm/board.c
--- u-boot.git.orig/lib_arm/board.c	2007-08-06 18:05:59.000000000 -0700
+++ u-boot.git/lib_arm/board.c	2007-08-07 10:15:34.000000000 -0700
@@ -364,6 +364,13 @@ void start_armboot (void)
  	enable_interrupts ();

  	/* Perform network card initialisation if necessary */
+#ifdef CONFIG_DRIVER_TI_EMAC
+extern void dm644x_eth_set_mac_addr (const u_int8_t *addr);
+	if (getenv ("ethaddr")) {
+		dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr);
+	}
+#endif
+
  #ifdef CONFIG_DRIVER_CS8900
  	cs8900_get_enetaddr (gd->bd->bi_enetaddr);
  #endif
diff -purN u-boot.git.orig/MAINTAINERS u-boot.git/MAINTAINERS
--- u-boot.git.orig/MAINTAINERS	2007-08-04 22:07:13.000000000 -0700
+++ u-boot.git/MAINTAINERS	2007-08-07 10:15:34.000000000 -0700
@@ -444,6 +444,12 @@ Nishant Kamat <nskamat@ti.com>

  	omap1610h2		ARM926EJS

+Sergey Kubushyn <ksi@koi8.net>
+
+	DV-EVM			ARM926EJS
+	SONATA			ARM926EJS
+	SCHMOOGIE		ARM926EJS
+
  Prakash Kumar <prakash@embedx.com>

  	cerf250			xscale
diff -purN u-boot.git.orig/MAKEALL u-boot.git/MAKEALL
--- u-boot.git.orig/MAKEALL	2007-08-06 18:05:59.000000000 -0700
+++ u-boot.git/MAKEALL	2007-08-07 10:15:34.000000000 -0700
@@ -220,7 +220,8 @@ LIST_ARM9="	\
  	omap1610h2	omap1610inn	omap730p2	sbc2410x	\
  	scb9328		smdk2400	smdk2410	trab		\
  	VCMA9		versatile	versatileab	versatilepb	\
-	voiceblue							\
+	voiceblue	davinci_dvevm	davinci_schmoogie		\
+	davinci_sonata
  "

  #########################################################################
diff -purN u-boot.git.orig/Makefile u-boot.git/Makefile
--- u-boot.git.orig/Makefile	2007-08-06 18:05:59.000000000 -0700
+++ u-boot.git/Makefile	2007-08-07 10:15:34.000000000 -0700
@@ -2019,6 +2019,15 @@ omap1510inn_config :	unconfig
  omap5912osk_config :	unconfig
  	@$(MKCONFIG) $(@:_config=) arm arm926ejs omap5912osk NULL omap

+davinci_dvevm_config :	unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs dv-evm davinci davinci
+
+davinci_schmoogie_config :	unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs schmoogie davinci davinci
+
+davinci_sonata_config :	unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs sonata davinci davinci
+
  omap1610inn_config \
  omap1610inn_cs0boot_config \
  omap1610inn_cs3boot_config \
diff -purN u-boot.git.orig/net/eth.c u-boot.git/net/eth.c
--- u-boot.git.orig/net/eth.c	2007-08-06 18:05:59.000000000 -0700
+++ u-boot.git/net/eth.c	2007-08-07 10:15:34.000000000 -0700
@@ -464,6 +464,8 @@ extern int at91rm9200_miiphy_initialize(
  extern int emac4xx_miiphy_initialize(bd_t *bis);
  extern int mcf52x2_miiphy_initialize(bd_t *bis);
  extern int ns7520_miiphy_initialize(bd_t *bis);
+extern int dm644x_eth_miiphy_initialize(bd_t *bis);
+

  int eth_initialize(bd_t *bis)
  {
@@ -484,6 +486,9 @@ int eth_initialize(bd_t *bis)
  #if defined(CONFIG_NETARM)
  	ns7520_miiphy_initialize(bis);
  #endif
+#if defined(CONFIG_DRIVER_TI_EMAC)
+	dm644x_eth_miiphy_initialize(bis);
+#endif
  	return 0;
  }
  #endif

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-07 21:11 [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5] ksi at koi8.net
@ 2007-08-08 15:57 ` Dirk Behme
  2007-08-09 21:35   ` Wolfgang Denk
  2007-08-10  4:46   ` Stefan Roese
  0 siblings, 2 replies; 10+ messages in thread
From: Dirk Behme @ 2007-08-08 15:57 UTC (permalink / raw)
  To: u-boot

ksi at koi8.net wrote:
> Signed-off-by: Sergey Kubushyn <ksi@koi8.net>

Acked-by: Dirk Behme <dirk.behme@gmail.com>

> diff -purN u-boot.git.orig/common/cmd_nvedit.c u-boot.git/common/cmd_nvedit.c
> --- u-boot.git.orig/common/cmd_nvedit.c	2007-08-06 18:05:59.000000000 -0700
> +++ u-boot.git/common/cmd_nvedit.c	2007-08-07 10:15:34.000000000 -0700
> @@ -193,7 +193,12 @@ int _do_setenv (int flag, int argc, char
>   		 * Ethernet Address and serial# can be set only once,
>   		 * ver is readonly.
>   		 */
> +#ifdef CONFIG_HAS_UID
> +		/* Allow serial# forced overwrite with 0xdeaf4add flag */
> +		if ( ((strcmp (name, "serial#") == 0) && (flag != 0xdeaf4add)) ||
> +#else
>   		if ( (strcmp (name, "serial#") == 0) ||
> +#endif
>   		    ((strcmp (name, "ethaddr") == 0)
>   #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
>   		     && (strcmp ((char *)env_get_addr(oldval),MK_STR(CONFIG_ETHADDR)) != 0)
> @@ -397,7 +402,15 @@ void setenv (char *varname, char *varval
>   		_do_setenv (0, 3, argv);
>   }
> 
> -int do_setenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
> +#ifdef CONFIG_HAS_UID
> +void forceenv (char *varname, char *varvalue)
> +{
> +	char *argv[4] = { "forceenv", varname, varvalue, NULL };
> +	_do_setenv (0xdeaf4add, 3, argv);
> +}
> +#endif
> +
> +int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
>   {
>   	if (argc < 2) {
>   		printf ("Usage:\n%s\n", cmdtp->usage);
> diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/dp83848.c u-boot.git/cpu/arm926ejs/davinci/dp83848.c
> --- u-boot.git.orig/cpu/arm926ejs/davinci/dp83848.c	1969-12-31 16:00:00.000000000 -0800
> +++ u-boot.git/cpu/arm926ejs/davinci/dp83848.c	2007-08-07 10:22:28.000000000 -0700
> @@ -0,0 +1,156 @@
> +/*
> + * National Semiconductor DP83848 PHY Driver for TI DaVinci
> + * (TMS320DM644x) based boards.
> + *
> + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
> + *
> + * --------------------------------------------------------
> + *
> + * 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 <dp83848.h>
> +#include <asm/arch/emac_defs.h>
> +
> +#ifdef CONFIG_DRIVER_TI_EMAC
> +
> +#ifdef CONFIG_CMD_NET
> +
> +int dp83848_is_phy_connected(int phy_addr)
> +{
> +	u_int16_t	id1, id2;
> +
> +	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1))
> +		return(0);
> +	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2))
> +		return(0);
> +
> +	if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI))
> +		return(1);
> +
> +	return(0);
> +}
> +
> +int dp83848_get_link_speed(int phy_addr)
> +{
> +	u_int16_t		tmp;
> +	volatile emac_regs*	emac = (emac_regs *)EMAC_BASE_ADDR;
> +
> +	if (!dm644x_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
> +		return(0);
> +
> +	if (!(tmp & DP83848_LINK_STATUS))	/* link up? */
> +		return(0);
> +
> +	if (!dm644x_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp))
> +		return(0);
> +
> +	/* Speed doesn't matter, there is no setting for it in EMAC... */
> +	if (tmp & DP83848_SPEED) {
> +		if (tmp & DP83848_DUPLEX) {
> +			/* set DM644x EMAC for Full Duplex  */
> +			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
> +		} else {
> +			/*set DM644x EMAC for Half Duplex  */
> +			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
> +		}
> +
> +		return(1);
> +	} else {
> +		if (tmp & DP83848_DUPLEX) {
> +			/* set DM644x EMAC for Full Duplex  */
> +			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
> +		} else {
> +			/*set DM644x EMAC for Half Duplex  */
> +			emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
> +		}
> +
> +		return(1);
> +	}
> +
> +	return(0);
> +}
> +
> +
> +int dp83848_init_phy(int phy_addr)
> +{
> +	int	ret = 1;
> +
> +	if (!dp83848_get_link_speed(phy_addr)) {
> +		/* Try another time */
> +		udelay(100000);
> +		ret = dp83848_get_link_speed(phy_addr);
> +	}
> +
> +	/* Disable PHY Interrupts */
> +	dm644x_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0);
> +
> +	return(ret);
> +}
> +
> +
> +int dp83848_auto_negotiate(int phy_addr)
> +{
> +	u_int16_t	tmp;
> +
> +
> +	if (!dm644x_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
> +		return(0);
> +
> +	/* Restart Auto_negotiation  */
> +	tmp &= ~DP83848_AUTONEG;	/* remove autonegotiation enable */
> +	tmp |= DP83848_ISOLATE;		/* Electrically isolate PHY */
> +	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
> +
> +	/* Set the Auto_negotiation Advertisement Register
> +	 * MII advertising for Next page, 100BaseTxFD and HD,
> +	 * 10BaseTFD and HD, IEEE 802.3
> +	 */
> +	tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX |
> +	 	DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3;
> +	dm644x_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp);
> +
> +
> +	/* Read Control Register */
> +	if (!dm644x_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
> +		return(0);
> +
> +	tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE;
> +	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
> +
> +	/* Restart Auto_negotiation  */
> +	tmp |= DP83848_RESTART_AUTONEG;
> +	dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
> +
> +	/*check AutoNegotiate complete */
> +	udelay(10000);
> +	if (!dm644x_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
> +		return(0);
> +
> +	if (!(tmp & DP83848_AUTONEG_COMP))
> +		return(0);
> +
> +	return (dp83848_get_link_speed(phy_addr));
> +}
> +
> +#endif	/* CONFIG_CMD_NET */
> +
> +#endif	/* CONFIG_DRIVER_ETHER */
> diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/ether.c u-boot.git/cpu/arm926ejs/davinci/ether.c
> --- u-boot.git.orig/cpu/arm926ejs/davinci/ether.c	1969-12-31 16:00:00.000000000 -0800
> +++ u-boot.git/cpu/arm926ejs/davinci/ether.c	2007-08-07 10:23:13.000000000 -0700
> @@ -0,0 +1,652 @@
> +/*
> + * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
> + *
> + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
> + *
> + * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
> + * follows:
> + *
> + * ----------------------------------------------------------------------------
> + *
> + * dm644x_emac.c
> + *
> + * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
> + *
> + * Copyright (C) 2005 Texas Instruments.
> + *
> + * ----------------------------------------------------------------------------
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + * ----------------------------------------------------------------------------
> +
> + * Modifications:
> + * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
> + * ver  1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
> + *
> + */
> +#include <common.h>
> +#include <command.h>
> +#include <net.h>
> +#include <miiphy.h>
> +#include <asm/arch/emac_defs.h>
> +
> +#ifdef CONFIG_DRIVER_TI_EMAC
> +
> +#ifdef CONFIG_CMD_NET
> +
> +unsigned int	emac_dbg = 0;
> +#define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)
> +
> +/* Internal static functions */
> +static int dm644x_eth_hw_init (void);
> +static int dm644x_eth_open (void);
> +static int dm644x_eth_close (void);
> +static int dm644x_eth_send_packet (volatile void *packet, int length);
> +static int dm644x_eth_rcv_packet (void);
> +static void dm644x_eth_mdio_enable(void);
> +
> +static int gen_init_phy(int phy_addr);
> +static int gen_is_phy_connected(int phy_addr);
> +static int gen_get_link_speed(int phy_addr);
> +static int gen_auto_negotiate(int phy_addr);
> +
> +/* Wrappers exported to the U-Boot proper */
> +int eth_hw_init(void)
> +{
> +	return(dm644x_eth_hw_init());
> +}
> +
> +int eth_init(bd_t * bd)
> +{
> +	return(dm644x_eth_open());
> +}
> +
> +void eth_halt(void)
> +{
> +	dm644x_eth_close();
> +}
> +
> +int eth_send(volatile void *packet, int length)
> +{
> +	return(dm644x_eth_send_packet(packet, length));
> +}
> +
> +int eth_rx(void)
> +{
> +	return(dm644x_eth_rcv_packet());
> +}
> +
> +void eth_mdio_enable(void)
> +{
> +	dm644x_eth_mdio_enable();
> +}
> +/* End of wrappers */
> +
> +
> +static u_int8_t dm644x_eth_mac_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
> +
> +/*
> + * This function must be called before emac_open() if you want to override
> + * the default mac address.
> + */
> +void dm644x_eth_set_mac_addr(const u_int8_t *addr)
> +{
> +	int i;
> +
> +	for (i = 0; i < sizeof (dm644x_eth_mac_addr); i++) {
> +		dm644x_eth_mac_addr[i] = addr[i];
> +	}
> +}
> +
> +/* EMAC Addresses */
> +static volatile emac_regs	*adap_emac = (emac_regs *)EMAC_BASE_ADDR;
> +static volatile ewrap_regs	*adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
> +static volatile mdio_regs	*adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;
> +
> +/* EMAC descriptors */
> +static volatile emac_desc	*emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
> +static volatile emac_desc	*emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
> +static volatile emac_desc	*emac_rx_active_head = 0;
> +static volatile emac_desc	*emac_rx_active_tail = 0;
> +static int			emac_rx_queue_active = 0;
> +
> +/* Receive packet buffers */
> +static unsigned char		emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
> +
> +/* PHY address for a discovered PHY (0xff - not found) */
> +static volatile u_int8_t	active_phy_addr = 0xff;
> +
> +phy_t				phy;
> +
> +static void dm644x_eth_mdio_enable(void)
> +{
> +	u_int32_t	clkdiv;
> +
> +	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
> +
> +	adap_mdio->CONTROL = (clkdiv & 0xff) |
> +		MDIO_CONTROL_ENABLE |
> +		MDIO_CONTROL_FAULT |
> +		MDIO_CONTROL_FAULT_ENABLE;
> +
> +	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
> +}
> +
> +/*
> + * Tries to find an active connected PHY. Returns 1 if address if found.
> + * If no active PHY (or more than one PHY) found returns 0.
> + * Sets active_phy_addr variable.
> + */
> +static int dm644x_eth_phy_detect(void)
> +{
> +	u_int32_t	phy_act_state;
> +	int		i;
> +
> +	active_phy_addr = 0xff;
> +
> +	if ((phy_act_state = adap_mdio->ALIVE) == 0)
> +		return(0);				/* No active PHYs */
> +
> +	debug_emac("dm644x_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
> +
> +	for (i = 0; i < 32; i++) {
> +		if (phy_act_state & (1 << i)) {
> +			if (phy_act_state & ~(1 << i))
> +				return(0);		/* More than one PHY */
> +			else {
> +				active_phy_addr = i;
> +				return(1);
> +			}
> +		}
> +	}
> +
> +	return(0);	/* Just to make GCC happy */
> +}
> +
> +
> +/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
> +int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
> +{
> +	int	tmp;
> +
> +	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
> +
> +	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
> +				MDIO_USERACCESS0_WRITE_READ |
> +				((reg_num & 0x1f) << 21) |
> +				((phy_addr & 0x1f) << 16);
> +
> +	/* Wait for command to complete */
> +	while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;}
> +
> +	if (tmp & MDIO_USERACCESS0_ACK) {
> +		*data = tmp & 0xffff;
> +		return(1);
> +	}
> +
> +	*data = -1;
> +	return(0);
> +}
> +
> +/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
> +int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
> +{
> +
> +	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
> +
> +	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
> +				MDIO_USERACCESS0_WRITE_WRITE |
> +				((reg_num & 0x1f) << 21) |
> +				((phy_addr & 0x1f) << 16) |
> +				(data & 0xffff);
> +
> +	/* Wait for command to complete */
> +	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
> +
> +	return(1);
> +}
> +
> +/* PHY functions for a generic PHY */
> +static int gen_init_phy(int phy_addr)
> +{
> +	int	ret = 1;
> +
> +	if (gen_get_link_speed(phy_addr)) {
> +		/* Try another time */
> +		ret = gen_get_link_speed(phy_addr);
> +	}
> +
> +	return(ret);
> +}
> +
> +static int gen_is_phy_connected(int phy_addr)
> +{
> +	u_int16_t	dummy;
> +
> +	return(dm644x_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy));
> +}
> +
> +static int gen_get_link_speed(int phy_addr)
> +{
> +	u_int16_t	tmp;
> +
> +	if (dm644x_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04))
> +		return(1);
> +
> +	return(0);
> +}
> +
> +static int gen_auto_negotiate(int phy_addr)
> +{
> +	u_int16_t	tmp;
> +
> +
> +	if (!dm644x_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
> +		return(0);
> +
> +	/* Restart Auto_negotiation  */
> +	tmp |= PHY_BMCR_AUTON;
> +	dm644x_eth_phy_write(phy_addr, PHY_BMCR, tmp);
> +
> +	/*check AutoNegotiate complete */
> +	udelay (10000);
> +	if (!dm644x_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
> +		return(0);
> +
> +	if (!(tmp & PHY_BMSR_AUTN_COMP))
> +		return(0);
> +
> +	return(gen_get_link_speed(phy_addr));
> +}
> +/* End of generic PHY functions */
> +
> +
> +
> +#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
> +static int dm644x_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
> +{
> +	return(dm644x_eth_phy_read(addr, reg, value) ? 0 : 1);
> +}
> +
> +static int dm644x_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
> +{
> +	return(dm644x_eth_phy_write(addr, reg, value) ? 0 : 1);
> +}
> +
> +int dm644x_eth_miiphy_initialize(bd_t *bis)
> +{
> +	miiphy_register(phy.name, dm644x_mii_phy_read, dm644x_mii_phy_write);
> +
> +	return(1);
> +}
> +#endif
> +
> +/*
> + * This function initializes the emac hardware. It does NOT initialize
> + * EMAC modules power or pin multiplexors, that is done by board_init()
> + * much earlier in bootup process. Returns 1 on success, 0 otherwise.
> + */
> +static int dm644x_eth_hw_init(void)
> +{
> +	u_int32_t	phy_id;
> +	u_int16_t	tmp;
> +	int		i;
> +
> +	dm644x_eth_mdio_enable();
> +
> +	for (i = 0; i < 256; i++) {
> +		if (adap_mdio->ALIVE)
> +			break;
> +		udelay(10);
> +	}
> +
> +	if (i >= 256) {
> +		printf("No ETH PHY detected!!!\n");
> +		return(0);
> +	}
> +
> +	/* Find if a PHY is connected and get it's address */
> +	if (!dm644x_eth_phy_detect())
> +		return(0);
> +
> +	/* Get PHY ID and initialize phy_ops for a detected PHY */
> +	if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) {
> +		active_phy_addr = 0xff;
> +		return(0);
> +	}
> +
> +	phy_id = (tmp << 16) & 0xffff0000;
> +
> +	if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) {
> +		active_phy_addr = 0xff;
> +		return(0);
> +	}
> +
> +	phy_id |= tmp & 0x0000ffff;
> +
> +	switch (phy_id) {
> +		case PHY_LXT972:
> +			sprintf(phy.name, "LXT972 @ 0x%02x", active_phy_addr);
> +			phy.init = lxt972_init_phy;
> +			phy.is_phy_connected = lxt972_is_phy_connected;
> +			phy.get_link_speed = lxt972_get_link_speed;
> +			phy.auto_negotiate = lxt972_auto_negotiate;
> +			break;
> +		case PHY_DP83848:
> +			sprintf(phy.name, "DP83848 @ 0x%02x", active_phy_addr);
> +			phy.init = dp83848_init_phy;
> +			phy.is_phy_connected = dp83848_is_phy_connected;
> +			phy.get_link_speed = dp83848_get_link_speed;
> +			phy.auto_negotiate = dp83848_auto_negotiate;
> +			break;
> +		default:
> +			sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
> +			phy.init = gen_init_phy;
> +			phy.is_phy_connected = gen_is_phy_connected;
> +			phy.get_link_speed = gen_get_link_speed;
> +			phy.auto_negotiate = gen_auto_negotiate;
> +	}
> +
> +	return(1);
> +}
> +
> +
> +/* Eth device open */
> +static int dm644x_eth_open(void)
> +{
> +	dv_reg_p		addr;
> +	u_int32_t		clkdiv, cnt;
> +	volatile emac_desc	*rx_desc;
> +
> +	debug_emac("+ emac_open\n");
> +
> +	/* Reset EMAC module and disable interrupts in wrapper */
> +	adap_emac->SOFTRESET = 1;
> +	while (adap_emac->SOFTRESET != 0) {;}
> +	adap_ewrap->EWCTL = 0;
> +	for (cnt = 0; cnt < 5; cnt++) {
> +		clkdiv = adap_ewrap->EWCTL;
> +	}
> +
> +	rx_desc = emac_rx_desc;
> +
> +	adap_emac->TXCONTROL = 0x01;
> +	adap_emac->RXCONTROL = 0x01;
> +
> +	/* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
> +	/* Using channel 0 only - other channels are disabled */
> +	adap_emac->MACINDEX = 0;
> +	adap_emac->MACADDRHI =
> +		(dm644x_eth_mac_addr[3] << 24) |
> +		(dm644x_eth_mac_addr[2] << 16) |
> +		(dm644x_eth_mac_addr[1] << 8)  |
> +		(dm644x_eth_mac_addr[0]);
> +	adap_emac->MACADDRLO =
> +		(dm644x_eth_mac_addr[5] << 8) |
> +		(dm644x_eth_mac_addr[4]);
> +
> +	adap_emac->MACHASH1 = 0;
> +	adap_emac->MACHASH2 = 0;
> +
> +	/* Set source MAC address - REQUIRED */
> +	adap_emac->MACSRCADDRHI =
> +		(dm644x_eth_mac_addr[3] << 24) |
> +		(dm644x_eth_mac_addr[2] << 16) |
> +		(dm644x_eth_mac_addr[1] << 8)  |
> +		(dm644x_eth_mac_addr[0]);
> +	adap_emac->MACSRCADDRLO =
> +		(dm644x_eth_mac_addr[4] << 8) |
> +		(dm644x_eth_mac_addr[5]);
> +
> +	/* Set DMA 8 TX / 8 RX Head pointers to 0 */
> +	addr = &adap_emac->TX0HDP;
> +	for(cnt = 0; cnt < 16; cnt++)
> +		*addr++ = 0;
> +
> +	addr = &adap_emac->RX0HDP;
> +	for(cnt = 0; cnt < 16; cnt++)
> +		*addr++ = 0;
> +
> +	/* Clear Statistics (do this before setting MacControl register) */
> +	addr = &adap_emac->RXGOODFRAMES;
> +	for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
> +		*addr++ = 0;
> +
> +	/* No multicast addressing */
> +	adap_emac->MACHASH1 = 0;
> +	adap_emac->MACHASH2 = 0;
> +
> +	/* Create RX queue and set receive process in place */
> +	emac_rx_active_head = emac_rx_desc;
> +	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
> +		rx_desc->next = (u_int32_t)(rx_desc + 1);
> +		rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
> +		rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
> +		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
> +		rx_desc++;
> +	}
> +
> +	/* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
> +	rx_desc--;
> +	rx_desc->next = 0;
> +	emac_rx_active_tail = rx_desc;
> +	emac_rx_queue_active = 1;
> +
> +	/* Enable TX/RX */
> +	adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
> +	adap_emac->RXBUFFEROFFSET = 0;
> +
> +	/* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
> +	adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;
> +
> +	/* Enable ch 0 only */
> +	adap_emac->RXUNICASTSET = 0x01;
> +
> +	/* Enable MII interface and Full duplex mode */
> +	adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE);
> +
> +	/* Init MDIO & get link state */
> +	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
> +	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
> +
> +	if (!phy.get_link_speed(active_phy_addr))
> +		return(0);
> +
> +	/* Start receive process */
> +	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
> +
> +	debug_emac("- emac_open\n");
> +
> +	return(1);
> +}
> +
> +/* EMAC Channel Teardown */
> +static void dm644x_eth_ch_teardown(int ch)
> +{
> +	dv_reg		dly = 0xff;
> +	dv_reg		cnt;
> +
> +	debug_emac("+ emac_ch_teardown\n");
> +
> +	if (ch == EMAC_CH_TX) {
> +		/* Init TX channel teardown */
> +		adap_emac->TXTEARDOWN = 1;
> +		for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) {
> +			/* Wait here for Tx teardown completion interrupt to occur
> +			 * Note: A task delay can be called here to pend rather than
> +			 * occupying CPU cycles - anyway it has been found that teardown
> +			 * takes very few cpu cycles and does not affect functionality */
> +			 dly--;
> +			 udelay(1);
> +			 if (dly == 0)
> +			 	break;
> +		}
> +		adap_emac->TX0CP = cnt;
> +		adap_emac->TX0HDP = 0;
> +	} else {
> +		/* Init RX channel teardown */
> +		adap_emac->RXTEARDOWN = 1;
> +		for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) {
> +			/* Wait here for Rx teardown completion interrupt to occur
> +			 * Note: A task delay can be called here to pend rather than
> +			 * occupying CPU cycles - anyway it has been found that teardown
> +			 * takes very few cpu cycles and does not affect functionality */
> +			 dly--;
> +			 udelay(1);
> +			 if (dly == 0)
> +			 	break;
> +		}
> +		adap_emac->RX0CP = cnt;
> +		adap_emac->RX0HDP = 0;
> +	}
> +
> +	debug_emac("- emac_ch_teardown\n");
> +}
> +
> +/* Eth device close */
> +static int dm644x_eth_close(void)
> +{
> +	debug_emac("+ emac_close\n");
> +
> +	dm644x_eth_ch_teardown(EMAC_CH_TX);	/* TX Channel teardown */
> +	dm644x_eth_ch_teardown(EMAC_CH_RX);	/* RX Channel teardown */
> +
> +	/* Reset EMAC module and disable interrupts in wrapper */
> +	adap_emac->SOFTRESET = 1;
> +	adap_ewrap->EWCTL = 0;
> +
> +	debug_emac("- emac_close\n");
> +	return(1);
> +}
> +
> +static int tx_send_loop = 0;
> +
> +/*
> + * This function sends a single packet on the network and returns
> + * positive number (number of bytes transmitted) or negative for error
> + */
> +static int dm644x_eth_send_packet(volatile void *packet, int length)
> +{
> +	int ret_status = -1;
> +	tx_send_loop = 0;
> +
> +	/* Return error if no link */
> +	if (!phy.get_link_speed(active_phy_addr))
> +	{
> +		printf("WARN: emac_send_packet: No link\n");
> +		return (ret_status);
> +	}
> +
> +	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
> +	if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
> +	{
> +		length = EMAC_MIN_ETHERNET_PKT_SIZE;
> +	}
> +
> +	/* Populate the TX descriptor */
> +	emac_tx_desc->next         = 0;
> +	emac_tx_desc->buffer       = (u_int8_t *)packet;
> +	emac_tx_desc->buff_off_len = (length & 0xffff);
> +	emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
> +			EMAC_CPPI_SOP_BIT |
> +			EMAC_CPPI_OWNERSHIP_BIT |
> +			EMAC_CPPI_EOP_BIT);
> +	/* Send the packet */
> +	adap_emac->TX0HDP = (unsigned int)emac_tx_desc;
> +
> +	/* Wait for packet to complete or link down */
> +	while (1) {
> +	        if (!phy.get_link_speed(active_phy_addr)) {
> +	        	dm644x_eth_ch_teardown(EMAC_CH_TX);
> +	        	return (ret_status);
> +	        }
> +	        if (adap_emac->TXINTSTATRAW & 0x01) {
> +	        	ret_status = length;
> +	        	break;
> +		}
> +	        tx_send_loop++;
> +	}
> +
> +	return(ret_status);
> +}
> +
> +/*
> + * This function handles receipt of a packet from the network
> + */
> +static int dm644x_eth_rcv_packet(void)
> +{
> +	volatile emac_desc	*rx_curr_desc;
> +	volatile emac_desc	*curr_desc;
> +	volatile emac_desc	*tail_desc;
> +	int			status, ret = -1;
> +
> +	rx_curr_desc = emac_rx_active_head;
> +	status = rx_curr_desc->pkt_flag_len;
> +	if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
> +	        if (status & EMAC_CPPI_RX_ERROR_FRAME) {
> +	        	/* Error in packet - discard it and requeue desc */
> +	        	printf("WARN: emac_rcv_pkt: Error in packet\n");
> +		} else {
> +			NetReceive(rx_curr_desc->buffer, (rx_curr_desc->buff_off_len & 0xffff));
> +			ret = rx_curr_desc->buff_off_len & 0xffff;
> +	        }
> +
> +	        /* Ack received packet descriptor */
> +	        adap_emac->RX0CP = (unsigned int)rx_curr_desc;
> +	        curr_desc = rx_curr_desc;
> +	        emac_rx_active_head = (volatile emac_desc *)rx_curr_desc->next;
> +
> +	        if (status & EMAC_CPPI_EOQ_BIT) {
> +	        	if (emac_rx_active_head) {
> +	        		adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
> +			} else {
> +				emac_rx_queue_active = 0;
> +				printf("INFO:emac_rcv_packet: RX Queue not active\n");
> +			}
> +		}
> +
> +		/* Recycle RX descriptor */
> +		rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
> +		rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
> +		rx_curr_desc->next = 0;
> +
> +		if (emac_rx_active_head == 0) {
> +			printf("INFO: emac_rcv_pkt: active queue head = 0\n");
> +			emac_rx_active_head = curr_desc;
> +			emac_rx_active_tail = curr_desc;
> +			if (emac_rx_queue_active != 0) {
> +				adap_emac->RX0HDP = (unsigned int)emac_rx_active_head;
> +				printf("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
> +				emac_rx_queue_active = 1;
> +			}
> +		} else {
> +			tail_desc = emac_rx_active_tail;
> +			emac_rx_active_tail = curr_desc;
> +			tail_desc->next = (unsigned int)curr_desc;
> +			status = tail_desc->pkt_flag_len;
> +			if (status & EMAC_CPPI_EOQ_BIT) {
> +				adap_emac->RX0HDP = (unsigned int)curr_desc;
> +				status &= ~EMAC_CPPI_EOQ_BIT;
> +				tail_desc->pkt_flag_len = status;
> +			}
> +		}
> +		return(ret);
> +	}
> +	return(0);
> +}
> +
> +#endif /* CONFIG_CMD_NET */
> +
> +#endif /* CONFIG_DRIVER_TI_EMAC */
> diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/i2c.c u-boot.git/cpu/arm926ejs/davinci/i2c.c
> --- u-boot.git.orig/cpu/arm926ejs/davinci/i2c.c	1969-12-31 16:00:00.000000000 -0800
> +++ u-boot.git/cpu/arm926ejs/davinci/i2c.c	2007-08-07 10:15:34.000000000 -0700
> @@ -0,0 +1,351 @@
> +/*
> + * TI DaVinci (TMS320DM644x) I2C driver.
> + *
> + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
> + *
> + * --------------------------------------------------------
> + *
> + * 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>
> +
> +#ifdef CONFIG_DRIVER_DAVINCI_I2C
> +
> +#include <i2c.h>
> +#include <asm/arch/hardware.h>
> +#include <asm/arch/i2c_defs.h>
> +
> +#define CHECK_NACK() \
> +	do {\
> +		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
> +			REG(I2C_CON) = 0;\
> +			return(1);\
> +		}\
> +	} while (0)
> +
> +
> +static int wait_for_bus(void)
> +{
> +	int	stat, timeout;
> +
> +	REG(I2C_STAT) = 0xffff;
> +
> +	for (timeout = 0; timeout < 10; timeout++) {
> +		if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
> +			REG(I2C_STAT) = 0xffff;
> +			return(0);
> +		}
> +
> +		REG(I2C_STAT) = stat;
> +		udelay(50000);
> +	}
> +
> +	REG(I2C_STAT) = 0xffff;
> +	return(1);
> +}
> +
> +
> +static int poll_i2c_irq(int mask)
> +{
> +	int	stat, timeout;
> +
> +	for (timeout = 0; timeout < 10; timeout++) {
> +		udelay(1000);
> +		stat = REG(I2C_STAT);
> +		if (stat & mask) {
> +			return(stat);
> +		}
> +	}
> +
> +	REG(I2C_STAT) = 0xffff;
> +	return(stat | I2C_TIMEOUT);
> +}
> +
> +
> +void flush_rx(void)
> +{
> +	int	dummy;
> +
> +	while (1) {
> +		if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
> +			break;
> +
> +		dummy = REG(I2C_DRR);
> +		REG(I2C_STAT) = I2C_STAT_RRDY;
> +		udelay(1000);
> +	}
> +}
> +
> +
> +void i2c_init(int speed, int slaveadd)
> +{
> +	u_int32_t	div, psc;
> +
> +	if (REG(I2C_CON) & I2C_CON_EN) {
> +		REG(I2C_CON) = 0;
> +		udelay (50000);
> +	}
> +
> +	psc = 2;
> +	div = (CFG_HZ_CLOCK / ((psc + 1) * speed)) - 10;	/* SCLL + SCLH */
> +	REG(I2C_PSC) = psc;			/* 27MHz / (2 + 1) = 9MHz */
> +	REG(I2C_SCLL) = (div * 50) / 100;	/* 50% Duty */
> +	REG(I2C_SCLH) = div - REG(I2C_SCLL);
> +
> +	REG(I2C_OA) = slaveadd;
> +	REG(I2C_CNT) = 0;
> +
> +	/* Interrupts must be enabled or I2C module won't work */
> +	REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
> +		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
> +
> +	/* Now enable I2C controller (get it out of reset) */
> +	REG(I2C_CON) = I2C_CON_EN;
> +
> +	udelay(1000);
> +}
> +
> +
> +int i2c_probe(u_int8_t chip)
> +{
> +	int	rc = 1;
> +
> +	if (chip == REG(I2C_OA)) {
> +		return(rc);
> +	}
> +
> +	REG(I2C_CON) = 0;
> +	if (wait_for_bus()) {return(1);}
> +
> +	/* try to read one byte from current (or only) address */
> +	REG(I2C_CNT) = 1;
> +	REG(I2C_SA) = chip;
> +	REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP);
> +	udelay (50000);
> +
> +	if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
> +		rc = 0;
> +		flush_rx();
> +		REG(I2C_STAT) = 0xffff;
> +	} else {
> +		REG(I2C_STAT) = 0xffff;
> +		REG(I2C_CON) |= I2C_CON_STP;
> +		udelay(20000);
> +		if (wait_for_bus()) {return(1);}
> +	}
> +
> +	flush_rx();
> +	REG(I2C_STAT) = 0xffff;
> +	REG(I2C_CNT) = 0;
> +	return(rc);
> +}
> +
> +
> +int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
> +{
> +	u_int32_t	tmp;
> +	int		i;
> +
> +	if ((alen < 0) || (alen > 2)) {
> +		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
> +		return(1);
> +	}
> +
> +	if (wait_for_bus()) {return(1);}
> +
> +	if (alen != 0) {
> +		/* Start address phase */
> +		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
> +		REG(I2C_CNT) = alen;
> +		REG(I2C_SA) = chip;
> +		REG(I2C_CON) = tmp;
> +
> +		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
> +
> +		CHECK_NACK();
> +
> +		switch (alen) {
> +			case 2:
> +				/* Send address MSByte */
> +				if (tmp & I2C_STAT_XRDY) {
> +					REG(I2C_DXR) = (addr >> 8) & 0xff;
> +				} else {
> +					REG(I2C_CON) = 0;
> +					return(1);
> +				}
> +
> +				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
> +
> +				CHECK_NACK();
> +				/* No break, fall through */
> +			case 1:
> +				/* Send address LSByte */
> +				if (tmp & I2C_STAT_XRDY) {
> +					REG(I2C_DXR) = addr & 0xff;
> +				} else {
> +					REG(I2C_CON) = 0;
> +					return(1);
> +				}
> +
> +				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
> +
> +				CHECK_NACK();
> +
> +				if (!(tmp & I2C_STAT_ARDY)) {
> +					REG(I2C_CON) = 0;
> +					return(1);
> +				}
> +		}
> +	}
> +
> +	/* Address phase is over, now read 'len' bytes and stop */
> +	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
> +	REG(I2C_CNT) = len & 0xffff;
> +	REG(I2C_SA) = chip;
> +	REG(I2C_CON) = tmp;
> +
> +	for (i = 0; i < len; i++) {
> +		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
> +
> +		CHECK_NACK();
> +
> +		if (tmp & I2C_STAT_RRDY) {
> +			buf[i] = REG(I2C_DRR);
> +		} else {
> +			REG(I2C_CON) = 0;
> +			return(1);
> +		}
> +	}
> +
> +	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
> +
> +	CHECK_NACK();
> +
> +	if (!(tmp & I2C_STAT_SCD)) {
> +		REG(I2C_CON) = 0;
> +		return(1);
> +	}
> +
> +	flush_rx();
> +	REG(I2C_STAT) = 0xffff;
> +	REG(I2C_CNT) = 0;
> +	REG(I2C_CON) = 0;
> +
> +	return(0);
> +}
> +
> +
> +int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
> +{
> +	u_int32_t	tmp;
> +	int		i;
> +
> +	if ((alen < 0) || (alen > 2)) {
> +		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
> +		return(1);
> +	}
> +	if (len < 0) {
> +		printf("%s(): bogus length %x\n", __FUNCTION__, len);
> +		return(1);
> +	}
> +
> +	if (wait_for_bus()) {return(1);}
> +
> +	/* Start address phase */
> +	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
> +	REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
> +	REG(I2C_SA) = chip;
> +	REG(I2C_CON) = tmp;
> +
> +	switch (alen) {
> +		case 2:
> +			/* Send address MSByte */
> +			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
> +
> +			CHECK_NACK();
> +
> +			if (tmp & I2C_STAT_XRDY) {
> +				REG(I2C_DXR) = (addr >> 8) & 0xff;
> +			} else {
> +				REG(I2C_CON) = 0;
> +				return(1);
> +			}
> +			/* No break, fall through */
> +		case 1:
> +			/* Send address LSByte */
> +			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
> +
> +			CHECK_NACK();
> +
> +			if (tmp & I2C_STAT_XRDY) {
> +				REG(I2C_DXR) = addr & 0xff;
> +			} else {
> +				REG(I2C_CON) = 0;
> +				return(1);
> +			}
> +	}
> +
> +	for (i = 0; i < len; i++) {
> +		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
> +
> +		CHECK_NACK();
> +
> +		if (tmp & I2C_STAT_XRDY) {
> +			REG(I2C_DXR) = buf[i];
> +		} else {
> +			return(1);
> +		}
> +	}
> +
> +	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
> +
> +	CHECK_NACK();
> +
> +	if (!(tmp & I2C_STAT_SCD)) {
> +		REG(I2C_CON) = 0;
> +		return(1);
> +	}
> +
> +	flush_rx();
> +	REG(I2C_STAT) = 0xffff;
> +	REG(I2C_CNT) = 0;
> +	REG(I2C_CON) = 0;
> +
> +	return(0);
> +}
> +
> +
> +u_int8_t i2c_reg_read(u_int8_t chip, u_int8_t reg)
> +{
> +	u_int8_t	tmp;
> +
> +	i2c_read(chip, reg, 1, &tmp, 1);
> +	return(tmp);
> +}
> +
> +
> +void i2c_reg_write(u_int8_t chip, u_int8_t reg, u_int8_t val)
> +{
> +	u_int8_t	tmp;
> +
> +	i2c_write(chip, reg, 1, &tmp, 1);
> +}
> +
> +#endif /* CONFIG_DRIVER_DAVINCI_I2C */
> diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/Makefile u-boot.git/cpu/arm926ejs/davinci/Makefile
> --- u-boot.git.orig/cpu/arm926ejs/davinci/Makefile	1969-12-31 16:00:00.000000000 -0800
> +++ u-boot.git/cpu/arm926ejs/davinci/Makefile	2007-08-07 10:15:34.000000000 -0700
> @@ -0,0 +1,49 @@
> +#
> +# (C) Copyright 2000-2006
> +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> +#
> +# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
> +#
> +# 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 $(TOPDIR)/config.mk
> +
> +LIB	= $(obj)lib$(SOC).a
> +
> +COBJS	= timer.o ether.o lxt972.o dp83848.o i2c.o nand.o
> +SOBJS	= lowlevel_init.o reset.o
> +
> +SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
> +OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
> +START	:= $(addprefix $(obj),$(START))
> +
> +all:	$(obj).depend $(LIB)
> +
> +$(LIB):	$(OBJS)
> +	$(AR) $(ARFLAGS) $@ $(OBJS)
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff -purN u-boot.git.orig/CREDITS u-boot.git/CREDITS
> --- u-boot.git.orig/CREDITS	2007-04-04 12:28:34.000000000 -0700
> +++ u-boot.git/CREDITS	2007-08-07 10:15:34.000000000 -0700
> @@ -252,6 +252,10 @@ E: Raghu.Krishnaprasad at fci.com
>   D: Support for Adder-II MPC852T evaluation board
>   W: http://www.forcecomputers.com
> 
> +N: Sergey Kubushyn
> +E: ksi at koi8.net
> +D: Support for various TI DaVinci based boards.
> +
>   N: Bernhard Kuhn
>   E: bkuhn at metrowerks.com
>   D Support for Coldfire CPU; Support for Motorola M5272C3 and M5282EVB boards
> diff -purN u-boot.git.orig/lib_arm/board.c u-boot.git/lib_arm/board.c
> --- u-boot.git.orig/lib_arm/board.c	2007-08-06 18:05:59.000000000 -0700
> +++ u-boot.git/lib_arm/board.c	2007-08-07 10:15:34.000000000 -0700
> @@ -364,6 +364,13 @@ void start_armboot (void)
>   	enable_interrupts ();
> 
>   	/* Perform network card initialisation if necessary */
> +#ifdef CONFIG_DRIVER_TI_EMAC
> +extern void dm644x_eth_set_mac_addr (const u_int8_t *addr);
> +	if (getenv ("ethaddr")) {
> +		dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr);
> +	}
> +#endif
> +
>   #ifdef CONFIG_DRIVER_CS8900
>   	cs8900_get_enetaddr (gd->bd->bi_enetaddr);
>   #endif
> diff -purN u-boot.git.orig/MAINTAINERS u-boot.git/MAINTAINERS
> --- u-boot.git.orig/MAINTAINERS	2007-08-04 22:07:13.000000000 -0700
> +++ u-boot.git/MAINTAINERS	2007-08-07 10:15:34.000000000 -0700
> @@ -444,6 +444,12 @@ Nishant Kamat <nskamat@ti.com>
> 
>   	omap1610h2		ARM926EJS
> 
> +Sergey Kubushyn <ksi@koi8.net>
> +
> +	DV-EVM			ARM926EJS
> +	SONATA			ARM926EJS
> +	SCHMOOGIE		ARM926EJS
> +
>   Prakash Kumar <prakash@embedx.com>
> 
>   	cerf250			xscale
> diff -purN u-boot.git.orig/MAKEALL u-boot.git/MAKEALL
> --- u-boot.git.orig/MAKEALL	2007-08-06 18:05:59.000000000 -0700
> +++ u-boot.git/MAKEALL	2007-08-07 10:15:34.000000000 -0700
> @@ -220,7 +220,8 @@ LIST_ARM9="	\
>   	omap1610h2	omap1610inn	omap730p2	sbc2410x	\
>   	scb9328		smdk2400	smdk2410	trab		\
>   	VCMA9		versatile	versatileab	versatilepb	\
> -	voiceblue							\
> +	voiceblue	davinci_dvevm	davinci_schmoogie		\
> +	davinci_sonata
>   "
> 
>   #########################################################################
> diff -purN u-boot.git.orig/Makefile u-boot.git/Makefile
> --- u-boot.git.orig/Makefile	2007-08-06 18:05:59.000000000 -0700
> +++ u-boot.git/Makefile	2007-08-07 10:15:34.000000000 -0700
> @@ -2019,6 +2019,15 @@ omap1510inn_config :	unconfig
>   omap5912osk_config :	unconfig
>   	@$(MKCONFIG) $(@:_config=) arm arm926ejs omap5912osk NULL omap
> 
> +davinci_dvevm_config :	unconfig
> +	@$(MKCONFIG) $(@:_config=) arm arm926ejs dv-evm davinci davinci
> +
> +davinci_schmoogie_config :	unconfig
> +	@$(MKCONFIG) $(@:_config=) arm arm926ejs schmoogie davinci davinci
> +
> +davinci_sonata_config :	unconfig
> +	@$(MKCONFIG) $(@:_config=) arm arm926ejs sonata davinci davinci
> +
>   omap1610inn_config \
>   omap1610inn_cs0boot_config \
>   omap1610inn_cs3boot_config \
> diff -purN u-boot.git.orig/net/eth.c u-boot.git/net/eth.c
> --- u-boot.git.orig/net/eth.c	2007-08-06 18:05:59.000000000 -0700
> +++ u-boot.git/net/eth.c	2007-08-07 10:15:34.000000000 -0700
> @@ -464,6 +464,8 @@ extern int at91rm9200_miiphy_initialize(
>   extern int emac4xx_miiphy_initialize(bd_t *bis);
>   extern int mcf52x2_miiphy_initialize(bd_t *bis);
>   extern int ns7520_miiphy_initialize(bd_t *bis);
> +extern int dm644x_eth_miiphy_initialize(bd_t *bis);
> +
> 
>   int eth_initialize(bd_t *bis)
>   {
> @@ -484,6 +486,9 @@ int eth_initialize(bd_t *bis)
>   #if defined(CONFIG_NETARM)
>   	ns7520_miiphy_initialize(bis);
>   #endif
> +#if defined(CONFIG_DRIVER_TI_EMAC)
> +	dm644x_eth_miiphy_initialize(bis);
> +#endif
>   	return 0;
>   }
>   #endif
> 
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems?  Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >>  http://get.splunk.com/
> _______________________________________________
> U-Boot-Users mailing list
> U-Boot-Users at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/u-boot-users
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-08 15:57 ` Dirk Behme
@ 2007-08-09 21:35   ` Wolfgang Denk
  2007-08-09 22:25     ` Zach Sadecki
  2007-08-10 15:14     ` Dirk Behme
  2007-08-10  4:46   ` Stefan Roese
  1 sibling, 2 replies; 10+ messages in thread
From: Wolfgang Denk @ 2007-08-09 21:35 UTC (permalink / raw)
  To: u-boot

In message <46B9E7EF.8030801@googlemail.com> you wrote:
> ksi at koi8.net wrote:
> > Signed-off-by: Sergey Kubushyn <ksi@koi8.net>
> 
> Acked-by: Dirk Behme <dirk.behme@gmail.com>

Dirk,

I've seen your ACK's for patches 2 through 5, but not for patch 1.
What about this one?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Motto of the Electrical Engineer: Working computer hardware is a  lot
like an erect penis: it stays up as long as you don't fuck with it.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-09 21:35   ` Wolfgang Denk
@ 2007-08-09 22:25     ` Zach Sadecki
  2007-08-10 15:14     ` Dirk Behme
  1 sibling, 0 replies; 10+ messages in thread
From: Zach Sadecki @ 2007-08-09 22:25 UTC (permalink / raw)
  To: u-boot

 Put me down as ACK for all 5 of them.  I have applied them and
successfully compliled and ran u-boot on Davinci. (after applying the
bios emulator patch, as well, to get it to compile).

Zach

-----Original Message-----
From: u-boot-users-bounces@lists.sourceforge.net
[mailto:u-boot-users-bounces at lists.sourceforge.net] On Behalf Of
Wolfgang Denk
Sent: Thursday, August 09, 2007 4:35 PM
To: Dirk Behme
Cc: U-Boot list
Subject: Re: [U-Boot-Users] [ARM] TI DaVinci support, hopefully final
[2/5]

In message <46B9E7EF.8030801@googlemail.com> you wrote:
> ksi at koi8.net wrote:
> > Signed-off-by: Sergey Kubushyn <ksi@koi8.net>
> 
> Acked-by: Dirk Behme <dirk.behme@gmail.com>

Dirk,

I've seen your ACK's for patches 2 through 5, but not for patch 1.
What about this one?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Motto of the Electrical Engineer: Working computer hardware is a  lot
like an erect penis: it stays up as long as you don't fuck with it.

------------------------------------------------------------------------
-
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
U-Boot-Users mailing list
U-Boot-Users at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/u-boot-users

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-08 15:57 ` Dirk Behme
  2007-08-09 21:35   ` Wolfgang Denk
@ 2007-08-10  4:46   ` Stefan Roese
  2007-08-10 15:43     ` Dirk Behme
  1 sibling, 1 reply; 10+ messages in thread
From: Stefan Roese @ 2007-08-10  4:46 UTC (permalink / raw)
  To: u-boot

On Wednesday 08 August 2007, Dirk Behme wrote:
> ksi at koi8.net wrote:
> > Signed-off-by: Sergey Kubushyn <ksi@koi8.net>
>
> Acked-by: Dirk Behme <dirk.behme@gmail.com>

Unfortunately it does not apply clean anymore. Sergey or Dirk, could you one 
of you please redo this patch and send it again? Thanks.

Other than that:

Acked-by: Stefan Roese <sr@denx.de>

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-09 21:35   ` Wolfgang Denk
  2007-08-09 22:25     ` Zach Sadecki
@ 2007-08-10 15:14     ` Dirk Behme
  1 sibling, 0 replies; 10+ messages in thread
From: Dirk Behme @ 2007-08-10 15:14 UTC (permalink / raw)
  To: u-boot

Wolfgang Denk wrote:
> In message <46B9E7EF.8030801@googlemail.com> you wrote:
> 
>>ksi at koi8.net wrote:
>>
>>>Signed-off-by: Sergey Kubushyn <ksi@koi8.net>
>>
>>Acked-by: Dirk Behme <dirk.behme@gmail.com>
> 
> 
> Dirk,
> 
> I've seen your ACK's for patches 2 through 5, but not for patch 1.
> What about this one?

Sorry, it was eaten by the list filter because pressing reply it 
exceeds 40k. Just resent it.

Assume my ack for all five patches.

Best regards

Dirk

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-10  4:46   ` Stefan Roese
@ 2007-08-10 15:43     ` Dirk Behme
  2007-08-10 18:15       ` Stefan Roese
  0 siblings, 1 reply; 10+ messages in thread
From: Dirk Behme @ 2007-08-10 15:43 UTC (permalink / raw)
  To: u-boot

Stefan Roese wrote:
> On Wednesday 08 August 2007, Dirk Behme wrote:
> 
>>ksi at koi8.net wrote:
>>
>>>Signed-off-by: Sergey Kubushyn <ksi@koi8.net>
>>
>>Acked-by: Dirk Behme <dirk.behme@gmail.com>
>  
> Unfortunately it does not apply clean anymore. Sergey or Dirk, could you one 
> of you please redo this patch and send it again? Thanks.

Yes, I know, it's against the list rules, but can you please try the 
patch set sent as attachment and not the inline ones?

http://article.gmane.org/gmane.comp.boot-loaders.u-boot/30721
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/30722

As already discussed, I never got the parts of these inline patches 
which modify existing files applied. Even if they were against the 
same git level as I had. Most probably this is some inline 
reformatting issue. And sounds now that it's on Sergeys side ;)

My recent git top is "mpc83xx: fix ITX[GP] O=builddir builds" and the 
both patches sent as attachment apply mainly cleany (Makefile has an 
offset of 7 lines resolved automatically by patch). After applying 
still needed div64/nand_util patches all three boards compile cleanly 
as well.

Best regards

Dirk

> Other than that:
> 
> Acked-by: Stefan Roese <sr@denx.de>
> 
> Best regards,
> Stefan

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-10 15:43     ` Dirk Behme
@ 2007-08-10 18:15       ` Stefan Roese
  2007-08-10 18:20         ` ksi at koi8.net
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Roese @ 2007-08-10 18:15 UTC (permalink / raw)
  To: u-boot

On Friday 10 August 2007, Dirk Behme wrote:
> > Unfortunately it does not apply clean anymore. Sergey or Dirk, could you
> > one of you please redo this patch and send it again? Thanks.
>
> Yes, I know, it's against the list rules, but can you please try the
> patch set sent as attachment and not the inline ones?

Yep, this works. Thanks for the hint, we'll take care of it from here.

Sergey, thanks for your input and patience.

Dirk, thanks for your assistance.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-10 18:15       ` Stefan Roese
@ 2007-08-10 18:20         ` ksi at koi8.net
  2007-08-10 18:59           ` Wolfgang Denk
  0 siblings, 1 reply; 10+ messages in thread
From: ksi at koi8.net @ 2007-08-10 18:20 UTC (permalink / raw)
  To: u-boot

On Fri, 10 Aug 2007, Stefan Roese wrote:

> On Friday 10 August 2007, Dirk Behme wrote:
>>> Unfortunately it does not apply clean anymore. Sergey or Dirk, could
> you
>>> one of you please redo this patch and send it again? Thanks.
>>
>> Yes, I know, it's against the list rules, but can you please try the
>> patch set sent as attachment and not the inline ones?
>
> Yep, this works. Thanks for the hint, we'll take care of it from here.

So it IS going to happen? I can't believe it... :)

Thank you all guys for your assistance. I do really hope it will benefit the
entire DaVinci community. Now it's time to take on DaVinci Linux kernel...

---
******************************************************************
*  KSI at home    KOI8 Net  < >  The impossible we do immediately.  *
*  Las Vegas   NV, USA   < >  Miracles require 24-hour notice.   *
******************************************************************

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]
  2007-08-10 18:20         ` ksi at koi8.net
@ 2007-08-10 18:59           ` Wolfgang Denk
  0 siblings, 0 replies; 10+ messages in thread
From: Wolfgang Denk @ 2007-08-10 18:59 UTC (permalink / raw)
  To: u-boot

In message <Pine.LNX.4.64ksi.0708101117440.23250@home-gw.koi8.net> you wrote:
>
> 
> > Yep, this works. Thanks for the hint, we'll take care of it from here.
> 
> So it IS going to happen? I can't believe it... :)

No, it is NOT going to happen.


It already happened.

See
http://www.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=commit;h=c74b2108e31fe09bd1c5d291c3cf360510d4f13e

Yes, that's mainline...

> Thank you all guys for your assistance. I do really hope it will benefit the
> entire DaVinci community. Now it's time to take on DaVinci Linux kernel...

Say thanks to Stefan, who did the actuall work. You owe him and  Dirk
a beer. From now on, adding new stuff should be much easier...

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The existence of god implies a violation of causality.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-08-10 18:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-07 21:11 [U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5] ksi at koi8.net
2007-08-08 15:57 ` Dirk Behme
2007-08-09 21:35   ` Wolfgang Denk
2007-08-09 22:25     ` Zach Sadecki
2007-08-10 15:14     ` Dirk Behme
2007-08-10  4:46   ` Stefan Roese
2007-08-10 15:43     ` Dirk Behme
2007-08-10 18:15       ` Stefan Roese
2007-08-10 18:20         ` ksi at koi8.net
2007-08-10 18:59           ` Wolfgang Denk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox