summaryrefslogtreecommitdiff
path: root/board/technologic/ts4800/ts4800.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/technologic/ts4800/ts4800.c')
-rw-r--r--board/technologic/ts4800/ts4800.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/board/technologic/ts4800/ts4800.c b/board/technologic/ts4800/ts4800.c
index 0a8d43e4e9..6ef15e10bf 100644
--- a/board/technologic/ts4800/ts4800.c
+++ b/board/technologic/ts4800/ts4800.c
@@ -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;
}
@@ -126,6 +160,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
*/