
Do not reconfigure the FEC clock during board_eth_init(), otherwise the FEC might have stability issues, refuse to autonegotiate link entirely or even corrupt packets while indicating correct checksum on them. Instead, move the FEC clock init to board_early_init_f(), where all the other upstream clock are initialized and also make sure there is proper stabilization delay.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam fabio.estevam@freescale.com Cc: Hector Palacios hector.palacios@digi.com Cc: Oliver Metz oliver@freetz.org Cc: Otavio Salvador otavio@ossystems.com.br Cc: Stefano Babic sbabic@denx.de Cc: Tom Rini trini@ti.com --- board/bluegiga/apx4devkit/apx4devkit.c | 10 ++++------ board/denx/m28evk/m28evk.c | 21 +++++++++++---------- board/freescale/mx28evk/mx28evk.c | 9 +++++---- board/schulercontrol/sc_sps_1/sc_sps_1.c | 19 +++++++++++-------- 4 files changed, 31 insertions(+), 28 deletions(-)
NOTE: I'd like to get this into current release as it fixes a serious issue I observe here on the MX28EVK (packets being corrupted on long transfers initiated early after boot). Please test this and report back ASAP.
diff --git a/board/bluegiga/apx4devkit/apx4devkit.c b/board/bluegiga/apx4devkit/apx4devkit.c index 08e79bd..044a182 100644 --- a/board/bluegiga/apx4devkit/apx4devkit.c +++ b/board/bluegiga/apx4devkit/apx4devkit.c @@ -39,6 +39,10 @@ int board_early_init_f(void) /* SSP0 clock at 96MHz */ mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
+#ifdef CONFIG_CMD_NET + cpu_eth_init(NULL); + udelay(10000); +#endif return 0; }
@@ -79,12 +83,6 @@ int board_eth_init(bd_t *bis) int ret; struct eth_device *dev;
- ret = cpu_eth_init(bis); - if (ret) { - printf("FEC MXS: Unable to init FEC clocks\n"); - return ret; - } - ret = fecmxc_initialize(bis); if (ret) { printf("FEC MXS: Unable to init FEC\n"); diff --git a/board/denx/m28evk/m28evk.c b/board/denx/m28evk/m28evk.c index 33d38cf..5065ee8 100644 --- a/board/denx/m28evk/m28evk.c +++ b/board/denx/m28evk/m28evk.c @@ -26,6 +26,9 @@ DECLARE_GLOBAL_DATA_PTR; */ int board_early_init_f(void) { + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + /* IO0 clock at 480MHz */ mxs_set_ioclk(MXC_IOCLK0, 480000); /* IO1 clock at 480MHz */ @@ -36,6 +39,14 @@ int board_early_init_f(void) /* SSP2 clock at 160MHz */ mxs_set_sspclk(MXC_SSPCLK2, 160000, 0);
+#ifdef CONFIG_CMD_NET + cpu_eth_init(NULL); + clrsetbits_le32(&clkctrl_regs->hw_clkctrl_enet, + CLKCTRL_ENET_TIME_SEL_MASK | CLKCTRL_ENET_CLK_OUT_EN, + CLKCTRL_ENET_TIME_SEL_RMII_CLK); + udelay(10000); +#endif + #ifdef CONFIG_CMD_USB mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT); mxs_iomux_setup_pad(MX28_PAD_AUART3_TX__GPIO_3_13 | @@ -110,19 +121,9 @@ int fecmxc_mii_postcall(int phy)
int board_eth_init(bd_t *bis) { - struct mxs_clkctrl_regs *clkctrl_regs = - (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; struct eth_device *dev; int ret;
- ret = cpu_eth_init(bis); - if (ret) - return ret; - - clrsetbits_le32(&clkctrl_regs->hw_clkctrl_enet, - CLKCTRL_ENET_TIME_SEL_MASK | CLKCTRL_ENET_CLK_OUT_EN, - CLKCTRL_ENET_TIME_SEL_RMII_CLK); - #if !defined(CONFIG_DENX_M28_V11) && !defined(CONFIG_DENX_M28_V10) /* Reset the new PHY */ gpio_direction_output(MX28_PAD_AUART2_RTS__GPIO_3_11, 0); diff --git a/board/freescale/mx28evk/mx28evk.c b/board/freescale/mx28evk/mx28evk.c index 5005fe2..2c93c44 100644 --- a/board/freescale/mx28evk/mx28evk.c +++ b/board/freescale/mx28evk/mx28evk.c @@ -41,6 +41,11 @@ int board_early_init_f(void) /* SSP2 clock at 160MHz */ mxs_set_sspclk(MXC_SSPCLK2, 160000, 0);
+#ifdef CONFIG_CMD_NET + cpu_eth_init(NULL); + udelay(10000); +#endif + #ifdef CONFIG_CMD_USB mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT); mxs_iomux_setup_pad(MX28_PAD_AUART2_RX__GPIO_3_8 | @@ -102,10 +107,6 @@ int board_eth_init(bd_t *bis) struct eth_device *dev; int ret;
- ret = cpu_eth_init(bis); - if (ret) - return ret; - /* MX28EVK uses ENET_CLK PAD to drive FEC clock */ writel(CLKCTRL_ENET_TIME_SEL_RMII_CLK | CLKCTRL_ENET_CLK_OUT_EN, &clkctrl_regs->hw_clkctrl_enet); diff --git a/board/schulercontrol/sc_sps_1/sc_sps_1.c b/board/schulercontrol/sc_sps_1/sc_sps_1.c index 7f0b591..9d3c970 100644 --- a/board/schulercontrol/sc_sps_1/sc_sps_1.c +++ b/board/schulercontrol/sc_sps_1/sc_sps_1.c @@ -26,6 +26,9 @@ DECLARE_GLOBAL_DATA_PTR; */ int board_early_init_f(void) { + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + /* IO0 clock at 480MHz */ mxs_set_ioclk(MXC_IOCLK0, 480000); /* IO1 clock at 480MHz */ @@ -36,6 +39,14 @@ int board_early_init_f(void) /* SSP2 clock at 96MHz */ mxs_set_sspclk(MXC_SSPCLK2, 96000, 0);
+#ifdef CONFIG_CMD_NET + cpu_eth_init(NULL); + clrsetbits_le32(&clkctrl_regs->hw_clkctrl_enet, + CLKCTRL_ENET_TIME_SEL_MASK, + CLKCTRL_ENET_TIME_SEL_RMII_CLK | CLKCTRL_ENET_CLK_OUT_EN); + udelay(10000); +#endif + #ifdef CONFIG_CMD_USB mxs_iomux_setup_pad(MX28_PAD_AUART1_CTS__USB0_OVERCURRENT); mxs_iomux_setup_pad(MX28_PAD_AUART2_TX__GPIO_3_9 | @@ -69,16 +80,8 @@ int board_mmc_init(bd_t *bis) #ifdef CONFIG_CMD_NET int board_eth_init(bd_t *bis) { - struct mxs_clkctrl_regs *clkctrl_regs = - (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; int ret;
- ret = cpu_eth_init(bis); - - clrsetbits_le32(&clkctrl_regs->hw_clkctrl_enet, - CLKCTRL_ENET_TIME_SEL_MASK, - CLKCTRL_ENET_TIME_SEL_RMII_CLK | CLKCTRL_ENET_CLK_OUT_EN); - ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE); if (ret) { printf("FEC MXS: Unable to init FEC0\n");