Skip to contentSkip to conversation

imx: clock support enet2 anatop clock support

PATCH New Peng Fan 2 participants 4 messages Aug 12, 2015

Subsystems (2)
lore
Share & tools
lore

Peng Fan

author
#0 lore raw

PATCH v2 1/3 imx: clock support enet2 anatop clock support

To i.MX6SX/UL, two ethernet interfaces are supported.
Add ENET2 clock support:
1. Introduce a new input parameter "fec_id", only 0 and 1 are allowed. To value 1, only i.MX6SX/UL can pass the check.
2. Modify board code who use this api to follow new api prototype.

Cc Heiko Schocher <[email protected]>
Cc Fabio Estevam <[email protected]>
Cc Stefan Roese <[email protected]>
Cc Nikolaos Pasaloukos <[email protected]>
Cc Stefano Babic <[email protected]>

---

Changes v2:
Addressed Fabio's comments. Using "fec_id == 0", but not "0 == fec_id".

 arch/arm/cpu/armv7/mx6/clock.c                | 23 ++++++++++++++++++-----
 arch/arm/include/asm/arch-mx6/clock.h         |  2 +-
 arch/arm/include/asm/arch-mx6/crm_regs.h      |  6 ++++++
 board/aristainetos/aristainetos-v1.c          |  2 +-
 board/barco/platinum/platinum_picon.c         |  2 +-
 board/freescale/mx6qsabreauto/mx6qsabreauto.c |  2 +-
 board/freescale/mx6slevk/mx6slevk.c           |  2 +-
 board/freescale/mx6sxsabresd/mx6sxsabresd.c   |  2 +-
 board/solidrun/mx6cuboxi/mx6cuboxi.c          |  2 +-
 9 files changed, 31 insertions(+), 12 deletions(-)
arch/arm/cpu/armv7/mx6/clock.c +18 -5
index 9cf4eec..ba6cc75 100644
@@ -524,7 +524,7 @@ void enable_qspi_clk(int qspi_num)
 #endif
 
 #ifdef CONFIG_FEC_MXC
-int enable_fec_anatop_clock(enum enet_freq freq)
+int enable_fec_anatop_clock(int fec_id, enum enet_freq freq)
 {
 	u32 reg = 0;
 	s32 timeout = 100000;
@@ -535,9 +535,19 @@ int enable_fec_anatop_clock(enum enet_freq freq)
 	if (freq < ENET_25MHZ || freq > ENET_125MHZ)
 		return -EINVAL;
 
-	reg = readl(&anatop->pll_enet);
-	reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
-	reg |= freq;
+	if (fec_id == 0) {
+		reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
+		reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq);
+	} else if (fec_id == 1) {
+		/* Only i.MX6SX/UL support ENET2 */
+		if (!(is_cpu_type(MXC_CPU_MX6SX) ||
+		      is_cpu_type(MXC_CPU_MX6UL)))
+			return -EINVAL;
+		reg &= ~BM_ANADIG_PLL_ENET2_DIV_SELECT;
+		reg |= BF_ANADIG_PLL_ENET2_DIV_SELECT(freq);
+	} else {
+		return -EINVAL;
+	}
 
 	if ((reg & BM_ANADIG_PLL_ENET_POWERDOWN) ||
 	    (!(reg & BM_ANADIG_PLL_ENET_LOCK))) {
@@ -552,7 +562,10 @@ int enable_fec_anatop_clock(enum enet_freq freq)
 	}
 
 	/* Enable FEC clock */
-	reg |= BM_ANADIG_PLL_ENET_ENABLE;
+	if (fec_id == 0)
+		reg |= BM_ANADIG_PLL_ENET_ENABLE;
+	else
+		reg |= BM_ANADIG_PLL_ENET2_ENABLE;
 	reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
 	writel(reg, &anatop->pll_enet);
 
arch/arm/include/asm/arch-mx6/clock.h +1 -1
index 7b3bbb8..2b220d6 100644
@@ -64,7 +64,7 @@ int enable_pcie_clock(void);
 int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
 int enable_spi_clk(unsigned char enable, unsigned spi_num);
 void enable_ipu_clock(void);
-int enable_fec_anatop_clock(enum enet_freq freq);
+int enable_fec_anatop_clock(int fec_id, enum enet_freq freq);
 void enable_enet_clk(unsigned char enable);
 void enable_qspi_clk(int qspi_num);
 void enable_thermal_clk(void);
arch/arm/include/asm/arch-mx6/crm_regs.h +6 -0
index fe75da4..10306cd 100644
@@ -1052,6 +1052,12 @@ struct mxc_ccm_reg {
 #define BF_ANADIG_PLL_ENET_DIV_SELECT(v)  \
 	(((v) << 0) & BM_ANADIG_PLL_ENET_DIV_SELECT)
 
+/* ENET2 for i.MX6SX/UL */
+#define BM_ANADIG_PLL_ENET2_ENABLE 0x00100000
+#define BM_ANADIG_PLL_ENET2_DIV_SELECT 0x0000000C
+#define BF_ANADIG_PLL_ENET2_DIV_SELECT(v)  \
+	(((v) << 2) & BM_ANADIG_PLL_ENET2_DIV_SELECT)
+
 #define BM_ANADIG_PFD_480_PFD3_CLKGATE 0x80000000
 #define BM_ANADIG_PFD_480_PFD3_STABLE 0x40000000
 #define BP_ANADIG_PFD_480_PFD3_FRAC      24
board/aristainetos/aristainetos-v1.c +1 -1
index d6a7614..b8fed2e 100644
@@ -185,7 +185,7 @@ int board_eth_init(bd_t *bis)
 	/* clear gpr1[14], gpr1[18:17] to select anatop clock */
 	clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC_MASK, 0);
 
-	ret = enable_fec_anatop_clock(ENET_50MHZ);
+	ret = enable_fec_anatop_clock(0, ENET_50MHZ);
 	if (ret)
 		return ret;
 
board/barco/platinum/platinum_picon.c +1 -1
index b2eab76..0384a26 100644
@@ -148,7 +148,7 @@ int platinum_setup_enet(void)
 	/* set GPIO_16 as ENET_REF_CLK_OUT */
 	setbits_le32(&iomux->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK);
 
-	return enable_fec_anatop_clock(ENET_50MHZ);
+	return enable_fec_anatop_clock(0, ENET_50MHZ);
 }
 
 int platinum_setup_i2c(void)
board/freescale/mx6qsabreauto/mx6qsabreauto.c +1 -1
index 98602f8..7c0e90a 100644
@@ -361,7 +361,7 @@ static void setup_fec(void)
 		 * select ENET MAC0 TX clock from PLL
 		 */
 		imx_iomux_set_gpr_register(5, 9, 1, 1);
-		enable_fec_anatop_clock(ENET_125MHZ);
+		enable_fec_anatop_clock(0, ENET_125MHZ);
 	}
 
 	setup_iomux_enet();
board/freescale/mx6slevk/mx6slevk.c +1 -1
index 7c18c90..98e3ef0 100644
@@ -279,7 +279,7 @@ static int setup_fec(void)
 	/* clear gpr1[14], gpr1[18:17] to select anatop clock */
 	clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC_MASK, 0);
 
-	return enable_fec_anatop_clock(ENET_50MHZ);
+	return enable_fec_anatop_clock(0, ENET_50MHZ);
 }
 #endif
 
board/freescale/mx6sxsabresd/mx6sxsabresd.c +1 -1
index d58a79a..ffc0046 100644
@@ -170,7 +170,7 @@ static int setup_fec(void)
 	reg |= BM_ANADIG_PLL_ENET_REF_25M_ENABLE;
 	writel(reg, &anatop->pll_enet);
 
-	return enable_fec_anatop_clock(ENET_125MHZ);
+	return enable_fec_anatop_clock(0, ENET_125MHZ);
 }
 
 int board_eth_init(bd_t *bis)
board/solidrun/mx6cuboxi/mx6cuboxi.c +1 -1
index 9b1ecf0..8247e43 100644
@@ -164,7 +164,7 @@ int board_eth_init(bd_t *bis)
 	struct mii_dev *bus;
 	struct phy_device *phydev;
 
-	int ret = enable_fec_anatop_clock(ENET_25MHZ);
+	int ret = enable_fec_anatop_clock(0, ENET_25MHZ);
 	if (ret)
 		return ret;
 
Signature · 1 line
1.8.4
author
#1 lore raw

PATCH v2 2/3 net: fec: do not access reserved register for i.MX6UL

The MIB RAM and FIFO receive start register does not exist on i.MX6UL. Accessing these register will cause enet not work well.

Cc Joe Hershberger <[email protected]>
Cc Stefano Babic <[email protected]>

---

Changes v2:
Using runtime check, but not hardcoding "#ifdef". This patch depends on the runtime checking patch:
https://patchwork.ozlabs.org/patch/505621/.

 drivers/net/fec_mxc.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/net/fec_mxc.c +9 -5
index c5dcbbb..bff5fd1 100644
@@ -17,6 +17,7 @@
 
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/imx-common/sys_proto.h>
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <linux/compiler.h>
@@ -551,12 +552,15 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 	writel(0x00000000, &fec->eth->gaddr2);
 
 
-	/* clear MIB RAM */
-	for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4)
-		writel(0, i);
+	/* Do not access reserved register for i.MX6UL */
+	if (!is_cpu_type(MXC_CPU_MX6UL)) {
+		/* clear MIB RAM */
+		for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4)
+			writel(0, i);
 
-	/* FIFO receive start register */
-	writel(0x520, &fec->eth->r_fstart);
+		/* FIFO receive start register */
+		writel(0x520, &fec->eth->r_fstart);
+	}
 
 	/* size and address of each buffer */
 	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);
Signature · 1 line
1.8.4
author
#2 lore raw

PATCH v2 3/3 imx: mx6ul_14x14_evk add ENET support

In reply to Peng Fan

Add enet support for mx6ul_14x14_evk board:
1. add pinmux settings
2. implement board_eth_init
3. implement board_phy_config

Cc Stefano Babic <[email protected]>
Cc Fabio Estevam <[email protected]>

---

Changes v2:
Addressed Fabio's comments, using "fec_id == 0", but not "0 == fec_id".

 board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c | 110 ++++++++++++++++++++++
 configs/mx6ul_14x14_evk_defconfig                 |   3 +
 include/configs/mx6ul_14x14_evk.h                 |  21 +++++
 3 files changed, 134 insertions(+)
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +110 -0
index 8f712cb..d9af220 100644
@@ -19,8 +19,10 @@
 #include <common.h>
 #include <fsl_esdhc.h>
 #include <i2c.h>
+#include <miiphy.h>
 #include <linux/sizes.h>
 #include <mmc.h>
+#include <netdev.h>
 #include <usb.h>
 #include <usb/ehci-fsl.h>
 
@@ -43,6 +45,18 @@ DECLARE_GLOBAL_DATA_PTR;
 	PAD_CTL_DSE_40ohm | PAD_CTL_HYS |			\
 	PAD_CTL_ODE)
 
+#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
+	PAD_CTL_SPEED_HIGH   |                                  \
+	PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST)
+
+#define MDIO_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
+	PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST | PAD_CTL_ODE)
+
+#define ENET_CLK_PAD_CTRL  (PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST)
+
+#define ENET_RX_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |          \
+	PAD_CTL_SPEED_HIGH   | PAD_CTL_SRE_FAST)
+
 #define IOX_SDI IMX_GPIO_NR(5, 10)
 #define IOX_STCP IMX_GPIO_NR(5, 7)
 #define IOX_SHCP IMX_GPIO_NR(5, 11)
@@ -457,6 +471,98 @@ int board_ehci_hcd_init(int port)
 }
 #endif
 
+#ifdef CONFIG_FEC_MXC
+/*
+ * pin conflicts for fec1 and fec2, GPIO1_IO06 and GPIO1_IO07 can only
+ * be used for ENET1 or ENET2, cannot be used for both.
+ */
+static iomux_v3_cfg_t const fec1_pads[] = {
+	MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
+	MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
+	MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const fec2_pads[] = {
+	MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
+	MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
+
+	MX6_PAD_ENET2_TX_DATA0__ENET2_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET2_TX_DATA1__ENET2_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
+	MX6_PAD_ENET2_TX_EN__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
+
+	MX6_PAD_ENET2_RX_DATA0__ENET2_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET2_RX_DATA1__ENET2_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
+};
+
+static void setup_iomux_fec(int fec_id)
+{
+	if (fec_id == 0)
+		imx_iomux_v3_setup_multiple_pads(fec1_pads,
+						 ARRAY_SIZE(fec1_pads));
+	else
+		imx_iomux_v3_setup_multiple_pads(fec2_pads,
+						 ARRAY_SIZE(fec2_pads));
+}
+
+int board_eth_init(bd_t *bis)
+{
+	setup_iomux_fec(CONFIG_FEC_ENET_DEV);
+
+	return fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
+				       CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
+}
+
+static int setup_fec(int fec_id)
+{
+	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+	int ret;
+
+	if (fec_id == 0) {
+		/*
+		 * Use 50M anatop loopback REF_CLK1 for ENET1,
+		 * clear gpr1[13], set gpr1[17].
+		 */
+		clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
+				IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
+	} else {
+		/*
+		 * Use 50M anatop loopback REF_CLK2 for ENET2,
+		 * clear gpr1[14], set gpr1[18].
+		 */
+		clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK,
+				IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK);
+	}
+
+	ret = enable_fec_anatop_clock(fec_id, ENET_50MHZ);
+	if (ret)
+		return ret;
+
+	enable_enet_clk(1);
+
+	return 0;
+}
+
+int board_phy_config(struct phy_device *phydev)
+{
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190);
+
+	if (phydev->drv->config)
+		phydev->drv->config(phydev);
+
+	return 0;
+}
+#endif
+
 int board_early_init_f(void)
 {
 	setup_iomux_uart();
@@ -477,6 +583,10 @@ int board_init(void)
 	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
 #endif
 
+#ifdef	CONFIG_FEC_MXC
+	setup_fec(CONFIG_FEC_ENET_DEV);
+#endif
+
 #ifdef CONFIG_USB_EHCI_MX6
 	setup_usb();
 #endif
configs/mx6ul_14x14_evk_defconfig +3 -0
index b6eefaf..85952e4 100644
@@ -2,3 +2,6 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6UL"
 CONFIG_ARM=y
 CONFIG_TARGET_MX6UL_14X14_EVK=y
 CONFIG_SPL=y
+CONFIG_CMD_NET=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_DHCP=y
include/configs/mx6ul_14x14_evk.h +21 -0
index 757aa6a..f643e4d 100644
@@ -221,6 +221,27 @@
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 2
 #endif
 
+#ifdef CONFIG_CMD_NET
+#define CONFIG_FEC_MXC
+#define CONFIG_MII
+#define CONFIG_FEC_ENET_DEV		1
+
+#if (CONFIG_FEC_ENET_DEV == 0)
+#define IMX_FEC_BASE			ENET_BASE_ADDR
+#define CONFIG_FEC_MXC_PHYADDR          0x2
+#define CONFIG_FEC_XCV_TYPE             RMII
+#elif (CONFIG_FEC_ENET_DEV == 1)
+#define IMX_FEC_BASE			ENET2_BASE_ADDR
+#define CONFIG_FEC_MXC_PHYADDR		0x1
+#define CONFIG_FEC_XCV_TYPE		RMII
+#endif
+#define CONFIG_ETHPRIME			"FEC"
+
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_MICREL
+#define CONFIG_FEC_DMA_MINALIGN		64
+#endif
+
 #define CONFIG_IMX6_THERMAL
 
 #endif
Signature · 1 line
1.8.4
#3 lore raw

PATCH v2 1/3 imx: clock support enet2 anatop clock support

In reply to Peng Fan
Quoted 6 lines · Peng Fan

To i.MX6SX/UL, two ethernet interfaces are supported.
Add ENET2 clock support:
1. Introduce a new input parameter "fec_id", only 0 and 1 are allowed. To value 1, only i.MX6SX/UL can pass the check.
2. Modify board code who use this api to follow new api prototype.

Quoted 6 lines
Cc Heiko Schocher <[email protected]>
Cc Fabio Estevam <[email protected]>
Cc Stefan Roese <[email protected]>
Cc Nikolaos Pasaloukos <[email protected]>
Cc Stefano Babic <[email protected]>

Thanks,
Stefan