[U-Boot] [Patch 2/7] TQMa6: mba6: add RGMII enet
Markus Niebel
list-09_u-boot at tqsc.de
Mon Jun 16 12:50:53 CEST 2014
From: Markus Niebel <Markus.Niebel at tqs.de>
Add RGMII ethernet using micrel KSZ9031 phy
to mba6 mainboard for TQMa6<x> module. The phy needs
special configurateions for the pad skew registers
to adjust for the signal routing.
Also support for standard ethernet commands and uppdate
via tftp is supported.
Signed-off-by: Markus Niebel <Markus.Niebel at tq-group.com>
---
board/tqc/tqma6/tqma6_mba6.c | 158 ++++++++++++++++++++++++++++++++++++++++++
include/configs/tqma6.h | 78 ++++++++++++++++++++-
2 files changed, 235 insertions(+), 1 deletion(-)
diff --git a/board/tqc/tqma6/tqma6_mba6.c b/board/tqc/tqma6/tqma6_mba6.c
index 8679db8..c30f379 100644
--- a/board/tqc/tqma6/tqma6_mba6.c
+++ b/board/tqc/tqma6/tqma6_mba6.c
@@ -20,7 +20,11 @@
#include <common.h>
#include <fsl_esdhc.h>
#include <libfdt.h>
+#include <malloc.h>
+#include <micrel.h>
+#include <miiphy.h>
#include <mmc.h>
+#include <netdev.h>
#include "tqma6_bb.h"
@@ -41,6 +45,87 @@ DECLARE_GLOBAL_DATA_PTR;
#define GPIO_IN_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \
PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+#if defined(CONFIG_MX6Q)
+
+#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0790
+#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e07ac
+
+#elif defined(CONFIG_MX6S)
+
+#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0768
+#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e0788
+
+#else
+
+#error "need to define target CPU"
+
+#endif
+
+#define ENET_RX_PAD_CTRL (PAD_CTL_DSE_34ohm)
+#define ENET_TX_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_34ohm)
+#define ENET_CLK_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_34ohm)
+#define ENET_MDIO_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_60ohm)
+
+/* disable on die termination for RGMII */
+#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE 0x00000000
+/* optimised drive strength for 1.0 .. 1.3 V signal on RGMII */
+#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P2V 0x00080000
+/* optimised drive strength for 1.3 .. 2.5 V signal on RGMII */
+#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V 0x000C0000
+
+#define ENET_PHY_RESET_GPIO IMX_GPIO_NR(1, 25)
+
+static iomux_v3_cfg_t const mba6_enet_pads[] = {
+ NEW_PAD_CTRL(MX6_PAD_ENET_MDIO__ENET_MDIO, ENET_MDIO_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_ENET_MDC__ENET_MDC, ENET_MDIO_PAD_CTRL),
+
+ NEW_PAD_CTRL(MX6_PAD_RGMII_TXC__RGMII_TXC, ENET_TX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_TD0__RGMII_TD0, ENET_TX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_TD1__RGMII_TD1, ENET_TX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_TD2__RGMII_TD2, ENET_TX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_TD3__RGMII_TD3, ENET_TX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL, ENET_TX_PAD_CTRL),
+
+ NEW_PAD_CTRL(MX6_PAD_ENET_REF_CLK__ENET_TX_CLK, ENET_CLK_PAD_CTRL),
+ /*
+ * these pins are also used for config strapping by phy
+ */
+ NEW_PAD_CTRL(MX6_PAD_RGMII_RD0__RGMII_RD0, ENET_RX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_RD1__RGMII_RD1, ENET_RX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_RD2__RGMII_RD2, ENET_RX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_RD3__RGMII_RD3, ENET_RX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_RXC__RGMII_RXC, ENET_RX_PAD_CTRL),
+ NEW_PAD_CTRL(MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL, ENET_RX_PAD_CTRL),
+ /* KSZ9031 PHY Reset */
+ NEW_PAD_CTRL(MX6_PAD_ENET_CRS_DV__GPIO1_IO25, GPIO_OUT_PAD_CTRL),
+};
+
+static void mba6_setup_iomuxc_enet(void)
+{
+ __raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE,
+ (void *)IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM);
+ __raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V,
+ (void *)IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII);
+
+ imx_iomux_v3_setup_multiple_pads(mba6_enet_pads,
+ ARRAY_SIZE(mba6_enet_pads));
+
+ /* Reset PHY */
+ gpio_direction_output(ENET_PHY_RESET_GPIO , 0);
+ /* Need delay 10ms after power on according to KSZ9031 spec */
+ udelay(1000 * 10);
+ gpio_set_value(ENET_PHY_RESET_GPIO, 1);
+ /*
+ * KSZ9031 manual: 100 usec wait time after reset before communication
+ * over MDIO
+ * BUGBUG: hardware has an RC const that needs > 10 msec from 0->1 on
+ * reset before the phy sees a high level
+ */
+ udelay(200);
+}
+
static iomux_v3_cfg_t const mba6_uart2_pads[] = {
NEW_PAD_CTRL(MX6_PAD_SD4_DAT4__UART2_RX_DATA, UART_PAD_CTRL),
NEW_PAD_CTRL(MX6_PAD_SD4_DAT7__UART2_TX_DATA, UART_PAD_CTRL),
@@ -115,6 +200,76 @@ int tqma6_bb_board_mmc_init(bd_t *bis)
return 0;
}
+int board_phy_config(struct phy_device *phydev)
+{
+#if defined(CONFIG_MX6Q)
+#define MBA6X_KSZ9031_CTRL_SKEW 0x0032
+#define MBA6X_KSZ9031_CLK_SKEW 0x03ff
+#define MBA6X_KSZ9031_RX_SKEW 0x3333
+#define MBA6X_KSZ9031_TX_SKEW 0x2036
+#elif defined(CONFIG_MX6S)
+#define MBA6X_KSZ9031_CTRL_SKEW 0x0030
+#define MBA6X_KSZ9031_CLK_SKEW 0x03ff
+#define MBA6X_KSZ9031_RX_SKEW 0x3333
+#define MBA6X_KSZ9031_TX_SKEW 0x2052
+#else
+#error
+#endif
+ /* min rx/tx ctrl delay */
+ ksz9031_phy_extended_write(phydev, 2,
+ MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
+ MII_KSZ9031_MOD_DATA_NO_POST_INC,
+ MBA6X_KSZ9031_CTRL_SKEW);
+ /* min rx delay */
+ ksz9031_phy_extended_write(phydev, 2,
+ MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
+ MII_KSZ9031_MOD_DATA_NO_POST_INC,
+ MBA6X_KSZ9031_RX_SKEW);
+ /* max tx delay */
+ ksz9031_phy_extended_write(phydev, 2,
+ MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
+ MII_KSZ9031_MOD_DATA_NO_POST_INC,
+ MBA6X_KSZ9031_TX_SKEW);
+ /* rx/tx clk skew */
+ ksz9031_phy_extended_write(phydev, 2,
+ MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
+ MII_KSZ9031_MOD_DATA_NO_POST_INC,
+ MBA6X_KSZ9031_CLK_SKEW);
+
+ phydev->drv->config(phydev);
+
+ return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+ uint32_t base = IMX_FEC_BASE;
+ struct mii_dev *bus = NULL;
+ struct phy_device *phydev = NULL;
+ int ret;
+
+ bus = fec_get_miibus(base, -1);
+ if (!bus)
+ return 0;
+ /* scan phy */
+ phydev = phy_find_by_mask(bus, (0xf << CONFIG_FEC_MXC_PHYADDR),
+ PHY_INTERFACE_MODE_RGMII);
+
+ if (!phydev) {
+ free(bus);
+ printf("No phy found\n");
+ return 0;
+ }
+ ret = fec_probe(bis, -1, base, bus, phydev);
+ if (ret) {
+ printf("FEC MXC: %s:failed\n", __func__);
+ free(phydev);
+ free(bus);
+ }
+
+ return 0;
+}
+
int tqma6_bb_board_early_init_f(void)
{
mba6_setup_iomuxc_uart();
@@ -124,6 +279,9 @@ int tqma6_bb_board_early_init_f(void)
int tqma6_bb_board_init(void)
{
+ /* do it here - to have reset completed */
+ mba6_setup_iomuxc_enet();
+
return 0;
}
diff --git a/include/configs/tqma6.h b/include/configs/tqma6.h
index 9e5d21d..5f7b1a9 100644
--- a/include/configs/tqma6.h
+++ b/include/configs/tqma6.h
@@ -65,6 +65,37 @@
#define CONFIG_CMD_FAT
#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NET
+
+#define CONFIG_FEC_MXC
+#define IMX_FEC_BASE ENET_BASE_ADDR
+#define CONFIG_PHYLIB
+#define CONFIG_MII
+
+#if defined(CONFIG_MBA6)
+
+#define CONFIG_FEC_XCV_TYPE RGMII
+#define CONFIG_ETHPRIME "FEC"
+
+#define CONFIG_FEC_MXC_PHYADDR 0x03
+#define CONFIG_PHY_MICREL
+#define CONFIG_PHY_KSZ9031
+
+#else
+
+#error "define PHY to use for your baseboard"
+
+#endif
+
+#define CONFIG_ARP_TIMEOUT 200UL
+/* Network config - Allow larger/faster download for TFTP/NFS */
+#define CONFIG_IP_DEFRAG
+#define CONFIG_TFTP_BLOCKSIZE 4096
+#define CONFIG_NFS_READ_SIZE 4096
+
#if defined(CONFIG_MBA6)
#define CONFIG_MXC_UART_BASE UART2_BASE
@@ -129,9 +160,43 @@
"mmc read ${loadaddr} ${kernel_start} ${kernel_size};\0" \
"loadfdt=mmc dev ${mmcdev}; " \
"mmc read ${fdt_addr} ${fdt_start} ${fdt_size};\0" \
+ "update_uboot=if tftp ${uboot}; then " \
+ "if itest ${filesize} > 0; then " \
+ "mmc dev ${mmcdev}; mmc rescan; " \
+ "setexpr blkc ${filesize} / 0x200; " \
+ "setexpr blkc ${blkc} + 1; " \
+ "if itest ${blkc} <= ${uboot_size}; then " \
+ "mmc write ${loadaddr} ${uboot_start} " \
+ "${blkc}; " \
+ "fi; " \
+ "fi; fi; " \
+ "setenv filesize; setenv blkc \0" \
+ "update_kernel=run kernel_name; " \
+ "if tftp ${kernel}; then " \
+ "if itest ${filesize} > 0; then " \
+ "mmc dev ${mmcdev}; mmc rescan; " \
+ "setexpr blkc ${filesize} / 0x200; " \
+ "setexpr blkc ${blkc} + 1; " \
+ "if itest ${blkc} <= ${kernel_size}; then " \
+ "mmc write ${loadaddr} " \
+ "${kernel_start} ${blkc}; " \
+ "fi; " \
+ "fi; " \
+ "fi; " \
+ "setenv filesize; setenv blkc \0" \
+ "update_fdt=if tftp ${fdt}; then " \
+ "if itest ${filesize} > 0; then " \
+ "mmc dev ${mmcdev}; mmc rescan; " \
+ "setexpr blkc ${filesize} / 0x200; " \
+ "setexpr blkc ${blkc} + 1; " \
+ "if itest ${blkc} <= ${fdt_size}; then " \
+ "mmc write ${loadaddr} ${fdt_start} ${blkc}; " \
+ "fi; " \
+ "fi; fi; " \
+ "setenv filesize; setenv blkc \0" \
#define CONFIG_BOOTCOMMAND \
- "run mmcboot; run panicboot"
+ "run mmcboot; run netboot; run panicboot"
#else
@@ -175,6 +240,17 @@
"${boot_type}; " \
"fi;\0" \
"setenv bootargs \0" \
+ "netboot=echo Booting from net ...; " \
+ "run kernel_name; " \
+ "run set_getcmd; " \
+ "setenv bootargs; " \
+ "run netargs; " \
+ "if ${getcmd} ${kernel}; then " \
+ "if ${getcmd} ${fdt_addr} ${fdt}; then " \
+ "${boot_type} ${loadaddr} - ${fdt_addr}; " \
+ "fi; " \
+ "fi; " \
+ "echo ... failed\0" \
"panicboot=echo No boot device !!! reset\0" \
CONFIG_EXTRA_BOOTDEV_ENV_SETTINGS \
--
1.7.9.5
More information about the U-Boot
mailing list