[U-Boot-Users] [ARM] TI DaVinci support, hopefully final [2/5]

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@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@fci.com D: Support for Adder-II MPC852T evaluation board W: http://www.forcecomputers.com
+N: Sergey Kubushyn +E: ksi@koi8.net +D: Support for various TI DaVinci based boards. + N: Bernhard Kuhn E: bkuhn@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

ksi@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@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@fci.com D: Support for Adder-II MPC852T evaluation board W: http://www.forcecomputers.com
+N: Sergey Kubushyn +E: ksi@koi8.net +D: Support for various TI DaVinci based boards.
- N: Bernhard Kuhn E: bkuhn@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@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users

In message 46B9E7EF.8030801@googlemail.com you wrote:
ksi@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

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@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@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

Wolfgang Denk wrote:
In message 46B9E7EF.8030801@googlemail.com you wrote:
ksi@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

On Wednesday 08 August 2007, Dirk Behme wrote:
ksi@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@denx.de =====================================================================

Stefan Roese wrote:
On Wednesday 08 August 2007, Dirk Behme wrote:
ksi@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

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@denx.de =====================================================================

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@home KOI8 Net < > The impossible we do immediately. * * Las Vegas NV, USA < > Miracles require 24-hour notice. * ******************************************************************

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=c74b2108e31fe0...
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
participants (5)
-
Dirk Behme
-
ksi@koi8.net
-
Stefan Roese
-
Wolfgang Denk
-
Zach Sadecki