diff mbox

[U-Boot,2/2] ARM: ts4800: add ethernet support

Message ID 1434398325-2902-3-git-send-email-damien.riegel@savoirfairelinux.com
State Changes Requested
Delegated to: Stefano Babic
Headers show

Commit Message

Damien Riegel June 15, 2015, 7:58 p.m. UTC
This commit adds ethernet support to the TS4800. Note that the
MAC address is not fused on this board and have to be read from
FEC PALR PAUR registers (this is how the kernel provided by
Technologic Systems does it).

Signed-off-by: Damien Riegel <damien.riegel@savoirfairelinux.com>
Cc: Stefano Babic <sbabic@denx.de>
---
 arch/arm/include/asm/arch-mx5/iomux-mx51.h |  11 +++
 board/technologic/ts4800/ts4800.c          | 104 +++++++++++++++++++++++++++++
 include/configs/ts4800.h                   |  17 +++++
 3 files changed, 132 insertions(+)
diff mbox

Patch

diff --git a/arch/arm/include/asm/arch-mx5/iomux-mx51.h b/arch/arm/include/asm/arch-mx5/iomux-mx51.h
index 70aaa37..6fb8119 100644
--- a/arch/arm/include/asm/arch-mx5/iomux-mx51.h
+++ b/arch/arm/include/asm/arch-mx5/iomux-mx51.h
@@ -184,8 +184,15 @@  enum {
 	MX51_PAD_DISPB2_SER_DIO__GPIO3_6	= IOMUX_PAD(0x6c0, 0x2c0, 4, 0x98c, 1, MX51_GPIO_PAD_CTRL),
 	MX51_PAD_DI1_PIN3__DI1_PIN3		= IOMUX_PAD(0x72c, 0x32c, 0, __NA_, 0, NO_PAD_CTRL),
 	MX51_PAD_DI1_PIN2__DI1_PIN2		= IOMUX_PAD(0x734, 0x330, 0, __NA_, 0, NO_PAD_CTRL),
+	MX51_PAD_DI2_PIN2__FEC_MDC		= IOMUX_PAD(0x74C, 0x344, 2, __NA_, 0, MX51_PAD_CTRL_5),
 	MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK	= IOMUX_PAD(0x754, 0x34c, 0, __NA_, 0, NO_PAD_CTRL),
 	MX51_PAD_DI_GP4__DI2_PIN15		= IOMUX_PAD(0x758, 0x350, 4, __NA_, 0, NO_PAD_CTRL),
+	MX51_PAD_DISP2_DAT6__FEC_TDAT1		= IOMUX_PAD(0x774, 0x36C, 2, __NA_, 0, MX51_PAD_CTRL_5),
+	MX51_PAD_DISP2_DAT7__FEC_TDAT2		= IOMUX_PAD(0x778, 0x370, 2, __NA_, 0, MX51_PAD_CTRL_5),
+	MX51_PAD_DISP2_DAT8__FEC_TDAT3		= IOMUX_PAD(0x77C, 0x374, 2, __NA_, 0, MX51_PAD_CTRL_5),
+	MX51_PAD_DISP2_DAT9__FEC_TX_EN		= IOMUX_PAD(0x780, 0x378, 2, __NA_, 0, MX51_PAD_CTRL_5),
+	MX51_PAD_DISP2_DAT12__FEC_RX_DV		= IOMUX_PAD(0x78C, 0x384, 2, 0x96c, 0x1, MX51_PAD_CTRL_4),
+	MX51_PAD_DISP2_DAT13__FEC_TX_CLK	= IOMUX_PAD(0x790, 0x388, 2, 0x974, 0x1, MX51_PAD_CTRL_4),
 	MX51_PAD_SD1_CMD__SD1_CMD		= IOMUX_PAD(0x79c, 0x394, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL),
 	MX51_PAD_SD1_CLK__SD1_CLK		= IOMUX_PAD(0x7a0, 0x398, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS),
 	MX51_PAD_SD1_DATA0__SD1_DATA0		= IOMUX_PAD(0x7a4, 0x39c, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL),
@@ -204,6 +211,10 @@  enum {
 	MX51_PAD_GPIO1_2__GPIO1_2		= IOMUX_PAD(0x7d4, 0x3cc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
 	MX51_PAD_GPIO1_2__PWM1_PWMO		= IOMUX_PAD(0x7d4, 0x3cc, 1, __NA_, 0, NO_PAD_CTRL),
 	MX51_PAD_GPIO1_3__GPIO1_3		= IOMUX_PAD(0x7d8, 0x3d0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
+	MX51_PAD_DISP2_DAT10__FEC_COL		= IOMUX_PAD(0x784, 0x37C, 2, 0x94c, 0x1, MX51_PAD_CTRL_2),
+	MX51_PAD_DISP2_DAT11__FEC_RXCLK		= IOMUX_PAD(0x788, 0x380, 2, 0x968, 0x1, MX51_PAD_CTRL_2),
+	MX51_PAD_DISP2_DAT14__FEC_RDAT0		= IOMUX_PAD(0x794, 0x38C, 2, 0x958, 0x1, MX51_PAD_CTRL_4),
+	MX51_PAD_DISP2_DAT15__FEC_TDAT0		= IOMUX_PAD(0x798, 0x390, 2, 0x0, 0, MX51_PAD_CTRL_5),
 	MX51_PAD_GPIO1_5__GPIO1_5		= IOMUX_PAD(0x808, 0x3dc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
 	MX51_PAD_GPIO1_6__GPIO1_6		= IOMUX_PAD(0x80c, 0x3e0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
 	MX51_PAD_GPIO1_7__GPIO1_7		= IOMUX_PAD(0x810, 0x3e4, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
diff --git a/board/technologic/ts4800/ts4800.c b/board/technologic/ts4800/ts4800.c
index e49f185..6b762b2 100644
--- a/board/technologic/ts4800/ts4800.c
+++ b/board/technologic/ts4800/ts4800.c
@@ -21,6 +21,10 @@ 
 #include <fsl_esdhc.h>
 #include <mc13892.h>
 
+#include <malloc.h>
+#include <netdev.h>
+#include <phy.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_FSL_ESDHC
@@ -60,6 +64,36 @@  static void setup_iomux_uart(void)
 	imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
 }
 
+static void setup_iomux_fec(void)
+{
+	static const iomux_v3_cfg_t fec_pads[] = {
+		NEW_PAD_CTRL(MX51_PAD_EIM_EB2__FEC_MDIO,
+				PAD_CTL_HYS |
+				PAD_CTL_PUS_22K_UP |
+				PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST),
+		MX51_PAD_EIM_EB3__FEC_RDATA1,
+		NEW_PAD_CTRL(MX51_PAD_EIM_CS2__FEC_RDATA2, PAD_CTL_HYS),
+		MX51_PAD_EIM_CS3__FEC_RDATA3,
+		MX51_PAD_NANDF_CS2__FEC_TX_ER,
+		MX51_PAD_EIM_CS5__FEC_CRS,
+		MX51_PAD_EIM_CS4__FEC_RX_ER,
+		/* PAD used on TS4800 */
+		MX51_PAD_DI2_PIN2__FEC_MDC,
+		MX51_PAD_DISP2_DAT14__FEC_RDAT0,
+		MX51_PAD_DISP2_DAT10__FEC_COL,
+		MX51_PAD_DISP2_DAT11__FEC_RXCLK,
+		MX51_PAD_DISP2_DAT15__FEC_TDAT0,
+		MX51_PAD_DISP2_DAT6__FEC_TDAT1,
+		MX51_PAD_DISP2_DAT7__FEC_TDAT2,
+		MX51_PAD_DISP2_DAT8__FEC_TDAT3,
+		MX51_PAD_DISP2_DAT9__FEC_TX_EN,
+		MX51_PAD_DISP2_DAT13__FEC_TX_CLK,
+		MX51_PAD_DISP2_DAT12__FEC_RX_DV,
+	};
+
+	imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));
+}
+
 #ifdef CONFIG_FSL_ESDHC
 int board_mmc_getcd(struct mmc *mmc)
 {
@@ -115,6 +149,7 @@  int board_mmc_init(bd_t *bis)
 int board_early_init_f(void)
 {
 	setup_iomux_uart();
+	setup_iomux_fec();
 
 	return 0;
 }
@@ -128,6 +163,75 @@  int board_init(void)
 }
 
 /*
+ * Read the MAC address from FEC's registers PALR PAUR.
+ * User is supposed to configure these registers when MAC address is known
+ * from another source (fuse), but on TS4800, MAC address is not fused and
+ * the bootrom configure these registers on startup.
+ */
+static int fec_get_mac_from_register(uint32_t base_addr)
+{
+	unsigned char ethaddr[6];
+	u32 reg_mac[2];
+	int i;
+
+	reg_mac[0] = in_be32(base_addr + 0xE4);
+	reg_mac[1] = in_be32(base_addr + 0xE8);
+
+	for(i = 0; i < 6; i++)
+		ethaddr[i] = (reg_mac[i / 4] >> ((i % 4) * 8)) & 0xFF;
+
+	if (is_valid_ethaddr(ethaddr)) {
+		eth_setenv_enetaddr("ethaddr", ethaddr);
+		return 0;
+	}
+
+	return -1;
+}
+
+#define TS4800_GPIO_FEC_PHY_RES         IMX_GPIO_NR(2, 14)
+int board_eth_init(bd_t *bd)
+{
+	int dev_id = -1;
+	int phy_id = 0xFF;
+	uint32_t addr = IMX_FEC_BASE;
+
+	uint32_t base_mii;
+	struct mii_dev *bus = NULL;
+	struct phy_device *phydev = NULL;
+	int ret;
+
+	/* reset FEC phy */
+	imx_iomux_v3_setup_pad(MX51_PAD_EIM_A20__GPIO2_14);
+	gpio_direction_output(TS4800_GPIO_FEC_PHY_RES, 0);
+	mdelay(1);
+	gpio_set_value(TS4800_GPIO_FEC_PHY_RES, 1);
+	mdelay(1);
+
+	base_mii = addr;
+	debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
+	bus = fec_get_miibus(base_mii, dev_id);
+	if (!bus)
+		return -ENOMEM;
+
+	phydev = phy_find_by_mask(bus, phy_id, PHY_INTERFACE_MODE_MII);
+	if (!phydev) {
+		free(bus);
+		return -ENOMEM;
+	}
+
+	if (fec_get_mac_from_register(addr))
+		printf("eth_init: failed to get MAC address\n");
+
+	ret = fec_probe(bd, dev_id, addr, bus, phydev);
+	if (ret) {
+		free(phydev);
+		free(bus);
+	}
+
+	return ret;
+}
+
+/*
  * Do not overwrite the console
  * Use always serial for U-Boot console
  */
diff --git a/include/configs/ts4800.h b/include/configs/ts4800.h
index f265968..9cdbee8 100644
--- a/include/configs/ts4800.h
+++ b/include/configs/ts4800.h
@@ -73,6 +73,23 @@ 
 #define CONFIG_CMD_FAT
 #define CONFIG_DOS_PARTITION
 
+/*
+ * Eth Configs
+ */
+#define CONFIG_MII
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_SMSC
+
+#define CONFIG_FEC_MXC
+#define IMX_FEC_BASE			FEC_BASE_ADDR
+#define CONFIG_ETHPRIME		"FEC"
+#define CONFIG_FEC_MXC_PHYADDR	0
+
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NET
+
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE		/* disable vendor parameters protection (serial#, ethaddr) */
 #define CONFIG_CONS_INDEX		1 /* use UART0 : used by serial driver */