ARM: ts4800: add ethernet support
authorDamien Riegel <damien.riegel@savoirfairelinux.com>
Tue, 30 Jun 2015 21:17:48 +0000 (17:17 -0400)
committerStefano Babic <sbabic@denx.de>
Wed, 2 Sep 2015 13:26:13 +0000 (15:26 +0200)
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
board/technologic/ts4800/ts4800.c
include/configs/ts4800.h

index 70aaa37f9d5c5f72078e54097ef9c4457ed0b121..b7b169505f91c4a213be59efca47e8a5aed770e7 100644 (file)
@@ -184,8 +184,19 @@ 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_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_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_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_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),
index 0a8d43e4e944b82cd8508a752ea99f8e36b67c64..6ef15e10bf6fde6e07a411112dec2eb801145bd9 100644 (file)
@@ -21,6 +21,9 @@
 #include <fsl_esdhc.h>
 #include <mc13892.h>
 
+#include <malloc.h>
+#include <netdev.h>
+#include <phy.h>
 #include "ts4800.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -62,6 +65,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)
 {
@@ -113,6 +146,7 @@ int board_mmc_init(bd_t *bis)
 int board_early_init_f(void)
 {
        setup_iomux_uart();
+       setup_iomux_fec();
 
        return 0;
 }
@@ -125,6 +159,75 @@ int board_init(void)
        return 0;
 }
 
+/*
+ * 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
index d3722fa073367794851876e9cc4eab9896c91d7e..21f1555eb79de4dc57cd86f7338e8b55452e64f5 100644 (file)
 #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
+
 /* 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 */