[U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver

Murali Karicheri m-karicheri2 at ti.com
Thu Feb 20 18:55:12 CET 2014


From: Vitaly Andrianov <vitalya at ti.com>

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 at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
Signed-off-by: WingMan Kwok <w-kwok2 at ti.com>
---
 - updated based on review comments
 arch/arm/include/asm/arch-keystone/emac_defs.h |  250 +++++++
 board/ti/k2hk_evm/board.c                      |   65 ++
 drivers/net/Makefile                           |    1 +
 drivers/net/keystone_net.c                     |  859 ++++++++++++++++++++++++
 include/configs/k2hk_evm.h                     |   38 ++
 5 files changed, 1213 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h
 create mode 100644 drivers/net/keystone_net.c

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
index 0000000..9c1c5bc
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/emac_defs.h
@@ -0,0 +1,250 @@
+/*
+ * 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 chipLmbd(x,y) _lmbd(x,y) */
+
+#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];
+};
+
+struct phy_t {
+	char	name[64];
+	int	(*init)(int phy_addr);
+	int	(*is_phy_connected)(int phy_addr);
+	int	(*get_link_speed)(int phy_addr);
+	int	(*auto_negotiate)(int phy_addr);
+};
+
+#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_ */
diff --git a/board/ti/k2hk_evm/board.c b/board/ti/k2hk_evm/board.c
index 14dc7e4..81f5ca4 100644
--- a/board/ti/k2hk_evm/board.c
+++ b/board/ti/k2hk_evm/board.c
@@ -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)
 {
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 7f9ce90..6005f7e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -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
index 0000000..473a4b1
--- /dev/null
+++ b/drivers/net/keystone_net.c
@@ -0,0 +1,859 @@
+/*
+ * 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;
+#define debug_emac(fmt, args...) if (emac_dbg) printf(fmt, ##args)
+
+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_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);
+
+static int marvell_88e1111_init_phy(int phy_addr);
+static int marvell_88e1111_is_phy_connected(int phy_addr);
+static int marvell_88e1111_get_link_speed(int phy_addr);
+static int marvell_88e1111_auto_negotiate(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;
+
+struct phy_t phy;
+
+static void chip_delay(u32 del)
+{
+	volatile unsigned int i;
+
+	for (i = 0; i < (del / 8); i++)
+		;
+}
+
+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 __attribute__((unused)) 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 __attribute__((unused)) gen_is_phy_connected(int phy_addr)
+{
+	u_int16_t	dummy;
+
+	return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
+}
+
+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 int __attribute__((unused)) gen_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+		return -1;
+
+	/* Restart Auto_negotiation  */
+	tmp |= BMCR_ANENABLE;
+	keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay(10000);
+	if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+		return -1;
+
+	if (!(tmp & BMSR_ANEGCOMPLETE))
+		return 0;
+
+	return gen_get_link_speed(phy_addr);
+}
+
+/* PHY functions for Marvell 88E1111 PHY */
+static int marvell_88e1111_init_phy(int phy_addr)
+{
+	int	ret = -1;
+
+	if (!marvell_88e1111_get_link_speed(phy_addr)) {
+		/* Try another time */
+		ret = marvell_88e1111_get_link_speed(phy_addr);
+	}
+
+	return ret;
+}
+
+static int marvell_88e1111_is_phy_connected(int phy_addr)
+{
+	u_int16_t	dummy;
+
+	return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
+}
+
+static int marvell_88e1111_get_link_speed(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
+	    (tmp & MII_STATUS_LINK_MASK)) {
+		return 0;
+	}
+
+	return -1;
+}
+
+static int marvell_88e1111_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+		return -1;
+
+	/* Restart Auto_negotiation  */
+	tmp |= BMCR_ANENABLE;
+	keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay(10000);
+	if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+		return -1;
+
+	if (!(tmp & BMSR_ANEGCOMPLETE))
+		return 0;
+
+	return marvell_88e1111_get_link_speed(phy_addr);
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int keystone2_mii_phy_read(const char *devname, unsigned char addr,
+				  unsigned char reg, unsigned short *value)
+{
+	return keystone2_eth_phy_read(addr, reg, value) ? -1 : 0;
+}
+
+static int keystone2_mii_phy_write(const char *devname, unsigned char addr,
+				 unsigned char reg, unsigned short value)
+{
+	return keystone2_eth_phy_write(addr, reg, value) ? -1 : 0;
+}
+#endif
+
+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 (phy.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("+ 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("- emac_open\n");
+
+	emac_open = 1;
+
+	return 0;
+}
+
+/* Eth device close */
+void keystone2_eth_close(struct eth_device *dev)
+{
+	debug_emac("+ emac_close\n");
+
+	if (!emac_open)
+		return;
+
+	ethss_stop();
+
+	netcp_close();
+	qm_close();
+
+	emac_open = 0;
+
+	debug_emac("- 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. 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.
+ */
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
+{
+	struct eth_device *dev;
+	static int phy_registered;
+
+	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);
+
+	if (sys_has_mdio && !phy_registered) {
+		phy_registered = 1;
+#ifdef CONFIG_ETH_PHY_MARVEL_88E1111
+		sprintf(phy.name, "88E1111");
+		phy.init = marvell_88e1111_init_phy;
+		phy.is_phy_connected = marvell_88e1111_is_phy_connected;
+		phy.get_link_speed = marvell_88e1111_get_link_speed;
+		phy.auto_negotiate = marvell_88e1111_auto_negotiate;
+#else
+		sprintf(phy.name, "GENERIC");
+		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;
+#endif
+		miiphy_register(phy.name, keystone2_mii_phy_read,
+				keystone2_mii_phy_write);
+	}
+
+	return 0;
+}
+
+#define reg_rmw(addr, value, mask) \
+	writel(((readl(addr) & (~(mask))) | (value)), (addr))
+
+void sgmii_serdes_setup_156p25mhz()
+{
+	unsigned int cnt;
+
+	reg_rmw(0x0232a000, 0x00800000, 0xffff0000);
+	reg_rmw(0x0232a014, 0x00008282, 0x0000ffff);
+	reg_rmw(0x0232a060, 0x00142438, 0x00ffffff);
+	reg_rmw(0x0232a064, 0x00c3c700, 0x00ffff00);
+	reg_rmw(0x0232a078, 0x0000c000, 0x0000ff00);
+
+	reg_rmw(0x0232a204, 0x38000080, 0xff0000ff);
+	reg_rmw(0x0232a208, 0x00000000, 0x000000ff);
+	reg_rmw(0x0232a20c, 0x02000000, 0xff000000);
+	reg_rmw(0x0232a210, 0x1b000000, 0xff000000);
+	reg_rmw(0x0232a214, 0x00006fb8, 0x0000ffff);
+	reg_rmw(0x0232a218, 0x758000e4, 0xffff00ff);
+	reg_rmw(0x0232a2ac, 0x00004400, 0x0000ff00);
+	reg_rmw(0x0232a22c, 0x00200800, 0x00ffff00);
+	reg_rmw(0x0232a280, 0x00820082, 0x00ff00ff);
+	reg_rmw(0x0232a284, 0x1d0f0385, 0xffffffff);
+
+	reg_rmw(0x0232a404, 0x38000080, 0xff0000ff);
+	reg_rmw(0x0232a408, 0x00000000, 0x000000ff);
+	reg_rmw(0x0232a40c, 0x02000000, 0xff000000);
+	reg_rmw(0x0232a410, 0x1b000000, 0xff000000);
+	reg_rmw(0x0232a414, 0x00006fb8, 0x0000ffff);
+	reg_rmw(0x0232a418, 0x758000e4, 0xffff00ff);
+	reg_rmw(0x0232a4ac, 0x00004400, 0x0000ff00);
+	reg_rmw(0x0232a42c, 0x00200800, 0x00ffff00);
+	reg_rmw(0x0232a480, 0x00820082, 0x00ff00ff);
+	reg_rmw(0x0232a484, 0x1d0f0385, 0xffffffff);
+
+	reg_rmw(0x0232a604, 0x38000080, 0xff0000ff);
+	reg_rmw(0x0232a608, 0x00000000, 0x000000ff);
+	reg_rmw(0x0232a60c, 0x02000000, 0xff000000);
+	reg_rmw(0x0232a610, 0x1b000000, 0xff000000);
+	reg_rmw(0x0232a614, 0x00006fb8, 0x0000ffff);
+	reg_rmw(0x0232a618, 0x758000e4, 0xffff00ff);
+	reg_rmw(0x0232a6ac, 0x00004400, 0x0000ff00);
+	reg_rmw(0x0232a62c, 0x00200800, 0x00ffff00);
+	reg_rmw(0x0232a680, 0x00820082, 0x00ff00ff);
+	reg_rmw(0x0232a684, 0x1d0f0385, 0xffffffff);
+
+	reg_rmw(0x0232a804, 0x38000080, 0xff0000ff);
+	reg_rmw(0x0232a808, 0x00000000, 0x000000ff);
+	reg_rmw(0x0232a80c, 0x02000000, 0xff000000);
+	reg_rmw(0x0232a810, 0x1b000000, 0xff000000);
+	reg_rmw(0x0232a814, 0x00006fb8, 0x0000ffff);
+	reg_rmw(0x0232a818, 0x758000e4, 0xffff00ff);
+	reg_rmw(0x0232a8ac, 0x00004400, 0x0000ff00);
+	reg_rmw(0x0232a82c, 0x00200800, 0x00ffff00);
+	reg_rmw(0x0232a880, 0x00820082, 0x00ff00ff);
+	reg_rmw(0x0232a884, 0x1d0f0385, 0xffffffff);
+
+	reg_rmw(0x0232aa00, 0x00000800, 0x0000ff00);
+	reg_rmw(0x0232aa08, 0x38a20000, 0xffff0000);
+	reg_rmw(0x0232aa30, 0x008a8a00, 0x00ffff00);
+	reg_rmw(0x0232aa84, 0x00000600, 0x0000ff00);
+	reg_rmw(0x0232aa94, 0x10000000, 0xff000000);
+	reg_rmw(0x0232aaa0, 0x81000000, 0xff000000);
+	reg_rmw(0x0232aabc, 0xff000000, 0xff000000);
+	reg_rmw(0x0232aac0, 0x0000008b, 0x000000ff);
+	reg_rmw(0x0232ab08, 0x583f0000, 0xffff0000);
+	reg_rmw(0x0232ab0c, 0x0000004e, 0x000000ff);
+	reg_rmw(0x0232a000, 0x00000003, 0x000000ff);
+	reg_rmw(0x0232aa00, 0x0000005f, 0x000000ff);
+
+	reg_rmw(0x0232aa48, 0x00fd8c00, 0x00ffff00);
+	reg_rmw(0x0232aa54, 0x002fec72, 0x00ffffff);
+	reg_rmw(0x0232aa58, 0x00f92100, 0xffffff00);
+	reg_rmw(0x0232aa5c, 0x00040060, 0xffffffff);
+	reg_rmw(0x0232aa60, 0x00008000, 0xffffffff);
+	reg_rmw(0x0232aa64, 0x0c581220, 0xffffffff);
+	reg_rmw(0x0232aa68, 0xe13b0602, 0xffffffff);
+	reg_rmw(0x0232aa6c, 0xb8074cc1, 0xffffffff);
+	reg_rmw(0x0232aa70, 0x3f02e989, 0xffffffff);
+	reg_rmw(0x0232aa74, 0x00000001, 0x000000ff);
+	reg_rmw(0x0232ab20, 0x00370000, 0x00ff0000);
+	reg_rmw(0x0232ab1c, 0x37000000, 0xff000000);
+	reg_rmw(0x0232ab20, 0x0000005d, 0x000000ff);
+
+	/*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/
+	reg_rmw(0x0232a010, 0x00000000, 1 << 28);
+
+	/* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */
+	reg_rmw(0x0232a228, 0x00000000, 1 << 29);
+	writel(0xF800F8C0, 0x0232bfe0);
+	reg_rmw(0x0232a428, 0x00000000, 1 << 29);
+	writel(0xF800F8C0, 0x0232bfe4);
+	reg_rmw(0x0232a628, 0x00000000, 1 << 29);
+	writel(0xF800F8C0, 0x0232bfe8);
+	reg_rmw(0x0232a828, 0x00000000, 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--)
+		;
+
+	chip_delay(45000);
+}
+
+void sgmii_serdes_shutdown()
+{
+	reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);
+	reg_rmw(0x02320228, 1 << 29, 1 << 29);
+	reg_rmw(0x0232bfe4, 0, 3 << 29 | 3 << 13);
+	reg_rmw(0x02320428, 1 << 29, 1 << 29);
+	reg_rmw(0x0232bfe8, 0, 3 << 29 | 3 << 13);
+	reg_rmw(0x02320628, 1 << 29, 1 << 29);
+	reg_rmw(0x0232bfec, 0, 3 << 29 | 3 << 13);
+	reg_rmw(0x02320828, 1 << 29, 1 << 29);
+
+	reg_rmw(0x02320034, 0, 3 << 29);
+	reg_rmw(0x02320010, 1 << 28, 1 << 28);
+}
+
diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h
index 985db8e..33c7551 100644
--- a/include/configs/k2hk_evm.h
+++ b/include/configs/k2hk_evm.h
@@ -106,6 +106,23 @@
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  20
 #define CONFIG_ENV_EEPROM_IS_ON_I2C
 
+/* Network Configuration */
+#define CONFIG_ETH_PHY_MARVEL_88E1111
+
+#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
@@ -179,24 +196,45 @@
 	"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						\
-- 
1.7.9.5



More information about the U-Boot mailing list