Skip to contentSkip to conversation

imx: clock support enet2 anatop clock support

PATCH Superseded Peng Fan 6 participants 18 messages Aug 3, 2015 – Aug 11, 2015

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Peng Fan

author
#0 lore raw

PATCH 1/4 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]>
---
 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..8c0356f 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 (0 == fec_id) {
+		reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
+		reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq);
+	} else if (1 == fec_id) {
+		/* 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 (0 == fec_id)
+		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 2/4 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.

---
 drivers/net/fec_mxc.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/net/fec_mxc.c +4 -0
index c5dcbbb..7fb1d5f 100644
@@ -520,8 +520,10 @@ static int fec_open(struct eth_device *edev)
 static int fec_init(struct eth_device *dev, bd_t* bd)
 {
 	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+#if !defined(CONFIG_MX6UL)
 	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
 	int i;
+#endif
 
 	/* Initialize MAC address */
 	fec_set_hwaddr(dev);
@@ -551,12 +553,14 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 	writel(0x00000000, &fec->eth->gaddr2);
 
 
+#if !defined(CONFIG_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);
+#endif
 
 	/* size and address of each buffer */
 	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);
Signature · 1 line
1.8.4
#2 lore raw

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

Hi Peng,

Quoted 31 lines · Peng Fan

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

---
  drivers/net/fec_mxc.c | 4 ++++
  1 file changed, 4 insertions(+)
drivers/net/fec_mxc.c +3 -0
index c5dcbbb..7fb1d5f 100644
@@ -520,8 +520,10 @@ static int fec_open(struct eth_device *edev)
  static int fec_init(struct eth_device *dev, bd_t* bd)
  {
  	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+#if !defined(CONFIG_MX6UL)
  	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
  	int i;
+#endif
 
  	/* Initialize MAC address */
  	fec_set_hwaddr(dev);
@@ -551,12 +553,14 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
  	writel(0x00000000, &fec->eth->gaddr2);
 
 
+#if !defined(CONFIG_MX6UL)

drivers/net/fec_mxc.c static int fec_init(struct eth_device *dev, bd_t* bd) · line 566

Quoted 10 lines
drivers/net/fec_mxc.c +1 -0
  	/* 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);
+#endif
 
  	/* size and address of each buffer */
  	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);

Is it possible to do runtime check for the SoC type, instead of ifdefs?

Regards,
Nikolay

#3 lore raw

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

Hi Nikolay,

Quoted 41 lines · Nikolay Dimitrov

Hi Peng,

Quoted 38 lines · Peng Fan

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

---
 drivers/net/fec_mxc.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/net/fec_mxc.c +4 -0
index c5dcbbb..7fb1d5f 100644
@@ -520,8 +520,10 @@ static int fec_open(struct eth_device *edev)
 static int fec_init(struct eth_device *dev, bd_t* bd)
 {
 	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+#if !defined(CONFIG_MX6UL)
 	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
 	int i;
+#endif
 
 	/* Initialize MAC address */
 	fec_set_hwaddr(dev);
@@ -551,12 +553,14 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 	writel(0x00000000, &fec->eth->gaddr2);
 
 
+#if !defined(CONFIG_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);
+#endif
 
Quoted 5 lines

drivers/net/fec_mxc.c static int fec_init(struct eth_device *dev, bd_t* bd) · line 566

Quoted 3 lines
drivers/net/fec_mxc.c +0 -0
 	/* size and address of each buffer */
 	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);

Is it possible to do runtime check for the SoC type, instead of ifdefs?

This driver is used by i.MX7 and i.MX6, but i.MX7 patchset has not been upstreamed now.

I considered using "if (!is_cpu_type(MXC_CPU_MX6UL))", but this will cause i.MX7 fail to complile successfully, because i.MX7 does not support the macro MXC_CPU_MX6UL.

The way I can think out is to refactor the code to support DM or FDT, using compatible string to figure out which SoC. But now I do not have much time to refactor the driver. So I just use the "#if !defined" way which is not good solution.

Regards,
Peng.

#4 lore raw

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

Hi Peng,

Quoted 52 lines · Peng Fan

Hi Nikolay,

Quoted 41 lines · Nikolay Dimitrov

Hi Peng,

Quoted 38 lines · Peng Fan

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

---
  drivers/net/fec_mxc.c | 4 ++++
  1 file changed, 4 insertions(+)
drivers/net/fec_mxc.c +4 -0
index c5dcbbb..7fb1d5f 100644
@@ -520,8 +520,10 @@ static int fec_open(struct eth_device *edev)
  static int fec_init(struct eth_device *dev, bd_t* bd)
  {
  	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+#if !defined(CONFIG_MX6UL)
  	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
  	int i;
+#endif
 
  	/* Initialize MAC address */
  	fec_set_hwaddr(dev);
@@ -551,12 +553,14 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
  	writel(0x00000000, &fec->eth->gaddr2);
 
 
+#if !defined(CONFIG_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);
+#endif
 
Quoted 5 lines

drivers/net/fec_mxc.c static int fec_init(struct eth_device *dev, bd_t* bd) · line 566

Quoted 3 lines
drivers/net/fec_mxc.c +0 -0
  	/* size and address of each buffer */
  	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);

Is it possible to do runtime check for the SoC type, instead of ifdefs?

This driver is used by i.MX7 and i.MX6, but i.MX7 patchset has not been upstreamed now.

Quoted 8 lines

I considered using "if (!is_cpu_type(MXC_CPU_MX6UL))", but this will cause i.MX7 fail to complile successfully, because i.MX7 does not support the macro MXC_CPU_MX6UL.

The way I can think out is to refactor the code to support DM or FDT, using compatible string to figure out which SoC. But now I do not have much time to refactor the driver. So I just use the "#if !defined" way which is not good solution.

Thanks for explaining. Please check this code:

#ifdef CONFIG_MX6
     if (!is_cpu_type(MXC_CPU_MX6UL))
#endif
     {
         /* soc-specific code here */
     }

This code will allow runtime detection for imx6 socs, and will not break the imx7 builds. What do you think?

Regards,
Nikolay

#5 lore raw

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

In reply to Peng Fan

Hi Peng,

Quoted 43 lines · Peng Fan

Hi Nikolay,

Quoted 41 lines · Nikolay Dimitrov

Hi Peng,

Quoted 38 lines · Peng Fan

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

---
 drivers/net/fec_mxc.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/net/fec_mxc.c +4 -0
index c5dcbbb..7fb1d5f 100644
@@ -520,8 +520,10 @@ static int fec_open(struct eth_device *edev)
 static int fec_init(struct eth_device *dev, bd_t* bd)
 {
 	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+#if !defined(CONFIG_MX6UL)
 	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
 	int i;
+#endif
 
 	/* Initialize MAC address */
 	fec_set_hwaddr(dev);
@@ -551,12 +553,14 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 	writel(0x00000000, &fec->eth->gaddr2);
 
 
+#if !defined(CONFIG_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);
+#endif
 
Quoted 8 lines
Quoted 5 lines

drivers/net/fec_mxc.c static int fec_init(struct eth_device *dev, bd_t* bd) · line 566

Quoted 3 lines
drivers/net/fec_mxc.c +0 -0
 	/* size and address of each buffer */
 	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);

Is it possible to do runtime check for the SoC type, instead of ifdefs?

This driver is used by i.MX7 and i.MX6, but i.MX7 patchset has not been upstreamed now.

Wait...this driver is used by all i.MXes. We have to take this in mind to avoid to break some SOCs - even if this is not the case.

Anyway, the rule is to push patches based on mainline, without supposing what happens with patches that are not yet applied. i.MX7 should be then adjusted for this.

Quoted 4 lines

I considered using "if (!is_cpu_type(MXC_CPU_MX6UL))", but this will cause i.MX7 fail to complile successfully, because i.MX7 does not support the macro MXC_CPU_MX6UL.

It looks like we have a problem in design - we have to move this macros to make available to all i.MXes.

In fact, it is even plausible that MX35 code runs "is_cpu_type(MXC_CPU_MX6UL)", and the macros must return false. Having these checks working for some SOCs vanifies the goal: check at runtime if a SOC is of a certain type.

Quoted 5 lines

The way I can think out is to refactor the code to support DM or FDT, using compatible string to figure out which SoC. But now I do not have much time to refactor the driver. So I just use the "#if !defined" way which is not good solution.

It is not - anyway, making macros commonly available to all i.MXes could be done with a smaller effort. Currently, macros are available only to mx6 (define in sys_proto.h). We have to move them in a header in arch/arm/include/asm/imx-common/, that is accessible by all SOCs.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#6 lore raw

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

Hi Stefano,

Quoted 67 lines · Stefano Babic

Hi Peng,

Quoted 43 lines · Peng Fan

Hi Nikolay,

Quoted 41 lines · Nikolay Dimitrov

Hi Peng,

Quoted 38 lines · Peng Fan

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

---
 drivers/net/fec_mxc.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/net/fec_mxc.c +4 -0
index c5dcbbb..7fb1d5f 100644
@@ -520,8 +520,10 @@ static int fec_open(struct eth_device *edev)
 static int fec_init(struct eth_device *dev, bd_t* bd)
 {
 	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+#if !defined(CONFIG_MX6UL)
 	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
 	int i;
+#endif
 
 	/* Initialize MAC address */
 	fec_set_hwaddr(dev);
@@ -551,12 +553,14 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 	writel(0x00000000, &fec->eth->gaddr2);
 
 
+#if !defined(CONFIG_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);
+#endif
 
Quoted 8 lines
Quoted 5 lines

drivers/net/fec_mxc.c static int fec_init(struct eth_device *dev, bd_t* bd) · line 566

Quoted 3 lines
drivers/net/fec_mxc.c +0 -0
 	/* size and address of each buffer */
 	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);

Is it possible to do runtime check for the SoC type, instead of ifdefs?

This driver is used by i.MX7 and i.MX6, but i.MX7 patchset has not been upstreamed now.

Wait...this driver is used by all i.MXes. We have to take this in mind to avoid to break some SOCs - even if this is not the case.

Anyway, the rule is to push patches based on mainline, without supposing what happens with patches that are not yet applied. i.MX7 should be then adjusted for this.

Quoted 4 lines

I considered using "if (!is_cpu_type(MXC_CPU_MX6UL))", but this will cause i.MX7 fail to complile successfully, because i.MX7 does not support the macro MXC_CPU_MX6UL.

Quoted 7 lines

It looks like we have a problem in design - we have to move this macros to make available to all i.MXes.

In fact, it is even plausible that MX35 code runs "is_cpu_type(MXC_CPU_MX6UL)", and the macros must return false. Having these checks working for some SOCs vanifies the goal: check at runtime if a SOC is of a certain type.

I checked related code for i.MX25/28/31/35/5x/6x.

We can add following define in imx-common/xxx.h
#define MXC_CPU_MX35 0x35
#define MXC_CPU_MX31 0x31
#define MXC_CPU_MX25 0x25
#define MXC_CPU_MX23 xxxx
#define MXC_CPU_MX28 yyyy
About i.mx23/28, I am not sure, since they have different get_cpu_rev implementation. Also they have different chipid layout.

To i.MX31, we can do following change:
return mx31_cpu_type[i].v | 0x31000; to replace return mx31_cpu_type[i].v;

Then we can use:
#define is_cpu_type(xxx) (((get_cpu_rev() & 0xFF000) >> 12) == xxx)

To i.MX23/28, they have different get_cpu_rev() prototype, maybe need to rewrite the function?

I am not familar with SoCs prior to i.MX6, not sure whether this ok.

Quoted 11 lines
Quoted 6 lines

The way I can think out is to refactor the code to support DM or FDT, using compatible string to figure out which SoC. But now I do not have much time to refactor the driver. So I just use the "#if !defined" way which is not good solution.

It is not - anyway, making macros commonly available to all i.MXes could be done with a smaller effort. Currently, macros are available only to mx6 (define in sys_proto.h). We have to move them in a header in arch/arm/include/asm/imx-common/, that is accessible by all SOCs.

Maybe need to add sys_proto.h in arch/arm/include/asm/imx-common.

Regards,
Peng.

Quoted 11 lines

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#7 lore raw

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

Hi Peng,

Quoted 14 lines · Peng Fan
Quoted 11 lines
Quoted 3 lines

I considered using "if (!is_cpu_type(MXC_CPU_MX6UL))", but this will cause i.MX7 fail to complile successfully, because i.MX7 does not support the macro MXC_CPU_MX6UL.

It looks like we have a problem in design - we have to move this macros to make available to all i.MXes.

In fact, it is even plausible that MX35 code runs "is_cpu_type(MXC_CPU_MX6UL)", and the macros must return false. Having these checks working for some SOCs vanifies the goal: check at runtime if a SOC is of a certain type.

I checked related code for i.MX25/28/31/35/5x/6x.

Quoted 8 lines

We can add following define in imx-common/xxx.h
#define MXC_CPU_MX35 0x35
#define MXC_CPU_MX31 0x31
#define MXC_CPU_MX25 0x25
#define MXC_CPU_MX23 xxxx
#define MXC_CPU_MX28 yyyy
About i.mx23/28, I am not sure, since they have different get_cpu_rev implementation.

As far as I understand, the chip id is retrieved and then converted as "23" or "28" (see get_cpu_type). I think it is plausible to define them in this way as well as using the waqy in get_cpu_type() to identify the SOC.

get_cpu_rev() in MX23/MX28 is also not compliant with the rest of SOCs. It returns a string intead of a u32.

Quoted 10 lines

Also they have different chipid layout.

To i.MX31, we can do following change:
return mx31_cpu_type[i].v | 0x31000; to replace return mx31_cpu_type[i].v;

Then we can use:
#define is_cpu_type(xxx) (((get_cpu_rev() & 0xFF000) >> 12) == xxx)

To i.MX23/28, they have different get_cpu_rev() prototype, maybe need to rewrite the function?

Agree - it is an exception in U-Boot for i.MXEs, and it defines a different prototype for the function.

Quoted 3 lines

I am not familar with SoCs prior to i.MX6, not sure whether this ok.

IMHO it looks ok ;-)

Quoted 7 lines
Quoted 7 lines
Quoted 6 lines

The way I can think out is to refactor the code to support DM or FDT, using compatible string to figure out which SoC. But now I do not have much time to refactor the driver. So I just use the "#if !defined" way which is not good solution.

Quoted 6 lines
Quoted 4 lines

It is not - anyway, making macros commonly available to all i.MXes could be done with a smaller effort. Currently, macros are available only to mx6 (define in sys_proto.h). We have to move them in a header in arch/arm/include/asm/imx-common/, that is accessible by all SOCs.

Maybe need to add sys_proto.h in arch/arm/include/asm/imx-common.

+1

Right - we have several sys_proto.h, iun most cases they have prototypes for the same functions.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#8 lore raw

PATCH 3/4 comment: net: Add CMD_MII in Kconfig

In reply to Peng Fan

Add CMD_MII Kconfig entry.

Cc Joe Hershberger <[email protected]>
---
 common/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)
common/Kconfig +4 -0
index 40cd69e..2ae5080 100644
@@ -433,6 +433,10 @@ config CMD_LINK_LOCAL
 	help
 	  Acquire a network IP address using the link-local protocol
 
+config CMD_MII
+	bool "mii"
+	help
+	  MII utility commands
 endmenu
 
 menu "Misc commands"
Signature · 1 line
1.8.4
#9 lore raw

PATCH 3/4 comment: net: Add CMD_MII in Kconfig

Hi Peng Fan,

Quoted 13 lines · Peng Fan

Add CMD_MII Kconfig entry.

Cc Joe Hershberger <[email protected]>
---
 common/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)
common/Kconfig +0 -0
index 40cd69e..2ae5080 100644

common/Kconfig config CMD_LINK_LOCAL · line 439

Quoted 7 lines
common/Kconfig +4 -0
@@ -433,6 +433,10 @@ config CMD_LINK_LOCAL
        help
          Acquire a network IP address using the link-local protocol
 
+config CMD_MII
+       bool "mii"
+       help
+         MII utility commands

I suspect this will break boards that use / enable this. You should use the moveconfig tool to also remove it from include/configs and add it to defconfigs.

Quoted 11 lines
common/Kconfig +0 -1
 endmenu
 
 menu "Misc commands"
--

1.8.4

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

author
#10 lore raw

PATCH 4/4 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]>
---
 board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c | 116 ++++++++++++++++++++++
 configs/mx6ul_14x14_evk_defconfig                 |   4 +
 include/configs/mx6ul_14x14_evk.h                 |  21 ++++
 3 files changed, 141 insertions(+)
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +116 -0
index 8f712cb..771e4f9 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,104 @@ 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)
+{
+	int ret;
+
+	setup_iomux_fec(CONFIG_FEC_ENET_DEV);
+
+	ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
+		CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
+	if (ret)
+		printf("FEC%d MXC: %s:failed\n", CONFIG_FEC_ENET_DEV, __func__);
+
+	return 0;
+}
+
+static int setup_fec(int fec_id)
+{
+	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+	int ret;
+
+	if (0 == fec_id) {
+		/*
+		 * 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 +589,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 +4 -0
index b6eefaf..87ba686 100644
@@ -2,3 +2,7 @@ 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
+CONFIG_CMD_MII=y
include/configs/mx6ul_14x14_evk.h +21 -0
index 436b022..a3815b3 100644
@@ -222,6 +222,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
#11 lore raw

PATCH 4/4 imx: mx6ul_14x14_evk add ENET support

board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c int board_ehci_hcd_init(int port) · line 528

Quoted 12 lines · Peng Fan
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +12 -0
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       setup_iomux_fec(CONFIG_FEC_ENET_DEV);
+
+       ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
+               CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
+       if (ret)
+               printf("FEC%d MXC: %s:failed\n", CONFIG_FEC_ENET_DEV, __func__);
+
+       return 0;

You are returning 0 even if there is an error.

You could simply do:

return fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);

board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c int board_ehci_hcd_init(int port) · line 536

Quoted 8 lines
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +8 -0
+}
+
+static int setup_fec(int fec_id)
+{
+       struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+       int ret;
+
+       if (0 == fec_id) {

Can you do if (!fec_id)?

#12 lore raw

PATCH 4/4 imx: mx6ul_14x14_evk add ENET support

Hi Fabio,

Quoted 17 lines · Fabio Estevam

board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c int board_ehci_hcd_init(int port) · line 528

Quoted 12 lines · Peng Fan
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +12 -0
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       setup_iomux_fec(CONFIG_FEC_ENET_DEV);
+
+       ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
+               CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
+       if (ret)
+               printf("FEC%d MXC: %s:failed\n", CONFIG_FEC_ENET_DEV, __func__);
+
+       return 0;

You are returning 0 even if there is an error.

Quoted 4 lines

You could simply do:

return fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);

Thanks, will fix in V2.

Quoted 11 lines

board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c int board_ehci_hcd_init(int port) · line 536

Quoted 9 lines
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +8 -0
+}
+
+static int setup_fec(int fec_id)
+{
+       struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+       int ret;
+
+       if (0 == fec_id) {

Can you do if (!fec_id)?

Why need to change to (!fec_id)? I do not see benifits to use (!fec_id).

Regards,
Peng.

#13 lore raw

PATCH 4/4 imx: mx6ul_14x14_evk add ENET support

Quoted 37 lines · Peng Fan

Hi Fabio,

Quoted 17 lines · Fabio Estevam

board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c int board_ehci_hcd_init(int port) · line 528

Quoted 12 lines · Peng Fan
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +12 -0
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       setup_iomux_fec(CONFIG_FEC_ENET_DEV);
+
+       ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
+               CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
+       if (ret)
+               printf("FEC%d MXC: %s:failed\n", CONFIG_FEC_ENET_DEV, __func__);
+
+       return 0;

You are returning 0 even if there is an error.

Quoted 4 lines

You could simply do:

return fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);

Thanks, will fix in V2.

Quoted 11 lines

board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c int board_ehci_hcd_init(int port) · line 536

Quoted 9 lines
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +8 -0
+}
+
+static int setup_fec(int fec_id)
+{
+       struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+       int ret;
+
+       if (0 == fec_id) {

Can you do if (!fec_id)?

Quoted 1 line

Why need to change to (!fec_id)? I do not see benifits to use (!fec_id).

No changes for the compiler, but this is like codestyle. You do not see (maybe some exceptions ?) ( 0 == variable) in U-Boot code.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#14 lore raw

PATCH 4/4 imx: mx6ul_14x14_evk add ENET support

Quoted 38 lines · Stefano Babic
Quoted 37 lines · Peng Fan

Hi Fabio,

Quoted 17 lines · Fabio Estevam

board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c int board_ehci_hcd_init(int port) · line 528

Quoted 12 lines · Peng Fan
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +12 -0
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       setup_iomux_fec(CONFIG_FEC_ENET_DEV);
+
+       ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
+               CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
+       if (ret)
+               printf("FEC%d MXC: %s:failed\n", CONFIG_FEC_ENET_DEV, __func__);
+
+       return 0;

You are returning 0 even if there is an error.

Quoted 4 lines

You could simply do:

return fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);

Thanks, will fix in V2.

Quoted 11 lines

board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c int board_ehci_hcd_init(int port) · line 536

Quoted 9 lines
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +8 -0
+}
+
+static int setup_fec(int fec_id)
+{
+       struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+       int ret;
+
+       if (0 == fec_id) {

Can you do if (!fec_id)?

Quoted 5 lines
Quoted 1 line

Why need to change to (!fec_id)? I do not see benifits to use (!fec_id).

No changes for the compiler, but this is like codestyle. You do not see (maybe some exceptions ?) ( 0 == variable) in U-Boot code.

Ok. Will fix this and same piece code in other patches.

Thanks,
Peng.

Quoted 11 lines

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#15 lore raw

PATCH 1/4 imx: clock support enet2 anatop clock support

In reply to Peng Fan

arch/arm/cpu/armv7/mx6/clock.c int enable_fec_anatop_clock(enum enet_freq freq) · line 538

Quoted 4 lines · Peng Fan
arch/arm/cpu/armv7/mx6/clock.c +1 -3
-       reg = readl(&anatop->pll_enet);
-       reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
-       reg |= freq;
+       if (0 == fec_id) {

Could you please use 'if (fec_id == 0)'.

Same applies below.

#16 lore raw

PATCH 1/4 imx: clock support enet2 anatop clock support

In reply to Peng Fan

Hi Peng,

(added Joe in CC as network custodian):

Quoted 38 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.

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]>
---
 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 +1 -1
index 9cf4eec..8c0356f 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;

arch/arm/cpu/armv7/mx6/clock.c int enable_fec_anatop_clock(enum enet_freq freq) · line 537

Quoted 3 lines
arch/arm/cpu/armv7/mx6/clock.c +0 -0
@@ -535,9 +535,19 @@ int enable_fec_anatop_clock(enum enet_freq freq)
 	if (freq < ENET_25MHZ || freq > ENET_125MHZ)
 		return -EINVAL;
 

Changes here are ok, but I noted a disalignment between getting the clock and initialkizing the fec.

The FEC driver already supports multiple FEC, see int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr). With your proposal it is also possible to set the clock for device 1 and then initialize device 0.

fec_get_miibus() is also called with a device id. Should we not make that this setup is done by a call of the FEC driver ?

Quoted 132 lines
arch/arm/cpu/armv7/mx6/clock.c +17 -4
-	reg = readl(&anatop->pll_enet);
-	reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
-	reg |= freq;
+	if (0 == fec_id) {
+		reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
+		reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq);
+	} else if (1 == fec_id) {
+		/* 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 (0 == fec_id)
+		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 +0 -0
index 9b1ecf0..8247e43 100644

board/solidrun/mx6cuboxi/mx6cuboxi.c int board_eth_init(bd_t *bis) · line 170

Quoted 8 lines
board/solidrun/mx6cuboxi/mx6cuboxi.c +1 -1
@@ -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;
 

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#17 lore raw

PATCH 1/4 imx: clock support enet2 anatop clock support

Hi Stefano,

Quoted 51 lines · Stefano Babic

Hi Peng,

(added Joe in CC as network custodian):

Quoted 38 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.

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]>
---
 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 +1 -1
index 9cf4eec..8c0356f 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;

arch/arm/cpu/armv7/mx6/clock.c int enable_fec_anatop_clock(enum enet_freq freq) · line 537

Quoted 3 lines
arch/arm/cpu/armv7/mx6/clock.c +0 -0
@@ -535,9 +535,19 @@ int enable_fec_anatop_clock(enum enet_freq freq)
 	if (freq < ENET_25MHZ || freq > ENET_125MHZ)
 		return -EINVAL;
 

Changes here are ok, but I noted a disalignment between getting the clock and initialkizing the fec.

Quoted 4 lines

The FEC driver already supports multiple FEC, see int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr). With your proposal it is also possible to set the clock for device 1 and then initialize device 0.

Yeah. This gives a chance to enable the clock for device 0 and enable the clock for device 0. But now, to i.mx platform, I did not see any platform that need to initialize both in uboot stage.

Just as the following code flow, we rarely need to initialize both:

setup_fec(CONFIG_FEC_ENET_DEV);
	->enable_fec_anatop_clock(CONFIG_FEC_ENET_DEV, ENET_50MHZ);
Quoted 3 lines

fec_get_miibus() is also called with a device id. Should we not make that this setup is done by a call of the FEC driver ?

Not sure whether I follow you correctly. You mean we should the clock setting function should be invoked from FEC driver since FEC driver supports devcie id? or the clock settings should be implemented in FEC driver?

From the longrun, I agree to invoke clock api to enable/disable/set rate clock in different drivers. But now, we do not have a strong clock framework.

Regards,
Peng.

Quoted 152 lines
Quoted 134 lines
arch/arm/cpu/armv7/mx6/clock.c +17 -4
-	reg = readl(&anatop->pll_enet);
-	reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
-	reg |= freq;
+	if (0 == fec_id) {
+		reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
+		reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq);
+	} else if (1 == fec_id) {
+		/* 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 (0 == fec_id)
+		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 +0 -0
index 9b1ecf0..8247e43 100644

board/solidrun/mx6cuboxi/mx6cuboxi.c int board_eth_init(bd_t *bis) · line 170

Quoted 8 lines
board/solidrun/mx6cuboxi/mx6cuboxi.c +1 -1
@@ -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;
 

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================