[U-Boot] [PATCH] ti816x: Enable ethernet support

Tom Rini trini at konsulko.com
Wed Jun 28 16:12:03 UTC 2017


The ti816x SoC revision of the ethernet IP block is handled by the
"davinci_emac" driver, rather than the "cpsw" driver as done by later
members of the family.  Enable the relevant plumbing.

Signed-off-by: Sriramakrishnan <srk at ti.com>
Signed-off-by: Vitaly Wool <vitaly.wool at konsulko.com>
Signed-off-by: Tom Rini <trini at konsulko.com>
---
 arch/arm/include/asm/arch-am33xx/emac_defs.h       | 38 ++++++++++++++
 arch/arm/include/asm/arch-am33xx/hardware_ti816x.h |  1 +
 board/ti/ti816x/evm.c                              | 28 ++++++++++
 configs/ti816x_evm_defconfig                       |  5 ++
 drivers/net/davinci_emac.c                         | 60 ++++++++++++++--------
 drivers/net/davinci_emac.h                         |  2 +
 include/configs/ti816x_evm.h                       |  9 ++++
 7 files changed, 122 insertions(+), 21 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-am33xx/emac_defs.h

diff --git a/arch/arm/include/asm/arch-am33xx/emac_defs.h b/arch/arm/include/asm/arch-am33xx/emac_defs.h
new file mode 100644
index 000000000000..b5703f710f42
--- /dev/null
+++ b/arch/arm/include/asm/arch-am33xx/emac_defs.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * Based on:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.h
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ */
+
+#ifndef _EMAC_DEFS_H_
+#define _EMAC_DEFS_H_
+
+#ifdef CONFIG_TI816X
+#define EMAC_BASE_ADDR			(0x4A100000)
+#define EMAC_WRAPPER_BASE_ADDR		(0x4A100900)
+#define EMAC_WRAPPER_RAM_ADDR		(0x4A102000)
+#define EMAC_MDIO_BASE_ADDR		(0x4A100800)
+#define EMAC_MDIO_BUS_FREQ		(250000000UL)
+#define EMAC_MDIO_CLOCK_FREQ		(2000000UL)
+
+typedef volatile unsigned int	dv_reg;
+typedef volatile unsigned int	*dv_reg_p;
+
+#define DAVINCI_EMAC_VERSION2
+#define DAVINCI_EMAC_GIG_ENABLE
+#endif
+
+#endif  /* _EMAC_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_ti816x.h b/arch/arm/include/asm/arch-am33xx/hardware_ti816x.h
index 3c680649abfa..78b79486ed47 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware_ti816x.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware_ti816x.h
@@ -31,6 +31,7 @@
 
 /* Control Module Base Address */
 #define CTRL_BASE		0x48140000
+#define CTRL_DEVICE_BASE	0x48140600
 
 /* PRCM Base Address */
 #define PRCM_BASE		0x48180000
diff --git a/board/ti/ti816x/evm.c b/board/ti/ti816x/evm.c
index 577e60f875f4..9d6c3d6b5dc9 100644
--- a/board/ti/ti816x/evm.c
+++ b/board/ti/ti816x/evm.c
@@ -9,6 +9,7 @@
 
 #include <common.h>
 #include <spl.h>
+#include <netdev.h>
 #include <asm/cache.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
@@ -31,6 +32,33 @@ int board_init(void)
 	return 0;
 }
 
+int board_eth_init(bd_t *bis)
+{
+	uint8_t mac_addr[6];
+	uint32_t mac_hi, mac_lo;
+	struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+	if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
+		printf("<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_ethaddr(mac_addr))
+			eth_setenv_enetaddr("ethaddr", mac_addr);
+		else
+			printf("Unable to read MAC address. Set <ethaddr>\n");
+	}
+
+	return davinci_emac_initialize();
+}
+
 #ifdef CONFIG_SPL_BUILD
 static struct module_pin_mux mmc_pin_mux[] = {
 	{ OFFSET(pincntl157), PULLDOWN_EN | PULLUDDIS | MODE(0x0) },
diff --git a/configs/ti816x_evm_defconfig b/configs/ti816x_evm_defconfig
index 1c6608218b00..7f43ecb7ebc2 100644
--- a/configs/ti816x_evm_defconfig
+++ b/configs/ti816x_evm_defconfig
@@ -35,6 +35,11 @@ CONFIG_OF_CONTROL=y
 CONFIG_DM=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_FAT=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SYS_NS16550=y
 # CONFIG_USE_PRIVATE_LIBGCC is not set
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 5e7ebc8a99f3..d1024879a0ef 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -341,6 +341,14 @@ static int gen_auto_negotiate(int phy_addr)
 	if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
 		return(0);
 
+#ifdef DAVINCI_EMAC_GIG_ENABLE
+	davinci_eth_phy_read(phy_addr, MII_CTRL1000, &val);
+	val |= PHY_1000BTCR_1000FD;
+	val &= ~PHY_1000BTCR_1000HD;
+	davinci_eth_phy_write(phy_addr, MII_CTRL1000, val);
+	davinci_eth_phy_read(phy_addr, MII_CTRL1000, &val);
+#endif
+
 	/* Restart Auto_negotiation  */
 	tmp |= BMCR_ANRESTART;
 	davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
@@ -407,7 +415,8 @@ static void  __attribute__((unused)) davinci_eth_gigabit_enable(int phy_addr)
 static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 {
 	dv_reg_p		addr;
-	u_int32_t		clkdiv, cnt;
+	u_int32_t		clkdiv, cnt, mac_control;
+	uint16_t		__maybe_unused lpa_val;
 	volatile emac_desc	*rx_desc;
 	int			index;
 
@@ -488,19 +497,6 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	/* Enable ch 0 only */
 	writel(1, &adap_emac->RXUNICASTSET);
 
-	/* Enable MII interface and Full duplex mode */
-#if defined(CONFIG_SOC_DA8XX) || \
-	(defined(CONFIG_OMAP34XX) && defined(CONFIG_DRIVER_TI_EMAC_USE_RMII))
-	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
-		EMAC_MACCONTROL_FULLDUPLEX_ENABLE |
-		EMAC_MACCONTROL_RMIISPEED_100),
-	       &adap_emac->MACCONTROL);
-#else
-	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
-		EMAC_MACCONTROL_FULLDUPLEX_ENABLE),
-	       &adap_emac->MACCONTROL);
-#endif
-
 	/* Init MDIO & get link state */
 	clkdiv = CONFIG_SYS_EMAC_TI_CLKDIV;
 	writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
@@ -513,8 +509,26 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	if (index == -1)
 		return(0);
 
-	emac_gigabit_enable(active_phy_addr[index]);
+	/* Enable MII interface */
+	mac_control = EMAC_MACCONTROL_MIIEN_ENABLE;
+#ifdef DAVINCI_EMAC_GIG_ENABLE
+	davinci_eth_phy_read(active_phy_addr[index], MII_STAT1000, &lpa_val);
+	if (lpa_val & PHY_1000BTSR_1000FD) {
+		debug_emac("eth_open : gigabit negotiated\n");
+		mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+		mac_control |= EMAC_MACCONTROL_GIGABIT_ENABLE;
+	}
+#endif
 
+	davinci_eth_phy_read(active_phy_addr[index], MII_LPA, &lpa_val);
+	if (lpa_val & (LPA_100FULL | LPA_10FULL))
+		/* set EMAC for Full Duplex  */
+		mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
+#if defined(CONFIG_SOC_DA8XX) || \
+	(defined(CONFIG_OMAP34XX) && defined(CONFIG_DRIVER_TI_EMAC_USE_RMII))
+	mac_control |= EMAC_MACCONTROL_RMIISPEED_100;
+#endif
+	writel(mac_control, &adap_emac->MACCONTROL);
 	/* Start receive process */
 	writel(BD_TO_HW((u_int32_t)emac_rx_desc), &adap_emac->RX0HDP);
 
@@ -619,8 +633,6 @@ static int davinci_eth_send_packet (struct eth_device *dev,
 		return (ret_status);
 	}
 
-	emac_gigabit_enable(active_phy_addr[index]);
-
 	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
 	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
 		length = EMAC_MIN_ETHERNET_PKT_SIZE;
@@ -648,8 +660,6 @@ static int davinci_eth_send_packet (struct eth_device *dev,
 			return (ret_status);
 		}
 
-		emac_gigabit_enable(active_phy_addr[index]);
-
 		if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
 			ret_status = length;
 			break;
@@ -870,11 +880,19 @@ int davinci_emac_initialize(void)
 		retval = mdio_register(mdiodev);
 		if (retval < 0)
 			return retval;
+#ifdef DAVINCI_EMAC_GIG_ENABLE
+#define PHY_CONF_REG	22
+		/* Enable PHY to clock out TX_CLK */
+		davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
+		tmp |= PHY_CONF_TXCLKEN;
+		davinci_eth_phy_write(active_phy_addr[i], PHY_CONF_REG, tmp);
+		davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
+#endif
 	}
 
-#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
+#if defined(CONFIG_TI816X) || (defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
 		defined(CONFIG_MACH_DAVINCI_DA850_EVM) && \
-			!defined(CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE)
+			!defined(CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE))
 	for (i = 0; i < num_phy; i++) {
 		if (phy[i].is_phy_connected(i))
 			phy[i].auto_negotiate(i);
diff --git a/drivers/net/davinci_emac.h b/drivers/net/davinci_emac.h
index 13cd68f040b9..e2ed54bac54d 100644
--- a/drivers/net/davinci_emac.h
+++ b/drivers/net/davinci_emac.h
@@ -40,6 +40,8 @@
 
 /* MII Status Register */
 #define MII_STATUS_REG			1
+/* PHY Configuration register */
+#define PHY_CONF_TXCLKEN		(1 << 5)
 
 /* Number of statistics registers */
 #define EMAC_NUM_STATS			36
diff --git a/include/configs/ti816x_evm.h b/include/configs/ti816x_evm.h
index defcad451880..4a81b1daf84e 100644
--- a/include/configs/ti816x_evm.h
+++ b/include/configs/ti816x_evm.h
@@ -123,6 +123,15 @@
 
 #define CONFIG_SYS_TEXT_BASE        0x80800000
 
+#define CONFIG_DRIVER_TI_EMAC
+#define CONFIG_MII
+#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
+
 /* Since SPL did pll and ddr initialization for us,
  * we don't need to do it twice.
  */
-- 
1.9.1



More information about the U-Boot mailing list