]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
keystone2: net: add keystone ethernet driver
authorKaricheri, Muralidharan <m-karicheri2@ti.com>
Tue, 1 Apr 2014 19:01:13 +0000 (15:01 -0400)
committerTom Rini <trini@ti.com>
Thu, 17 Apr 2014 21:24:39 +0000 (17:24 -0400)
Ethernet driver configures the CPSW, SGMI and Phy and uses
the the Navigator APIs. The driver supports 4 Ethernet ports and
can work with only one port at a time.

Port configurations are defined in board.c.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
arch/arm/include/asm/arch-keystone/emac_defs.h [new file with mode: 0644]
board/ti/k2hk_evm/board.c
drivers/net/Makefile
drivers/net/keystone_net.c [new file with mode: 0644]
include/configs/k2hk_evm.h

diff --git a/arch/arm/include/asm/arch-keystone/emac_defs.h b/arch/arm/include/asm/arch-keystone/emac_defs.h
new file mode 100644 (file)
index 0000000..0aa2f89
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * emac definitions for keystone2 devices
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _EMAC_DEFS_H_
+#define _EMAC_DEFS_H_
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+#define DEVICE_REG32_R(a)               readl(a)
+#define DEVICE_REG32_W(a, v)            writel(v, a)
+
+#define EMAC_EMACSL_BASE_ADDR           (KS2_PASS_BASE + 0x00090900)
+#define EMAC_MDIO_BASE_ADDR             (KS2_PASS_BASE + 0x00090300)
+#define EMAC_SGMII_BASE_ADDR            (KS2_PASS_BASE + 0x00090100)
+
+#define KEYSTONE2_EMAC_GIG_ENABLE
+
+#define MAC_ID_BASE_ADDR                (KS2_DEVICE_STATE_CTRL_BASE + 0x110)
+
+#ifdef CONFIG_SOC_K2HK
+/* MDIO module input frequency */
+#define EMAC_MDIO_BUS_FREQ              (clk_get_rate(pass_pll_clk))
+/* MDIO clock output frequency */
+#define EMAC_MDIO_CLOCK_FREQ            1000000                /* 1.0 MHz */
+#endif
+
+/* MII Status Register */
+#define MII_STATUS_REG                  1
+#define MII_STATUS_LINK_MASK            (0x4)
+
+/* Marvell 88E1111 PHY ID */
+#define PHY_MARVELL_88E1111             (0x01410cc0)
+
+#define MDIO_CONTROL_IDLE               (0x80000000)
+#define MDIO_CONTROL_ENABLE             (0x40000000)
+#define MDIO_CONTROL_FAULT_ENABLE       (0x40000)
+#define MDIO_CONTROL_FAULT              (0x80000)
+#define MDIO_USERACCESS0_GO             (0x80000000)
+#define MDIO_USERACCESS0_WRITE_READ     (0x0)
+#define MDIO_USERACCESS0_WRITE_WRITE    (0x40000000)
+#define MDIO_USERACCESS0_ACK            (0x20000000)
+
+#define EMAC_MACCONTROL_MIIEN_ENABLE       (0x20)
+#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE  (0x1)
+#define EMAC_MACCONTROL_GIGABIT_ENABLE     (1 << 7)
+#define EMAC_MACCONTROL_GIGFORCE           (1 << 17)
+#define EMAC_MACCONTROL_RMIISPEED_100      (1 << 15)
+
+#define EMAC_MIN_ETHERNET_PKT_SIZE         60
+
+struct mac_sl_cfg {
+       u_int32_t max_rx_len;   /* Maximum receive packet length. */
+       u_int32_t ctl;          /* Control bitfield */
+};
+
+/*
+ * Definition: Control bitfields used in the ctl field of hwGmacSlCfg_t
+ */
+#define GMACSL_RX_ENABLE_RCV_CONTROL_FRAMES       (1 << 24)
+#define GMACSL_RX_ENABLE_RCV_SHORT_FRAMES         (1 << 23)
+#define GMACSL_RX_ENABLE_RCV_ERROR_FRAMES         (1 << 22)
+#define GMACSL_RX_ENABLE_EXT_CTL                  (1 << 18)
+#define GMACSL_RX_ENABLE_GIG_FORCE                (1 << 17)
+#define GMACSL_RX_ENABLE_IFCTL_B                  (1 << 16)
+#define GMACSL_RX_ENABLE_IFCTL_A                  (1 << 15)
+#define GMACSL_RX_ENABLE_CMD_IDLE                 (1 << 11)
+#define GMACSL_TX_ENABLE_SHORT_GAP                (1 << 10)
+#define GMACSL_ENABLE_GIG_MODE                    (1 <<  7)
+#define GMACSL_TX_ENABLE_PACE                     (1 <<  6)
+#define GMACSL_ENABLE                             (1 <<  5)
+#define GMACSL_TX_ENABLE_FLOW_CTL                 (1 <<  4)
+#define GMACSL_RX_ENABLE_FLOW_CTL                 (1 <<  3)
+#define GMACSL_ENABLE_LOOPBACK                    (1 <<  1)
+#define GMACSL_ENABLE_FULL_DUPLEX                 (1 <<  0)
+
+/*
+ * DEFINTITION: function return values
+ */
+#define GMACSL_RET_OK                        0
+#define GMACSL_RET_INVALID_PORT             -1
+#define GMACSL_RET_WARN_RESET_INCOMPLETE    -2
+#define GMACSL_RET_WARN_MAXLEN_TOO_BIG      -3
+#define GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE -4
+
+/* Register offsets */
+#define CPGMACSL_REG_ID         0x00
+#define CPGMACSL_REG_CTL        0x04
+#define CPGMACSL_REG_STATUS     0x08
+#define CPGMACSL_REG_RESET      0x0c
+#define CPGMACSL_REG_MAXLEN     0x10
+#define CPGMACSL_REG_BOFF       0x14
+#define CPGMACSL_REG_RX_PAUSE   0x18
+#define CPGMACSL_REG_TX_PAURSE  0x1c
+#define CPGMACSL_REG_EM_CTL     0x20
+#define CPGMACSL_REG_PRI        0x24
+
+/* Soft reset register values */
+#define CPGMAC_REG_RESET_VAL_RESET_MASK      (1 << 0)
+#define CPGMAC_REG_RESET_VAL_RESET           (1 << 0)
+
+/* Maxlen register values */
+#define CPGMAC_REG_MAXLEN_LEN                0x3fff
+
+/* Control bitfields */
+#define CPSW_CTL_P2_PASS_PRI_TAGGED     (1 << 5)
+#define CPSW_CTL_P1_PASS_PRI_TAGGED     (1 << 4)
+#define CPSW_CTL_P0_PASS_PRI_TAGGED     (1 << 3)
+#define CPSW_CTL_P0_ENABLE              (1 << 2)
+#define CPSW_CTL_VLAN_AWARE             (1 << 1)
+#define CPSW_CTL_FIFO_LOOPBACK          (1 << 0)
+
+#define DEVICE_CPSW_NUM_PORTS       5                    /* 5 switch ports */
+#define DEVICE_CPSW_BASE            (0x02090800)
+#define target_get_switch_ctl()     CPSW_CTL_P0_ENABLE   /* Enable port 0 */
+#define SWITCH_MAX_PKT_SIZE         9000
+
+/* Register offsets */
+#define CPSW_REG_CTL                0x004
+#define CPSW_REG_STAT_PORT_EN       0x00c
+#define CPSW_REG_MAXLEN             0x040
+#define CPSW_REG_ALE_CONTROL        0x608
+#define CPSW_REG_ALE_PORTCTL(x)     (0x640 + (x)*4)
+
+/* Register values */
+#define CPSW_REG_VAL_STAT_ENABLE_ALL             0xf
+#define CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE    ((u_int32_t)0xc0000000)
+#define CPSW_REG_VAL_ALE_CTL_BYPASS              ((u_int32_t)0x00000010)
+#define CPSW_REG_VAL_PORTCTL_FORWARD_MODE        0x3
+
+#define SGMII_REG_STATUS_LOCK           BIT(4)
+#define SGMII_REG_STATUS_LINK           BIT(0)
+#define SGMII_REG_STATUS_AUTONEG        BIT(2)
+#define SGMII_REG_CONTROL_AUTONEG       BIT(0)
+#define SGMII_REG_CONTROL_MASTER        BIT(5)
+#define        SGMII_REG_MR_ADV_ENABLE         BIT(0)
+#define        SGMII_REG_MR_ADV_LINK           BIT(15)
+#define        SGMII_REG_MR_ADV_FULL_DUPLEX    BIT(12)
+#define SGMII_REG_MR_ADV_GIG_MODE       BIT(11)
+
+#define SGMII_LINK_MAC_MAC_AUTONEG      0
+#define SGMII_LINK_MAC_PHY              1
+#define SGMII_LINK_MAC_MAC_FORCED       2
+#define SGMII_LINK_MAC_FIBER            3
+#define SGMII_LINK_MAC_PHY_FORCED       4
+
+#define TARGET_SGMII_BASE              KS2_PASS_BASE + 0x00090100
+#define TARGET_SGMII_BASE_ADDRESSES    {KS2_PASS_BASE + 0x00090100, \
+                                       KS2_PASS_BASE + 0x00090200, \
+                                       KS2_PASS_BASE + 0x00090400, \
+                                       KS2_PASS_BASE + 0x00090500}
+
+#define SGMII_OFFSET(x)        ((x <= 1) ? (x * 0x100) : ((x * 0x100) + 0x100))
+
+/*
+ * SGMII registers
+ */
+#define SGMII_IDVER_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x000)
+#define SGMII_SRESET_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x004)
+#define SGMII_CTL_REG(x)      (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x010)
+#define SGMII_STATUS_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x014)
+#define SGMII_MRADV_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x018)
+#define SGMII_LPADV_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x020)
+#define SGMII_TXCFG_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x030)
+#define SGMII_RXCFG_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x034)
+#define SGMII_AUXCFG_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x038)
+
+#define DEVICE_EMACSL_BASE(x)      (KS2_PASS_BASE + 0x00090900 + (x) * 0x040)
+#define DEVICE_N_GMACSL_PORTS           4
+#define DEVICE_EMACSL_RESET_POLL_COUNT  100
+
+#define DEVICE_PSTREAM_CFG_REG_ADDR                 (KS2_PASS_BASE + 0x604)
+
+#ifdef CONFIG_SOC_K2HK
+#define DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI      0x06060606
+#endif
+
+#define hw_config_streaming_switch() \
+       DEVICE_REG32_W(DEVICE_PSTREAM_CFG_REG_ADDR, \
+                      DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI);
+
+/* EMAC MDIO Registers Structure */
+struct mdio_regs {
+       dv_reg          version;
+       dv_reg          control;
+       dv_reg          alive;
+       dv_reg          link;
+       dv_reg          linkintraw;
+       dv_reg          linkintmasked;
+       u_int8_t        rsvd0[8];
+       dv_reg          userintraw;
+       dv_reg          userintmasked;
+       dv_reg          userintmaskset;
+       dv_reg          userintmaskclear;
+       u_int8_t        rsvd1[80];
+       dv_reg          useraccess0;
+       dv_reg          userphysel0;
+       dv_reg          useraccess1;
+       dv_reg          userphysel1;
+};
+
+/* Ethernet MAC Registers Structure */
+struct emac_regs {
+       dv_reg          idver;
+       dv_reg          maccontrol;
+       dv_reg          macstatus;
+       dv_reg          soft_reset;
+       dv_reg          rx_maxlen;
+       u32             rsvd0;
+       dv_reg          rx_pause;
+       dv_reg          tx_pause;
+       dv_reg          emcontrol;
+       dv_reg          pri_map;
+       u32             rsvd1[6];
+};
+
+#define SGMII_ACCESS(port, reg) \
+       *((volatile unsigned int *)(sgmiis[port] + reg))
+
+struct eth_priv_t {
+       char    int_name[32];
+       int     rx_flow;
+       int     phy_addr;
+       int     slave_port;
+       int     sgmii_link_type;
+};
+
+extern struct eth_priv_t eth_priv_cfg[];
+
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv);
+void sgmii_serdes_setup_156p25mhz(void);
+void sgmii_serdes_shutdown(void);
+
+#endif  /* _EMAC_DEFS_H_ */
index aef67f4b48fd01db9ccff826e63c78c17a9e334d..dc39139565f9bcaa72e129d6cc8bb4a744c2a196 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/arch/nand_defs.h>
+#include <asm/arch/emac_defs.h>
 #include <asm/arch/psc_defs.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -70,6 +71,70 @@ int dram_init(void)
        return 0;
 }
 
+#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
+struct eth_priv_t eth_priv_cfg[] = {
+       {
+               .int_name       = "K2HK_EMAC",
+               .rx_flow        = 22,
+               .phy_addr       = 0,
+               .slave_port     = 1,
+               .sgmii_link_type = SGMII_LINK_MAC_PHY,
+       },
+       {
+               .int_name       = "K2HK_EMAC1",
+               .rx_flow        = 23,
+               .phy_addr       = 1,
+               .slave_port     = 2,
+               .sgmii_link_type = SGMII_LINK_MAC_PHY,
+       },
+       {
+               .int_name       = "K2HK_EMAC2",
+               .rx_flow        = 24,
+               .phy_addr       = 2,
+               .slave_port     = 3,
+               .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+       },
+       {
+               .int_name       = "K2HK_EMAC3",
+               .rx_flow        = 25,
+               .phy_addr       = 3,
+               .slave_port     = 4,
+               .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+       },
+};
+
+int get_eth_env_param(char *env_name)
+{
+       char *env;
+       int  res = -1;
+
+       env = getenv(env_name);
+       if (env)
+               res = simple_strtol(env, NULL, 0);
+
+       return res;
+}
+
+int board_eth_init(bd_t *bis)
+{
+       int     j;
+       int     res;
+       char    link_type_name[32];
+
+       for (j = 0; j < (sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t));
+            j++) {
+               sprintf(link_type_name, "sgmii%d_link_type", j);
+               res = get_eth_env_param(link_type_name);
+               if (res >= 0)
+                       eth_priv_cfg[j].sgmii_link_type = res;
+
+               keystone2_emac_initialize(&eth_priv_cfg[j]);
+       }
+
+       return 0;
+}
+#endif
+
 /* Byte swap the 32-bit data if the device is BE */
 int cpu_to_bus(u32 *ptr, u32 length)
 {
index 7f9ce90a6d554eb2585f70bf42def4b2a15de071..6005f7e4137bc0c5092422a1a5dbfe682c950c8a 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_FTMAC110) += ftmac110.o
 obj-$(CONFIG_FTMAC100) += ftmac100.o
 obj-$(CONFIG_GRETH) += greth.o
 obj-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
+obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o
 obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
 obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
 obj-$(CONFIG_LAN91C96) += lan91c96.o
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
new file mode 100644 (file)
index 0000000..f95c928
--- /dev/null
@@ -0,0 +1,716 @@
+/*
+ * Ethernet driver for TI K2HK EVM.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+
+#include <net.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <asm/arch/emac_defs.h>
+#include <asm/arch/psc_defs.h>
+#include <asm/arch/keystone_nav.h>
+
+unsigned int emac_dbg;
+
+unsigned int emac_open;
+static unsigned int sys_has_mdio = 1;
+
+#ifdef KEYSTONE2_EMAC_GIG_ENABLE
+#define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x)
+#else
+#define emac_gigabit_enable(x) /* no gigabit to enable */
+#endif
+
+#define RX_BUFF_NUMS   24
+#define RX_BUFF_LEN    1520
+#define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN
+
+static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16);
+
+struct rx_buff_desc net_rx_buffs = {
+       .buff_ptr       = rx_buffs,
+       .num_buffs      = RX_BUFF_NUMS,
+       .buff_len       = RX_BUFF_LEN,
+       .rx_flow        = 22,
+};
+
+static void keystone2_eth_mdio_enable(void);
+
+static int gen_get_link_speed(int phy_addr);
+
+/* EMAC Addresses */
+static volatile struct emac_regs       *adap_emac =
+       (struct emac_regs *)EMAC_EMACSL_BASE_ADDR;
+static volatile struct mdio_regs       *adap_mdio =
+       (struct mdio_regs *)EMAC_MDIO_BASE_ADDR;
+
+int keystone2_eth_read_mac_addr(struct eth_device *dev)
+{
+       struct eth_priv_t *eth_priv;
+       u32 maca = 0;
+       u32 macb = 0;
+
+       eth_priv = (struct eth_priv_t *)dev->priv;
+
+       /* Read the e-fuse mac address */
+       if (eth_priv->slave_port == 1) {
+               maca = __raw_readl(MAC_ID_BASE_ADDR);
+               macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
+       }
+
+       dev->enetaddr[0] = (macb >>  8) & 0xff;
+       dev->enetaddr[1] = (macb >>  0) & 0xff;
+       dev->enetaddr[2] = (maca >> 24) & 0xff;
+       dev->enetaddr[3] = (maca >> 16) & 0xff;
+       dev->enetaddr[4] = (maca >>  8) & 0xff;
+       dev->enetaddr[5] = (maca >>  0) & 0xff;
+
+       return 0;
+}
+
+static void keystone2_eth_mdio_enable(void)
+{
+       u_int32_t       clkdiv;
+
+       clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+
+       writel((clkdiv & 0xffff) |
+              MDIO_CONTROL_ENABLE |
+              MDIO_CONTROL_FAULT |
+              MDIO_CONTROL_FAULT_ENABLE,
+              &adap_mdio->control);
+
+       while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE)
+               ;
+}
+
+/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
+int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+{
+       int     tmp;
+
+       while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
+               ;
+
+       writel(MDIO_USERACCESS0_GO |
+              MDIO_USERACCESS0_WRITE_READ |
+              ((reg_num & 0x1f) << 21) |
+              ((phy_addr & 0x1f) << 16),
+              &adap_mdio->useraccess0);
+
+       /* Wait for command to complete */
+       while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO)
+               ;
+
+       if (tmp & MDIO_USERACCESS0_ACK) {
+               *data = tmp & 0xffff;
+               return 0;
+       }
+
+       *data = -1;
+       return -1;
+}
+
+/*
+ * Write to a PHY register via MDIO inteface.
+ * Blocks until operation is complete.
+ */
+int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+{
+       while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
+               ;
+
+       writel(MDIO_USERACCESS0_GO |
+              MDIO_USERACCESS0_WRITE_WRITE |
+              ((reg_num & 0x1f) << 21) |
+              ((phy_addr & 0x1f) << 16) |
+              (data & 0xffff),
+              &adap_mdio->useraccess0);
+
+       /* Wait for command to complete */
+       while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
+               ;
+
+       return 0;
+}
+
+/* PHY functions for a generic PHY */
+static int gen_get_link_speed(int phy_addr)
+{
+       u_int16_t       tmp;
+
+       if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
+           (tmp & 0x04)) {
+               return 0;
+       }
+
+       return -1;
+}
+
+static void  __attribute__((unused))
+       keystone2_eth_gigabit_enable(struct eth_device *dev)
+{
+       u_int16_t data;
+       struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+       if (sys_has_mdio) {
+               if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) ||
+                   !(data & (1 << 6))) /* speed selection MSB */
+                       return;
+       }
+
+       /*
+        * Check if link detected is giga-bit
+        * If Gigabit mode detected, enable gigbit in MAC
+        */
+       writel(readl(&(adap_emac[eth_priv->slave_port - 1].maccontrol)) |
+              EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
+              &(adap_emac[eth_priv->slave_port - 1].maccontrol))
+               ;
+}
+
+int keystone_sgmii_link_status(int port)
+{
+       u32 status = 0;
+
+       status = __raw_readl(SGMII_STATUS_REG(port));
+
+       return status & SGMII_REG_STATUS_LINK;
+}
+
+
+int keystone_get_link_status(struct eth_device *dev)
+{
+       struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+       int sgmii_link;
+       int link_state = 0;
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
+       int j;
+
+       for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
+            j++) {
+#endif
+               sgmii_link =
+                       keystone_sgmii_link_status(eth_priv->slave_port - 1);
+
+               if (sgmii_link) {
+                       link_state = 1;
+
+                       if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)
+                               if (gen_get_link_speed(eth_priv->phy_addr))
+                                       link_state = 0;
+               }
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
+       }
+#endif
+       return link_state;
+}
+
+int keystone_sgmii_config(int port, int interface)
+{
+       unsigned int i, status, mask;
+       unsigned int mr_adv_ability, control;
+
+       switch (interface) {
+       case SGMII_LINK_MAC_MAC_AUTONEG:
+               mr_adv_ability  = (SGMII_REG_MR_ADV_ENABLE |
+                                  SGMII_REG_MR_ADV_LINK |
+                                  SGMII_REG_MR_ADV_FULL_DUPLEX |
+                                  SGMII_REG_MR_ADV_GIG_MODE);
+               control         = (SGMII_REG_CONTROL_MASTER |
+                                  SGMII_REG_CONTROL_AUTONEG);
+
+               break;
+       case SGMII_LINK_MAC_PHY:
+       case SGMII_LINK_MAC_PHY_FORCED:
+               mr_adv_ability  = SGMII_REG_MR_ADV_ENABLE;
+               control         = SGMII_REG_CONTROL_AUTONEG;
+
+               break;
+       case SGMII_LINK_MAC_MAC_FORCED:
+               mr_adv_ability  = (SGMII_REG_MR_ADV_ENABLE |
+                                  SGMII_REG_MR_ADV_LINK |
+                                  SGMII_REG_MR_ADV_FULL_DUPLEX |
+                                  SGMII_REG_MR_ADV_GIG_MODE);
+               control         = SGMII_REG_CONTROL_MASTER;
+
+               break;
+       case SGMII_LINK_MAC_FIBER:
+               mr_adv_ability  = 0x20;
+               control         = SGMII_REG_CONTROL_AUTONEG;
+
+               break;
+       default:
+               mr_adv_ability  = SGMII_REG_MR_ADV_ENABLE;
+               control         = SGMII_REG_CONTROL_AUTONEG;
+       }
+
+       __raw_writel(0, SGMII_CTL_REG(port));
+
+       /*
+        * Wait for the SerDes pll to lock,
+        * but don't trap if lock is never read
+        */
+       for (i = 0; i < 1000; i++)  {
+               udelay(2000);
+               status = __raw_readl(SGMII_STATUS_REG(port));
+               if ((status & SGMII_REG_STATUS_LOCK) != 0)
+                       break;
+       }
+
+       __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port));
+       __raw_writel(control, SGMII_CTL_REG(port));
+
+
+       mask = SGMII_REG_STATUS_LINK;
+
+       if (control & SGMII_REG_CONTROL_AUTONEG)
+               mask |= SGMII_REG_STATUS_AUTONEG;
+
+       for (i = 0; i < 1000; i++) {
+               status = __raw_readl(SGMII_STATUS_REG(port));
+               if ((status & mask) == mask)
+                       break;
+       }
+
+       return 0;
+}
+
+int mac_sl_reset(u32 port)
+{
+       u32 i, v;
+
+       if (port >= DEVICE_N_GMACSL_PORTS)
+               return GMACSL_RET_INVALID_PORT;
+
+       /* Set the soft reset bit */
+       DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) +
+                      CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET);
+
+       /* Wait for the bit to clear */
+       for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
+               v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
+                                  CPGMACSL_REG_RESET);
+               if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
+                   CPGMAC_REG_RESET_VAL_RESET)
+                       return GMACSL_RET_OK;
+       }
+
+       /* Timeout on the reset */
+       return GMACSL_RET_WARN_RESET_INCOMPLETE;
+}
+
+int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
+{
+       u32 v, i;
+       int ret = GMACSL_RET_OK;
+
+       if (port >= DEVICE_N_GMACSL_PORTS)
+               return GMACSL_RET_INVALID_PORT;
+
+       if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) {
+               cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN;
+               ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG;
+       }
+
+       /* Must wait if the device is undergoing reset */
+       for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
+               v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
+                                  CPGMACSL_REG_RESET);
+               if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
+                   CPGMAC_REG_RESET_VAL_RESET)
+                       break;
+       }
+
+       if (i == DEVICE_EMACSL_RESET_POLL_COUNT)
+               return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE;
+
+       DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN,
+                      cfg->max_rx_len);
+
+       DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL,
+                      cfg->ctl);
+
+       return ret;
+}
+
+int ethss_config(u32 ctl, u32 max_pkt_size)
+{
+       u32 i;
+
+       /* Max length register */
+       DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_MAXLEN, max_pkt_size);
+
+       /* Control register */
+       DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_CTL, ctl);
+
+       /* All statistics enabled by default */
+       DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN,
+                      CPSW_REG_VAL_STAT_ENABLE_ALL);
+
+       /* Reset and enable the ALE */
+       DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL,
+                      CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE |
+                      CPSW_REG_VAL_ALE_CTL_BYPASS);
+
+       /* All ports put into forward mode */
+       for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++)
+               DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i),
+                              CPSW_REG_VAL_PORTCTL_FORWARD_MODE);
+
+       return 0;
+}
+
+int ethss_start(void)
+{
+       int i;
+       struct mac_sl_cfg cfg;
+
+       cfg.max_rx_len  = MAX_SIZE_STREAM_BUFFER;
+       cfg.ctl         = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL;
+
+       for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) {
+               mac_sl_reset(i);
+               mac_sl_config(i, &cfg);
+       }
+
+       return 0;
+}
+
+int ethss_stop(void)
+{
+       int i;
+
+       for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++)
+               mac_sl_reset(i);
+
+       return 0;
+}
+
+int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num)
+{
+       if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
+               num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;
+
+       return netcp_send(buffer, num_bytes, (slave_port_num) << 16);
+}
+
+/* Eth device open */
+static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
+{
+       u_int32_t clkdiv;
+       int link;
+       struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+       debug("+ emac_open\n");
+
+       net_rx_buffs.rx_flow    = eth_priv->rx_flow;
+
+       sys_has_mdio =
+               (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
+
+       psc_enable_module(KS2_LPSC_PA);
+       psc_enable_module(KS2_LPSC_CPGMAC);
+
+       sgmii_serdes_setup_156p25mhz();
+
+       if (sys_has_mdio)
+               keystone2_eth_mdio_enable();
+
+       keystone_sgmii_config(eth_priv->slave_port - 1,
+                             eth_priv->sgmii_link_type);
+
+       udelay(10000);
+
+       /* On chip switch configuration */
+       ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);
+
+       /* TODO: add error handling code */
+       if (qm_init()) {
+               printf("ERROR: qm_init()\n");
+               return -1;
+       }
+       if (netcp_init(&net_rx_buffs)) {
+               qm_close();
+               printf("ERROR: netcp_init()\n");
+               return -1;
+       }
+
+       /*
+        * Streaming switch configuration. If not present this
+        * statement is defined to void in target.h.
+        * If present this is usually defined to a series of register writes
+        */
+       hw_config_streaming_switch();
+
+       if (sys_has_mdio) {
+               /* Init MDIO & get link state */
+               clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+               writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE |
+                      MDIO_CONTROL_FAULT, &adap_mdio->control)
+                       ;
+
+               /* We need to wait for MDIO to start */
+               udelay(1000);
+
+               link = keystone_get_link_status(dev);
+               if (link == 0) {
+                       netcp_close();
+                       qm_close();
+                       return -1;
+               }
+       }
+
+       emac_gigabit_enable(dev);
+
+       ethss_start();
+
+       debug("- emac_open\n");
+
+       emac_open = 1;
+
+       return 0;
+}
+
+/* Eth device close */
+void keystone2_eth_close(struct eth_device *dev)
+{
+       debug("+ emac_close\n");
+
+       if (!emac_open)
+               return;
+
+       ethss_stop();
+
+       netcp_close();
+       qm_close();
+
+       emac_open = 0;
+
+       debug("- emac_close\n");
+}
+
+static int tx_send_loop;
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int keystone2_eth_send_packet(struct eth_device *dev,
+                                       void *packet, int length)
+{
+       int ret_status = -1;
+       struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+       tx_send_loop = 0;
+
+       if (keystone_get_link_status(dev) == 0)
+               return -1;
+
+       emac_gigabit_enable(dev);
+
+       if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
+               return ret_status;
+
+       if (keystone_get_link_status(dev) == 0)
+               return -1;
+
+       emac_gigabit_enable(dev);
+
+       return length;
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int keystone2_eth_rcv_packet(struct eth_device *dev)
+{
+       void *hd;
+       int  pkt_size;
+       u32  *pkt;
+
+       hd = netcp_recv(&pkt, &pkt_size);
+       if (hd == NULL)
+               return 0;
+
+       NetReceive((uchar *)pkt, pkt_size);
+
+       netcp_release_rxhd(hd);
+
+       return pkt_size;
+}
+
+/*
+ * This function initializes the EMAC hardware.
+ */
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
+{
+       struct eth_device *dev;
+
+       dev = malloc(sizeof(struct eth_device));
+       if (dev == NULL)
+               return -1;
+
+       memset(dev, 0, sizeof(struct eth_device));
+
+       strcpy(dev->name, eth_priv->int_name);
+       dev->priv = eth_priv;
+
+       keystone2_eth_read_mac_addr(dev);
+
+       dev->iobase             = 0;
+       dev->init               = keystone2_eth_open;
+       dev->halt               = keystone2_eth_close;
+       dev->send               = keystone2_eth_send_packet;
+       dev->recv               = keystone2_eth_rcv_packet;
+
+       eth_register(dev);
+
+       return 0;
+}
+
+void sgmii_serdes_setup_156p25mhz(void)
+{
+       unsigned int cnt;
+
+       /*
+        * configure Serializer/Deserializer (SerDes) hardware. SerDes IP
+        * hardware vendor published only register addresses and their values
+        * to be used for configuring SerDes. So had to use hardcoded values
+        * below.
+        */
+       clrsetbits_le32(0x0232a000, 0xffff0000, 0x00800000);
+       clrsetbits_le32(0x0232a014, 0x0000ffff, 0x00008282);
+       clrsetbits_le32(0x0232a060, 0x00ffffff, 0x00142438);
+       clrsetbits_le32(0x0232a064, 0x00ffff00, 0x00c3c700);
+       clrsetbits_le32(0x0232a078, 0x0000ff00, 0x0000c000);
+
+       clrsetbits_le32(0x0232a204, 0xff0000ff, 0x38000080);
+       clrsetbits_le32(0x0232a208, 0x000000ff, 0x00000000);
+       clrsetbits_le32(0x0232a20c, 0xff000000, 0x02000000);
+       clrsetbits_le32(0x0232a210, 0xff000000, 0x1b000000);
+       clrsetbits_le32(0x0232a214, 0x0000ffff, 0x00006fb8);
+       clrsetbits_le32(0x0232a218, 0xffff00ff, 0x758000e4);
+       clrsetbits_le32(0x0232a2ac, 0x0000ff00, 0x00004400);
+       clrsetbits_le32(0x0232a22c, 0x00ffff00, 0x00200800);
+       clrsetbits_le32(0x0232a280, 0x00ff00ff, 0x00820082);
+       clrsetbits_le32(0x0232a284, 0xffffffff, 0x1d0f0385);
+
+       clrsetbits_le32(0x0232a404, 0xff0000ff, 0x38000080);
+       clrsetbits_le32(0x0232a408, 0x000000ff, 0x00000000);
+       clrsetbits_le32(0x0232a40c, 0xff000000, 0x02000000);
+       clrsetbits_le32(0x0232a410, 0xff000000, 0x1b000000);
+       clrsetbits_le32(0x0232a414, 0x0000ffff, 0x00006fb8);
+       clrsetbits_le32(0x0232a418, 0xffff00ff, 0x758000e4);
+       clrsetbits_le32(0x0232a4ac, 0x0000ff00, 0x00004400);
+       clrsetbits_le32(0x0232a42c, 0x00ffff00, 0x00200800);
+       clrsetbits_le32(0x0232a480, 0x00ff00ff, 0x00820082);
+       clrsetbits_le32(0x0232a484, 0xffffffff, 0x1d0f0385);
+
+       clrsetbits_le32(0x0232a604, 0xff0000ff, 0x38000080);
+       clrsetbits_le32(0x0232a608, 0x000000ff, 0x00000000);
+       clrsetbits_le32(0x0232a60c, 0xff000000, 0x02000000);
+       clrsetbits_le32(0x0232a610, 0xff000000, 0x1b000000);
+       clrsetbits_le32(0x0232a614, 0x0000ffff, 0x00006fb8);
+       clrsetbits_le32(0x0232a618, 0xffff00ff, 0x758000e4);
+       clrsetbits_le32(0x0232a6ac, 0x0000ff00, 0x00004400);
+       clrsetbits_le32(0x0232a62c, 0x00ffff00, 0x00200800);
+       clrsetbits_le32(0x0232a680, 0x00ff00ff, 0x00820082);
+       clrsetbits_le32(0x0232a684, 0xffffffff, 0x1d0f0385);
+
+       clrsetbits_le32(0x0232a804, 0xff0000ff, 0x38000080);
+       clrsetbits_le32(0x0232a808, 0x000000ff, 0x00000000);
+       clrsetbits_le32(0x0232a80c, 0xff000000, 0x02000000);
+       clrsetbits_le32(0x0232a810, 0xff000000, 0x1b000000);
+       clrsetbits_le32(0x0232a814, 0x0000ffff, 0x00006fb8);
+       clrsetbits_le32(0x0232a818, 0xffff00ff, 0x758000e4);
+       clrsetbits_le32(0x0232a8ac, 0x0000ff00, 0x00004400);
+       clrsetbits_le32(0x0232a82c, 0x00ffff00, 0x00200800);
+       clrsetbits_le32(0x0232a880, 0x00ff00ff, 0x00820082);
+       clrsetbits_le32(0x0232a884, 0xffffffff, 0x1d0f0385);
+
+       clrsetbits_le32(0x0232aa00, 0x0000ff00, 0x00000800);
+       clrsetbits_le32(0x0232aa08, 0xffff0000, 0x38a20000);
+       clrsetbits_le32(0x0232aa30, 0x00ffff00, 0x008a8a00);
+       clrsetbits_le32(0x0232aa84, 0x0000ff00, 0x00000600);
+       clrsetbits_le32(0x0232aa94, 0xff000000, 0x10000000);
+       clrsetbits_le32(0x0232aaa0, 0xff000000, 0x81000000);
+       clrsetbits_le32(0x0232aabc, 0xff000000, 0xff000000);
+       clrsetbits_le32(0x0232aac0, 0x000000ff, 0x0000008b);
+       clrsetbits_le32(0x0232ab08, 0xffff0000, 0x583f0000);
+       clrsetbits_le32(0x0232ab0c, 0x000000ff, 0x0000004e);
+       clrsetbits_le32(0x0232a000, 0x000000ff, 0x00000003);
+       clrsetbits_le32(0x0232aa00, 0x000000ff, 0x0000005f);
+
+       clrsetbits_le32(0x0232aa48, 0x00ffff00, 0x00fd8c00);
+       clrsetbits_le32(0x0232aa54, 0x00ffffff, 0x002fec72);
+       clrsetbits_le32(0x0232aa58, 0xffffff00, 0x00f92100);
+       clrsetbits_le32(0x0232aa5c, 0xffffffff, 0x00040060);
+       clrsetbits_le32(0x0232aa60, 0xffffffff, 0x00008000);
+       clrsetbits_le32(0x0232aa64, 0xffffffff, 0x0c581220);
+       clrsetbits_le32(0x0232aa68, 0xffffffff, 0xe13b0602);
+       clrsetbits_le32(0x0232aa6c, 0xffffffff, 0xb8074cc1);
+       clrsetbits_le32(0x0232aa70, 0xffffffff, 0x3f02e989);
+       clrsetbits_le32(0x0232aa74, 0x000000ff, 0x00000001);
+       clrsetbits_le32(0x0232ab20, 0x00ff0000, 0x00370000);
+       clrsetbits_le32(0x0232ab1c, 0xff000000, 0x37000000);
+       clrsetbits_le32(0x0232ab20, 0x000000ff, 0x0000005d);
+
+       /*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/
+       clrbits_le32(0x0232a010, 1 << 28);
+
+       /* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */
+       clrbits_le32(0x0232a228, 1 << 29);
+       writel(0xF800F8C0, 0x0232bfe0);
+       clrbits_le32(0x0232a428, 1 << 29);
+       writel(0xF800F8C0, 0x0232bfe4);
+       clrbits_le32(0x0232a628, 1 << 29);
+       writel(0xF800F8C0, 0x0232bfe8);
+       clrbits_le32(0x0232a828, 1 << 29);
+       writel(0xF800F8C0, 0x0232bfec);
+
+       /*Enable pll via the pll_ctrl 0x0014*/
+       writel(0xe0000000, 0x0232bff4)
+               ;
+
+       /*Waiting for SGMII Serdes PLL lock.*/
+       for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--)
+               ;
+
+       for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--)
+               ;
+
+       for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--)
+               ;
+
+       for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--)
+               ;
+
+       udelay(45000);
+}
+
+void sgmii_serdes_shutdown(void)
+{
+       /*
+        * shutdown SerDes hardware. SerDes hardware vendor published only
+        * register addresses and their values. So had to use hardcoded
+        * values below.
+        */
+       clrbits_le32(0x0232bfe0, 3 << 29 | 3 << 13);
+       setbits_le32(0x02320228, 1 << 29);
+       clrbits_le32(0x0232bfe4, 3 << 29 | 3 << 13);
+       setbits_le32(0x02320428, 1 << 29);
+       clrbits_le32(0x0232bfe8, 3 << 29 | 3 << 13);
+       setbits_le32(0x02320628, 1 << 29);
+       clrbits_le32(0x0232bfec, 3 << 29 | 3 << 13);
+       setbits_le32(0x02320828, 1 << 29);
+
+       clrbits_le32(0x02320034, 3 << 29);
+       setbits_le32(0x02320010, 1 << 28);
+}
index 28a6d722fbb0b6f18d3dfba0bf523e69440829a5..9bb8f342b60318d4e7362aeb5329418fa320f724 100644 (file)
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  20
 #define CONFIG_ENV_EEPROM_IS_ON_I2C
 
+/* Network Configuration */
+#define CONFIG_DRIVER_TI_KEYSTONE_NET
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_NET_RETRY_COUNT                 32
+#define CONFIG_NET_MULTI
+#define CONFIG_GET_LINK_STATUS_ATTEMPTS        5
+#define CONFIG_SYS_SGMII_REFCLK_MHZ            312
+#define CONFIG_SYS_SGMII_LINERATE_MHZ          1250
+#define CONFIG_SYS_SGMII_RATESCALE             2
+
 /* NAND Configuration */
 #define CONFIG_NAND_DAVINCI
 #define CONFIG_SYS_NAND_CS                     2
        "addr_fs=0x82000000\0"                                          \
        "addr_ubi=0x82000000\0"                                         \
        "fdt_high=0xffffffff\0"                                         \
+       "name_fdt=uImage-k2hk-evm.dtb\0"                                \
+       "name_fs=arago-console-image.cpio.gz\0"                         \
+       "name_kern=uImage-keystone-evm.bin\0"                           \
+       "name_mon=skern-keystone-evm.bin\0"                             \
+       "name_uboot=u-boot-spi-keystone-evm.gph\0"                      \
+       "name_ubi=keystone-evm-ubifs.ubi\0"                             \
        "run_mon=mon_install ${addr_mon}\0"                             \
        "run_kern=bootm ${addr_kern} - ${addr_fdt}\0"                   \
+       "init_net=run args_all args_net\0"                              \
        "init_ubi=run args_all args_ubi; "                              \
                "ubi part ubifs; ubifsmount boot\0"                     \
+       "get_fdt_net=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0"       \
        "get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0"               \
+       "get_kern_net=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0"    \
        "get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0"            \
+       "get_mon_net=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0"       \
        "get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0"               \
+       "get_uboot_net=dhcp ${addr_uboot} ${tftp_root}/${name_uboot}\0" \
        "burn_uboot=sf probe; sf erase 0 0x100000; "                    \
                "sf write ${addr_uboot} 0 ${filesize}\0"                \
        "args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0"  \
        "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs "        \
                "root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0"   \
+       "args_net=setenv bootargs ${bootargs} rootfstype=nfs "          \
+               "root=/dev/nfs rw nfsroot=${serverip}:${nfs_root},"     \
+               "${nfs_options} ip=dhcp\0"                              \
+       "nfs_options=v3,tcp,rsize=4096,wsize=4096\0"                    \
+       "get_fdt_ramfs=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0"     \
+       "get_kern_ramfs=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0"  \
+       "get_mon_ramfs=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0"     \
+       "get_fs_ramfs=dhcp ${addr_fs} ${tftp_root}/${name_fs}\0"        \
+       "get_ubi_net=dhcp ${addr_ubi} ${tftp_root}/${name_ubi}\0"       \
        "burn_ubi=nand erase.part ubifs; "                              \
                "nand write ${addr_ubi} ubifs ${filesize}\0"            \
        "init_ramfs=run args_all args_ramfs get_fs_ramfs\0"             \
        "args_ramfs=setenv bootargs ${bootargs} earlyprintk "           \
                "rdinit=/sbin/init rw root=/dev/ram0 "                  \
                "initrd=0x802000000,9M\0"                               \
+       "no_post=1\0"                                                   \
        "mtdparts=mtdparts=davinci_nand.0:"                             \
                "1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
 #define CONFIG_BOOTCOMMAND                                             \