[U-Boot] [PATCH v2 2/2] ARM:AM33XX:Added cpsw support for AM335x EVM
Chandan Nath
chandan.nath at ti.com
Thu Nov 10 13:40:29 CET 2011
This patch adds cpsw support on AM335X EVM.
Signed-off-by: Chandan Nath <chandan.nath at ti.com>
---
Changes since v1:
- Added weak alias miiphy_is_1000base_x function to fix atheros phy issue
arch/arm/cpu/armv7/am33xx/clock.c | 9 ++-
arch/arm/include/asm/arch-am33xx/cpu.h | 22 ++++-
arch/arm/include/asm/arch-am33xx/hardware.h | 5 +
board/ti/am335x/common_def.h | 2 +
board/ti/am335x/evm.c | 149 +++++++++++++++++++++++++++
board/ti/am335x/mux.c | 24 +++++
common/miiphyutil.c | 5 +-
drivers/net/cpsw.c | 147 ++++++++++++++++++--------
include/configs/am335x_evm.h | 16 +++-
include/netdev.h | 19 +++-
10 files changed, 341 insertions(+), 57 deletions(-)
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
index 4ca6c45..73b1408 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -24,6 +24,7 @@
#define PRCM_MOD_EN 0x2
#define PRCM_FORCE_WAKEUP 0x2
+#define PRCM_FUNCTL 0x0
#define PRCM_EMIF_CLK_ACTIVITY BIT(2)
#define PRCM_L3_GCLK_ACTIVITY BIT(4)
@@ -38,7 +39,7 @@
#define CLK_MODE_SEL 0x7
#define CLK_MODE_MASK 0xfffffff8
#define CLK_DIV_SEL 0xFFFFFFE0
-
+#define CPGMAC0_IDLE 0x30000
const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
@@ -105,6 +106,12 @@ static void enable_per_clocks(void)
writel(PRCM_MOD_EN, &cmwkup->wkup_uart0ctrl);
while (readl(&cmwkup->wkup_uart0ctrl) != PRCM_MOD_EN)
;
+
+ /* Ethernet */
+ writel(PRCM_MOD_EN, &cmper->cpgmac0clkctrl);
+ writel(PRCM_MOD_EN, &cmper->cpswclkstctrl);
+ while ((readl(&cmper->cpgmac0clkctrl) & CPGMAC0_IDLE) != PRCM_FUNCTL)
+ ;
}
static void mpu_pll_config(void)
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index ad9156e..e255dd9 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -108,7 +108,9 @@ struct cm_perpll {
unsigned int l3sclkstctrl; /* offset 0x04 */
unsigned int l4fwclkstctrl; /* offset 0x08 */
unsigned int l3clkstctrl; /* offset 0x0c */
- unsigned int resv1[6];
+ unsigned int resv0[1];
+ unsigned int cpgmac0clkctrl; /* offset 0x14 */
+ unsigned int resv1[4];
unsigned int emifclkctrl; /* offset 0x28 */
unsigned int ocmcramclkctrl; /* offset 0x2c */
unsigned int resv2[12];
@@ -124,6 +126,8 @@ struct cm_perpll {
unsigned int resv6[14];
unsigned int l4hsclkstctrl; /* offset 0x11C */
unsigned int l4hsclkctrl; /* offset 0x120 */
+ unsigned int resv7[8];
+ unsigned int cpswclkstctrl; /* offset 0x144 */
};
/* Encapsulating Display pll registers */
@@ -173,9 +177,9 @@ struct timer_reg {
/* Timer 32 bit registers */
struct gptimer {
unsigned int tidr; /* offset 0x00 */
- unsigned int res1[0xc];
+ unsigned int res1[3];
unsigned int tiocp_cfg; /* offset 0x10 */
- unsigned int res2[0xc];
+ unsigned int res2[3];
unsigned int tier; /* offset 0x20 */
unsigned int tistatr; /* offset 0x24 */
unsigned int tistat; /* offset 0x28 */
@@ -211,6 +215,18 @@ struct ctrl_stat {
unsigned int statusreg; /* ofset 0x40 */
};
+/* Control Device Register */
+struct ctrl_dev {
+ unsigned int deviceid; /* offset 0x00 */
+ unsigned int resv1[11];
+ unsigned int macid0l; /* offset 0x30 */
+ unsigned int macid0h; /* offset 0x34 */
+ unsigned int macid1l; /* offset 0x38 */
+ unsigned int macid1h; /* offset 0x3c */
+ unsigned int resv2[4];
+ unsigned int miisel; /* offset 0x50 */
+};
+
void init_timer(void);
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL_STRICT_NAMES */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h
index 0ec22eb..4b1c725 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -46,6 +46,7 @@
/* Control Module Base Address */
#define CTRL_BASE 0x44E10000
+#define CTRL_DEVICE_BASE 0x44E10600
/* PRCM Base Address */
#define PRCM_BASE 0x44E00000
@@ -78,4 +79,8 @@
#define DDRPHY_0_CONFIG_BASE (CTRL_BASE + 0x1400)
#define DDRPHY_CONFIG_BASE DDRPHY_0_CONFIG_BASE
+/* CPSW Config space */
+#define AM335X_CPSW_BASE 0x4A100000
+#define AM335X_CPSW_MDIO_BASE 0x4A101000
+
#endif /* __AM33XX_HARDWARE_H */
diff --git a/board/ti/am335x/common_def.h b/board/ti/am335x/common_def.h
index 1696d60..01cda88 100644
--- a/board/ti/am335x/common_def.h
+++ b/board/ti/am335x/common_def.h
@@ -17,8 +17,10 @@
#define __COMMON_DEF_H__
extern void enable_uart0_pin_mux(void);
+extern void enable_rgmii1_pin_mux(void);
extern void configure_evm_pin_mux(unsigned char daughter_board_id,
unsigned short daughter_board_profile,
unsigned char daughter_board_flag);
+extern void cpsw_eth_set_mac_addr(const unsigned char *addr);
#endif/*__COMMON_DEF_H__ */
diff --git a/board/ti/am335x/evm.c b/board/ti/am335x/evm.c
index b4eddd8..993d2a1 100644
--- a/board/ti/am335x/evm.c
+++ b/board/ti/am335x/evm.c
@@ -18,6 +18,8 @@
#include <asm/arch/hardware.h>
#include "common_def.h"
#include <serial.h>
+#include <miiphy.h>
+#include <netdev.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -25,6 +27,12 @@ DECLARE_GLOBAL_DATA_PTR;
#define UART_CLK_RUNNING_MASK 0x1
#define UART_SMART_IDLE_EN (0x1 << 0x3)
+/* RGMII mode define */
+#define RGMII_MODE_ENABLE 0xA
+#define ETH_ALEN 6
+
+struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
/*
* Basic board specific setup
*/
@@ -42,7 +50,148 @@ int init_basic_setup(void)
int board_init(void)
{
enable_uart0_pin_mux();
+ enable_rgmii1_pin_mux();
init_basic_setup();
return 0;
}
+
+#ifdef CONFIG_DRIVER_TI_CPSW
+/* Atheros PHY report 1000baseX speed incorrectly and so this function
+ * is define to overcome this issue. The original code is kept as
+ * _miiphy_is_1000base_x as an weak alias to this function.
+ */
+int miiphy_is_1000base_x(const char *devname, unsigned char addr)
+{
+ return 0;
+}
+
+/* TODO : Check for the board specific PHY */
+static void evm_phy_init(char *name, int addr)
+{
+ unsigned short val;
+ unsigned int cntr = 0;
+
+ /* Enable Autonegotiation */
+ if (miiphy_read(name, addr, MII_BMCR, &val) != 0) {
+ printf("failed to read bmcr\n");
+ return;
+ }
+
+ val |= BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100;
+ if (miiphy_write(name, addr, MII_BMCR, val) != 0) {
+ printf("failed to write bmcr\n");
+ return;
+ }
+ miiphy_read(name, addr, MII_BMCR, &val);
+
+ /* TODO: Disable GIG advertisement for the time being */
+ miiphy_read(name, addr, MII_CTRL1000, &val);
+ val |= PHY_1000BTCR_1000FD;
+ val &= ~PHY_1000BTCR_1000HD;
+ miiphy_write(name, addr, MII_CTRL1000, val);
+ miiphy_read(name, addr, MII_CTRL1000, &val);
+
+ /* Setup general advertisement */
+ if (miiphy_read(name, addr, MII_ADVERTISE, &val) != 0) {
+ printf("failed to read anar\n");
+ return;
+ }
+ val |= (LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL);
+ if (miiphy_write(name, addr, MII_ADVERTISE, val) != 0) {
+ printf("failed to write anar\n");
+ return;
+ }
+ miiphy_read(name, addr, MII_ADVERTISE, &val);
+
+ /* Restart auto negotiation*/
+ miiphy_read(name, addr, MII_BMCR, &val);
+ val |= BMCR_ANRESTART;
+ miiphy_write(name, addr, MII_BMCR, val);
+
+ /*check AutoNegotiate complete - it can take upto 3 secs*/
+ do {
+ udelay(40000);
+ cntr++;
+ if (!miiphy_read(name, addr, MII_BMSR, &val)) {
+ if (val & BMSR_ANEGCOMPLETE)
+ break;
+ }
+ } while (cntr < 1000);
+
+ if (cntr >= 1000)
+ printf("Auto negotitation failed\n");
+
+ return;
+}
+
+static void cpsw_control(int enabled)
+{
+ /* nothing for now */
+ /* TODO : VTP was here before */
+ return;
+}
+
+static struct cpsw_slave_data cpsw_slaves[] = {
+ {
+ .slave_reg_ofs = 0x208,
+ .sliver_reg_ofs = 0xd80,
+ .phy_id = 0,
+ },
+ {
+ .slave_reg_ofs = 0x308,
+ .sliver_reg_ofs = 0xdc0,
+ .phy_id = 1,
+ },
+};
+
+static struct cpsw_platform_data cpsw_data = {
+ .mdio_base = AM335X_CPSW_MDIO_BASE,
+ .cpsw_base = AM335X_CPSW_BASE,
+ .mdio_div = 0xff,
+ .channels = 8,
+ .cpdma_reg_ofs = 0x800,
+ .slaves = 1,
+ .slave_data = cpsw_slaves,
+ .ale_reg_ofs = 0xd00,
+ .ale_entries = 1024,
+ .host_port_reg_ofs = 0x108,
+ .hw_stats_reg_ofs = 0x900,
+ .mac_control = (1 << 5),
+ .control = cpsw_control,
+ .phy_init = evm_phy_init,
+ .host_port_num = 0,
+ .version = CPSW_CTRL_VERSION_2,
+};
+
+int board_eth_init(bd_t *bis)
+{
+ uint8_t mac_addr[6];
+ uint32_t mac_hi, mac_lo;
+
+ if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
+ debug("<ethaddr> not set. Reading from E-fuse\n");
+ /* try reading mac address from efuse */
+ mac_lo = readl(&cdev->macid0l);
+ mac_hi = readl(&cdev->macid0h);
+ mac_addr[0] = mac_hi & 0xFF;
+ mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+ mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+ mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+ mac_addr[4] = mac_lo & 0xFF;
+ mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+
+ if (is_valid_ether_addr(mac_addr)) {
+ eth_setenv_enetaddr("ethaddr", mac_addr);
+ } else {
+ printf("Caution: Using hardcoded mac address. "
+ "Set <ethaddr> variable to overcome this.\n");
+ }
+ }
+
+ /* set mii mode to rgmii in in device configure register */
+ writel(RGMII_MODE_ENABLE, &cdev->miisel);
+
+ return cpsw_register(&cpsw_data);
+}
+#endif
diff --git a/board/ti/am335x/mux.c b/board/ti/am335x/mux.c
index 8f27409..3cda206 100644
--- a/board/ti/am335x/mux.c
+++ b/board/ti/am335x/mux.c
@@ -258,6 +258,24 @@ static struct module_pin_mux uart0_pin_mux[] = {
{-1},
};
+static struct module_pin_mux rgmii1_pin_mux[] = {
+ {OFFSET(mii1_txen), MODE(2)}, /* RGMII1_TCTL */
+ {OFFSET(mii1_rxdv), MODE(2) | RXACTIVE}, /* RGMII1_RCTL */
+ {OFFSET(mii1_txd3), MODE(2)}, /* RGMII1_TD3 */
+ {OFFSET(mii1_txd2), MODE(2)}, /* RGMII1_TD2 */
+ {OFFSET(mii1_txd1), MODE(2)}, /* RGMII1_TD1 */
+ {OFFSET(mii1_txd0), MODE(2)}, /* RGMII1_TD0 */
+ {OFFSET(mii1_txclk), MODE(2)}, /* RGMII1_TCLK */
+ {OFFSET(mii1_rxclk), MODE(2) | RXACTIVE}, /* RGMII1_RCLK */
+ {OFFSET(mii1_rxd3), MODE(2) | RXACTIVE}, /* RGMII1_RD3 */
+ {OFFSET(mii1_rxd2), MODE(2) | RXACTIVE}, /* RGMII1_RD2 */
+ {OFFSET(mii1_rxd1), MODE(2) | RXACTIVE}, /* RGMII1_RD1 */
+ {OFFSET(mii1_rxd0), MODE(2) | RXACTIVE}, /* RGMII1_RD0 */
+ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN},/* MDIO_DATA */
+ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
+ {-1},
+};
+
/*
* Configure the pin mux for the module
*/
@@ -276,3 +294,9 @@ void enable_uart0_pin_mux(void)
{
configure_module_pin_mux(uart0_pin_mux);
}
+
+
+void enable_rgmii1_pin_mux(void)
+{
+ configure_module_pin_mux(rgmii1_pin_mux);
+}
diff --git a/common/miiphyutil.c b/common/miiphyutil.c
index 35ad357..dd56fda 100644
--- a/common/miiphyutil.c
+++ b/common/miiphyutil.c
@@ -548,7 +548,7 @@ miiphy_read_failed:
* Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
* 1000BASE-T, or on error.
*/
-int miiphy_is_1000base_x(const char *devname, unsigned char addr)
+static int __miiphy_is_1000base_x(const char *devname, unsigned char addr)
{
#if defined(CONFIG_PHY_GIGE)
u16 exsr;
@@ -564,6 +564,9 @@ int miiphy_is_1000base_x(const char *devname, unsigned char addr)
#endif
}
+int miiphy_is_1000base_x(const char *devname, unsigned char addr)
+ __attribute__((weak, alias("__miiphy_is_1000base_x")));
+
#ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
/*****************************************************************************
*
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 4cef4cf..c41eeaf 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -1,22 +1,16 @@
/*
* CPSW Ethernet Switch Driver
*
- * See file CREDITS for list of people who contributed to this
- * project.
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*
- * 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 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 version 2.
*
- * 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
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; 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.
*/
#include <common.h>
@@ -28,9 +22,7 @@
#include <netdev.h>
#include <asm/errno.h>
#include <asm/io.h>
-#include <linux/mii.h>
-#define BIT(x) (1 << (x))
#define BITMASK(bits) (BIT(bits) - 1)
#define PHY_REG_MASK 0x1f
#define PHY_ID_MASK 0x1f
@@ -43,10 +35,15 @@
#define CPDMA_RXCONTROL 0x014
#define CPDMA_SOFTRESET 0x01c
#define CPDMA_RXFREE 0x0e0
-#define CPDMA_TXHDP 0x100
-#define CPDMA_RXHDP 0x120
-#define CPDMA_TXCP 0x140
-#define CPDMA_RXCP 0x160
+#define CPDMA_TXHDP_VER1 0x100
+#define CPDMA_TXHDP_VER2 0x200
+#define CPDMA_RXHDP_VER1 0x120
+#define CPDMA_RXHDP_VER2 0x220
+#define CPDMA_TXCP_VER1 0x140
+#define CPDMA_TXCP_VER2 0x240
+#define CPDMA_RXCP_VER1 0x160
+#define CPDMA_RXCP_VER2 0x260
+
/* Descriptor mode bits */
#define CPDMA_DESC_SOP BIT(31)
@@ -252,12 +249,12 @@ static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \
DEFINE_ALE_FIELD(entry_type, 60, 2)
DEFINE_ALE_FIELD(mcast_state, 62, 2)
-DEFINE_ALE_FIELD(port_mask, 64, 3)
-DEFINE_ALE_FIELD(ucast_type, 66, 2)
-DEFINE_ALE_FIELD(port_num, 64, 2)
-DEFINE_ALE_FIELD(blocked, 63, 1)
-DEFINE_ALE_FIELD(secure, 62, 1)
-DEFINE_ALE_FIELD(mcast, 47, 1)
+DEFINE_ALE_FIELD(port_mask, 66, 3)
+DEFINE_ALE_FIELD(ucast_type, 62, 2)
+DEFINE_ALE_FIELD(port_num, 66, 2)
+DEFINE_ALE_FIELD(blocked, 65, 1)
+DEFINE_ALE_FIELD(secure, 64, 1)
+DEFINE_ALE_FIELD(mcast, 40, 1)
/* The MAC address field in the ALE entry cannot be macroized as above */
static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
@@ -452,7 +449,7 @@ static inline void wait_for_idle(void)
;
}
-static int cpsw_mdio_read(char *devname, unsigned char phy_id,
+static int cpsw_mdio_read(const char *devname, unsigned char phy_id,
unsigned char phy_reg, unsigned short *data)
{
u32 reg;
@@ -470,7 +467,7 @@ static int cpsw_mdio_read(char *devname, unsigned char phy_id,
return (reg & USERACCESS_ACK) ? 0 : -EIO;
}
-static int cpsw_mdio_write(char *devname, unsigned char phy_id,
+static int cpsw_mdio_write(const char *devname, unsigned char phy_id,
unsigned char phy_reg, unsigned short data)
{
u32 reg;
@@ -502,6 +499,7 @@ static void cpsw_mdio_init(char *name, u32 mdio_base, u32 div)
* silicon. Since the effect of (b) was found to be largely
* negligible, we keep things simple here.
*/
+
udelay(1000);
miiphy_register(name, cpsw_mdio_read, cpsw_mdio_write);
@@ -514,6 +512,20 @@ static inline void soft_reset(void *reg)
;
}
+static u_int8_t cpsw_eth_mac_addr[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x66 };
+
+/*
+ * This function must be called before cpsw_init() if you want to override
+ * the default mac address.
+ */
+void cpsw_eth_set_mac_addr(const u_int8_t *addr)
+{
+ int i;
+
+ for (i = 0; i < sizeof(cpsw_eth_mac_addr); i++)
+ cpsw_eth_mac_addr[i] = addr[i];
+}
+
#define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \
((mac)[2] << 16) | ((mac)[3] << 24))
#define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8))
@@ -547,6 +559,8 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
mac_control |= BIT(7); /* GIGABITEN */
if (duplex == FULL)
mac_control |= BIT(0); /* FULLDUPLEXEN */
+ if (speed == 100)
+ mac_control |= BIT(15);
}
if (mac_control == slave->mac_control)
@@ -571,8 +585,17 @@ static int cpsw_update_link(struct cpsw_priv *priv)
return link;
}
+static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
+{
+ if (priv->host_port == 0)
+ return slave_num + 1;
+ else
+ return slave_num;
+}
+
static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
{
+ u32 slave_port;
soft_reset(&slave->sliver->soft_reset);
/* setup priority mapping */
@@ -586,9 +609,10 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
slave->mac_control = 0; /* no link yet */
/* enable forwarding */
- cpsw_ale_port_state(priv, slave->slave_num, ALE_PORT_STATE_FORWARD);
+ slave_port = cpsw_get_slave_port(priv, slave->slave_num);
+ cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD);
- cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave->slave_num);
+ cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port);
priv->data.phy_init(priv->dev->name, slave->data->phy_id);
}
@@ -708,7 +732,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
__raw_writel(BIT(priv->host_port), &priv->regs->stat_port_en);
cpsw_ale_port_state(priv, priv->host_port, ALE_PORT_STATE_FORWARD);
-
+ memcpy(priv->dev->enetaddr, cpsw_eth_mac_addr, 6);
cpsw_ale_add_ucast(priv, priv->dev->enetaddr, priv->host_port,
ALE_SECURE);
cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << priv->host_port);
@@ -725,25 +749,58 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
priv->desc_free = &priv->descs[0];
/* initialize channels */
- memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
- priv->rx_chan.hdp = priv->dma_regs + CPDMA_RXHDP;
- priv->rx_chan.cp = priv->dma_regs + CPDMA_RXCP;
- priv->rx_chan.rxfree = priv->dma_regs + CPDMA_RXFREE;
-
- memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
- priv->tx_chan.hdp = priv->dma_regs + CPDMA_TXHDP;
- priv->tx_chan.cp = priv->dma_regs + CPDMA_TXCP;
+ if (priv->data.version == CPSW_CTRL_VERSION_2) {
+ memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
+ priv->rx_chan.hdp = priv->dma_regs + CPDMA_RXHDP_VER2;
+ priv->rx_chan.cp = priv->dma_regs + CPDMA_RXCP_VER2;
+ priv->rx_chan.rxfree = priv->dma_regs + CPDMA_RXFREE;
+
+ memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
+ priv->tx_chan.hdp = priv->dma_regs + CPDMA_TXHDP_VER2;
+ priv->tx_chan.cp = priv->dma_regs + CPDMA_TXCP_VER2;
+ } else {
+ memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
+ priv->rx_chan.hdp = priv->dma_regs + CPDMA_RXHDP_VER1;
+ priv->rx_chan.cp = priv->dma_regs + CPDMA_RXCP_VER1;
+ priv->rx_chan.rxfree = priv->dma_regs + CPDMA_RXFREE;
+
+ memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
+ priv->tx_chan.hdp = priv->dma_regs + CPDMA_TXHDP_VER1;
+ priv->tx_chan.cp = priv->dma_regs + CPDMA_TXCP_VER1;
+ }
/* clear dma state */
soft_reset(priv->dma_regs + CPDMA_SOFTRESET);
- for (i = 0; i < priv->data.channels; i++) {
- __raw_writel(0, priv->dma_regs + CPDMA_RXHDP + 4 * i);
- __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4 * i);
- __raw_writel(0, priv->dma_regs + CPDMA_RXCP + 4 * i);
- __raw_writel(0, priv->dma_regs + CPDMA_TXHDP + 4 * i);
- __raw_writel(0, priv->dma_regs + CPDMA_TXCP + 4 * i);
+ if (priv->data.version == CPSW_CTRL_VERSION_2) {
+ for (i = 0; i < priv->data.channels; i++) {
+ __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4
+ * i);
+ __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
+ * i);
+ __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER2 + 4
+ * i);
+ __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER2 + 4
+ * i);
+ __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER2 + 4
+ * i);
+ }
+ } else {
+ for (i = 0; i < priv->data.channels; i++) {
+ __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4
+ * i);
+ __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
+ * i);
+ __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER1 + 4
+ * i);
+ __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER1 + 4
+ * i);
+ __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER1 + 4
+ * i);
+
+ }
}
+
__raw_writel(1, priv->dma_regs + CPDMA_TXCONTROL);
__raw_writel(1, priv->dma_regs + CPDMA_RXCONTROL);
@@ -838,7 +895,7 @@ int cpsw_register(struct cpsw_platform_data *data)
return -ENOMEM;
}
- priv->host_port = data->slaves;
+ priv->host_port = data->host_port_num;
priv->regs = regs;
priv->host_port_regs = regs + data->host_port_reg_ofs;
priv->dma_regs = regs + data->cpdma_reg_ofs;
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index b471c9b..18844db 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -21,7 +21,6 @@
#undef CONFIG_GZIP
#undef CONFIG_ZLIB
#undef CONFIG_SYS_HUSH_PARSER
-#undef CONFIG_CMD_NET
#include <asm/arch/cpu.h>
#include <asm/arch/hardware.h>
@@ -116,6 +115,21 @@
#define CONFIG_SYS_TEXT_BASE 0x402f0400
+# define CONFIG_CMD_NET
+# define CONFIG_CMD_DHCP
+# define CONFIG_CMD_PING
+# define CONFIG_DRIVER_TI_CPSW
+# define CONFIG_MII
+# define CONFIG_BOOTP_DEFAULT
+# define CONFIG_BOOTP_DNS
+# define CONFIG_BOOTP_DNS2
+# define CONFIG_BOOTP_SEND_HOSTNAME
+# define CONFIG_BOOTP_GATEWAY
+# define CONFIG_BOOTP_SUBNETMASK
+# define CONFIG_NET_RETRY_COUNT 10
+# define CONFIG_NET_MULTI
+# define CONFIG_PHY_GIGE
+
/* Unsupported features */
#undef CONFIG_USE_IRQ
diff --git a/include/netdev.h b/include/netdev.h
index 740213e..b8c12ae 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -193,21 +193,28 @@ struct cpsw_slave_data {
int phy_id;
};
+enum {
+ CPSW_CTRL_VERSION_1 = 0, /* version1 devices */
+ CPSW_CTRL_VERSION_2 /* version2 devices */
+};
+
struct cpsw_platform_data {
u32 mdio_base;
u32 cpsw_base;
int mdio_div;
- int channels; /* number of cpdma channels (symmetric) */
- u32 cpdma_reg_ofs; /* cpdma register offset */
- int slaves; /* number of slave cpgmac ports */
- u32 ale_reg_ofs; /* address lookup engine reg offset */
- int ale_entries; /* ale table size */
+ int channels; /* number of cpdma channels (symmetric) */
+ u32 cpdma_reg_ofs; /* cpdma register offset */
+ int slaves; /* number of slave cpgmac ports */
+ u32 ale_reg_ofs; /* address lookup engine reg offset */
+ int ale_entries; /* ale table size */
u32 host_port_reg_ofs; /* cpdma host port registers */
u32 hw_stats_reg_ofs; /* cpsw hw stats counters */
u32 mac_control;
- struct cpsw_slave_data *slave_data;
+ struct cpsw_slave_data *slave_data;
void (*control)(int enabled);
void (*phy_init)(char *name, int addr);
+ u32 host_port_num;
+ u8 version;
};
int cpsw_register(struct cpsw_platform_data *data);
--
1.7.1
More information about the U-Boot
mailing list