i.MX8MP FEC no RMII TXEN/TXD signals

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX8MP FEC no RMII TXEN/TXD signals

Jump to solution
1,061 Views
rllx
Contributor I

Hi,

we're facing problems with FEC in RMII mode on a custom i.MX8MP board and looking for help. Any feedback/pointer/question is welcome. Thanks!

 

Problem:

FEC MAC does not generate TXEN/TXD signals and therefore FEC_TBD_READY doesn't get cleared (in https://source.codeaurora.org/external/imx/uboot-imx/tree/drivers/net/fec_mxc.c?h=imx_v2020.04_5.4.7...).

REFCLK and CRS_DV and RXD signals are fine (verified using a scope).

In U-boot we get the following output (with some additonal debugging lines):

=> ping 10.0.0.1
fec_reg_setup: RMII mode
fec_mii_setspeed: mii_speed 0000026a
fec_open: fec_open(dev)
fec_mdio_read: phy: 00 reg:01 val:0x782d
fec_mdio_read: phy: 00 reg:01 val:0x782d
fec_mdio_read: phy: 00 reg:01 val:0x782d
fec_mdio_read: phy: 00 reg:04 val:0x1e1
fec_mdio_read: phy: 00 reg:05 val:0xc5e1
fec_open:Speed=100
Using ethernet@30be0000 device
fecmxc_send: 42 <FF FF FF FF FF FF 8E 07 A3 5C A3 9C 08 06 00 01 08 00 06 04 00 01 8E 07 A3 5C A3 9C 0A 00 00 0A 00 00 00 00 00 00 0A 00 00 01 >
fec_tx_task_enable
fecmxc_send: timeout: became not ready
fec_send: status 0x8c00 index 0 ret -22 err 0x48b9

 

Hardware:

Custom i.MX8MP based board with LAN8720Ai PHY connected to FEC signals on SAI1 pads. 50MHz refclk is generated by SoC.

 

U-Boot/SPL:

U-Boot + SPL: 2020.04 - rel_imx_5.4.70_2.3.6 from https://source.codeaurora.org/external/imx/uboot-imx with custom board files and dts.

DTS snippet:

/* Aux Ethernet - IC031, X035 - LAN8720AICP */
&fec {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_fec>;
	phy-mode = "rmii";
	phy-handle = <&ethphyaux>;
	/* currently we need the phy-reset-gpios in mac as the phy driver in
	 * u-boot 2020.04 doesn't support reset-gpios */
	phy-reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
	status = "okay";

	/* overwrite the assigned clocks as it seems the driver cannot handle
	 * this based on the phy-mode... */
	assigned-clocks = <&clk IMX8MP_CLK_ENET_AXI>,
			  <&clk IMX8MP_CLK_ENET_TIMER>,
			  <&clk IMX8MP_CLK_ENET_REF>,
			  <&clk IMX8MP_CLK_ENET_PHY_REF>;
	assigned-clock-rates = <0>, <100000000>, <50000000>, <50000000>;
	assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>,
				 <&clk IMX8MP_SYS_PLL2_100M>,
				 <&clk IMX8MP_SYS_PLL2_50M>;
	mdio {
		#address-cells = <1>;
		#size-cells = <0>;

		ethphyaux: ethernet-phy@0 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>;
			max-speed = <100>;
			clocks = <&clk IMX8MP_CLK_ENET_PHY_REF>;

			interrupt-parent = <&gpio4>;
			interrupts =  IRQ_TYPE_LEVEL_LOW>;
			reset-assert-us = <100>; /* see datasheet TABLE 5-8 */
			reset-deassert-us = <1>; /* see datasheet TABLE 5-8 */
		};
	};
};

&iomuxc {
	pinctrl-names = "default";

	pinctrl_fec: fecgrp {
		fsl,pins = <
			MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC		0x00000146 /* ETH_AUX_MDC */
			MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO		0x00000146 /* ETH_AUX_MDIO */
			MX8MP_IOMUXC_SAI1_MCLK__ENET1_TX_CLK		0x00000106 /* ETH_AUX_REFCLK */
			MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0		0x00000106 /* ETH_AUX_RXD0 */
			MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1		0x00000106 /* ETH_AUX_RXD1 */
			MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0		0x00000106 /* ETH_AUX_TXD0 */
			MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1		0x00000106 /* ETH_AUX_TXD1 */
			MX8MP_IOMUXC_SAI1_TXD6__ENET1_RX_ER		0x00000106 /* ETH_AUX_RXER */
			MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL	0x00000106 /* ETH_AUX_TXEN */
			MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL	0x00000106 /* ETH_AUX_CRS_DV */
			MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03		0x00000046 /* !ETH_AUX_INT */
			MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02		0x00000006 /* !ETH_AUX_PHY_RESET */
		>;
	};
};

 

Board ethernet bringup code (called from U-Boot board_init()):

static int board_phy_init_fec(void)
{
	struct iomuxc_gpr_base_regs *gpr =
		(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;

	/* Enable RMII TX clk output */
	setbits_le32(&gpr->gpr[1], IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK);

	return 0;
}

 

BL31 (ATF):

BL31: rel_imx_5.4.70_2.3.6 from https://source.codeaurora.org/external/imx/imx-atf with following change:

diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index d32789c51..e6abd809a 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -93,7 +93,7 @@
 #define IMX_CAAM_RAM_BASE              U(0x100000)
 #define IMX_CAAM_RAM_SIZE              U(0x10000)
 #define IMX_DRAM_BASE                  U(0x40000000)
-#define IMX_DRAM_SIZE                  U(0xc0000000)
+#define IMX_DRAM_SIZE                  U(0x80000000)
 #define IMX_VPU_BLK_BASE               U(0x38330000)
 #define IMX_VPU_BLK_SIZE               U(0x10000)

 

Similar (unresolved) issues found on the net:

Tags (3)
0 Kudos
Reply
1 Solution
1,018 Views
rllx
Contributor I

We finally managed to get FEC in RMII mode to life using Linux v6.0-rc1. Basically it boiled down to an incorrect assumption on clocking from our side and setting a "magic bit" in the SW_PAD_CTL_PAD_SAI1_MCLK register (where the ENET1_TX_CLK signal is muxed to).

So it would be great if someone could explain the "magic" 0x40000000 bit
(I've started an attempt on getting information about this bit also on https://lore.kernel.org/imx/YvzFPR5rwVSLzNPK@skidata.com/T/#m070c0391ae85d9cb39f1354f224596b82dce6e9...)

For the sake of completeness here's our current dts node for FEC in RMII mode on i.MX8MP:

 

/* Aux Ethernet - IC031, X035 - LAN8720AICP */
&fec {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_fec>;

	phy-handle = <&ethphyaux>;
	phy-mode = "rmii";

	/* configure 50MHz REF and PHY_REF clock */
	assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>,
					<&clk IMX8MP_SYS_PLL2_100M>,
					<&clk IMX8MP_SYS_PLL2_50M>;
	assigned-clock-rates = <0>, <100000000>, <50000000>, <0>;

	status = "okay";

	mdio {
		#address-cells = <1>;
		#size-cells = <0>;
		status = "okay";

		ethphyaux: ethernet-phy@0 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>;

			interrupt-parent = <&gpio4>;
			interrupts =  IRQ_TYPE_LEVEL_LOW>;

			reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
			reset-assert-us = <1000>; /* see datasheet TABLE 5-8 */
			reset-deassert-us = <10>; /* see datasheet TABLE 5-8 */
			status = "okay";
		};
	};
};

&iomuxc {
	pinctrl_fec: fecgrp {
		fsl,pins = <
			MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC		0x00000106 /* ETH_AUX_MDC */
			MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO		0x00000106 /* ETH_AUX_MDIO */
			MX8MP_IOMUXC_SAI1_MCLK__ENET1_TX_CLK		0x40000090 /* ETH_AUX_REFCLK */
			MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0		0x00000090 /* ETH_AUX_RXD0 */
			MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1		0x00000090 /* ETH_AUX_RXD1 */
			MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0		0x00000016 /* ETH_AUX_TXD0 */
			MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1		0x00000016 /* ETH_AUX_TXD1 */
			MX8MP_IOMUXC_SAI1_TXD6__ENET1_RX_ER		0x00000090 /* ETH_AUX_RXER */
			MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL	0x00000016 /* ETH_AUX_TXEN */
			MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL	0x00000090 /* ETH_AUX_CRS_DV */
			MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03		0x00000046 /* !ETH_AUX_INT */
			MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02		0x00000006 /* !ETH_AUX_PHY_RESET */
		>;
	};
};

 

 

View solution in original post

0 Kudos
Reply
1 Reply
1,019 Views
rllx
Contributor I

We finally managed to get FEC in RMII mode to life using Linux v6.0-rc1. Basically it boiled down to an incorrect assumption on clocking from our side and setting a "magic bit" in the SW_PAD_CTL_PAD_SAI1_MCLK register (where the ENET1_TX_CLK signal is muxed to).

So it would be great if someone could explain the "magic" 0x40000000 bit
(I've started an attempt on getting information about this bit also on https://lore.kernel.org/imx/YvzFPR5rwVSLzNPK@skidata.com/T/#m070c0391ae85d9cb39f1354f224596b82dce6e9...)

For the sake of completeness here's our current dts node for FEC in RMII mode on i.MX8MP:

 

/* Aux Ethernet - IC031, X035 - LAN8720AICP */
&fec {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_fec>;

	phy-handle = <&ethphyaux>;
	phy-mode = "rmii";

	/* configure 50MHz REF and PHY_REF clock */
	assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>,
					<&clk IMX8MP_SYS_PLL2_100M>,
					<&clk IMX8MP_SYS_PLL2_50M>;
	assigned-clock-rates = <0>, <100000000>, <50000000>, <0>;

	status = "okay";

	mdio {
		#address-cells = <1>;
		#size-cells = <0>;
		status = "okay";

		ethphyaux: ethernet-phy@0 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>;

			interrupt-parent = <&gpio4>;
			interrupts =  IRQ_TYPE_LEVEL_LOW>;

			reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
			reset-assert-us = <1000>; /* see datasheet TABLE 5-8 */
			reset-deassert-us = <10>; /* see datasheet TABLE 5-8 */
			status = "okay";
		};
	};
};

&iomuxc {
	pinctrl_fec: fecgrp {
		fsl,pins = <
			MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC		0x00000106 /* ETH_AUX_MDC */
			MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO		0x00000106 /* ETH_AUX_MDIO */
			MX8MP_IOMUXC_SAI1_MCLK__ENET1_TX_CLK		0x40000090 /* ETH_AUX_REFCLK */
			MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0		0x00000090 /* ETH_AUX_RXD0 */
			MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1		0x00000090 /* ETH_AUX_RXD1 */
			MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0		0x00000016 /* ETH_AUX_TXD0 */
			MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1		0x00000016 /* ETH_AUX_TXD1 */
			MX8MP_IOMUXC_SAI1_TXD6__ENET1_RX_ER		0x00000090 /* ETH_AUX_RXER */
			MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL	0x00000016 /* ETH_AUX_TXEN */
			MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL	0x00000090 /* ETH_AUX_CRS_DV */
			MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03		0x00000046 /* !ETH_AUX_INT */
			MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02		0x00000006 /* !ETH_AUX_PHY_RESET */
		>;
	};
};

 

 

0 Kudos
Reply