iMX6ULL Ethernet / LAN8720 / U-Boot

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

iMX6ULL Ethernet / LAN8720 / U-Boot

Jump to solution
3,097 Views
daneduplooy
Contributor III

I have spun a custom board and am currently trying to get the Ethernet working in U-Boot.

Processor is i.MX6ULL, PHY chip is LAN8720. Only 1 Ethernet being used (Ethernet 1).

Connections are:

Schematic.png

.dtsi:

 

 

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    status = "okay";

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

        ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <0>;
            max-speed = <100>;
            clocks = <&clks IMX6UL_CLK_ENET_REF>;
            clock-names = "rmii-ref";
        };
    };
};
 
&iomuxc {
    pinctrl-names = "default";

    pinctrl_enet1: enet1grp {
        fsl,pins = <
            MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN  0x1b0b0 /* FEC_CRS_DV */
            MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER  0x1b0b0 /* FEC_RX_ER */
            MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0 /* FEC_RXD0 */
            MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0 /* FEC_RXD1 */
            MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN  0x1b0b0 /* FEC_TX_EN */
            MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0 /* FEC_TXD0 */
            MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0 /* FEC_TXD1 */
            MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b031 /* FEC_TXCLK */
           
            MX6UL_PAD_ENET2_RX_DATA0__ENET1_MDIO    0x1b0b0 /* ENET_MDIO */
            MX6UL_PAD_ENET2_RX_DATA1__ENET1_MDC     0x1b0b0 /* ENET_MDC */
        >;
    };

   .....

};

 

 

 

Board .c file:

 

 

#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)

#ifdef CONFIG_FEC_MXC
static iomux_v3_cfg_t const fec1_pads[] = {
    MX6_PAD_ENET2_RX_DATA0__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
    MX6_PAD_ENET2_RX_DATA1__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 void setup_iomux_fec(int fec_id)
{
    if (fec_id == 0) {
		  printf("setup_iomux_fec(0);");
          imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
    }
}
#endif

#ifdef CONFIG_FEC_MXC
int board_eth_init(struct bd_info *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 (fec_id == 0) {
		/*
		 * Use 50MHz 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);
	} 

	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_init(void)
{
	/* Address of boot parameters */
	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;

#ifdef	CONFIG_FEC_MXC
	setup_fec(CONFIG_FEC_ENET_DEV);
#endif

	return 0;
}

 

 

 
Board .h file:

 

 

#ifdef CONFIG_CMD_NET
	#define CONFIG_FEC_ENET_DEV		0
	#define IMX_FEC_BASE			ENET_BASE_ADDR
	#define CONFIG_FEC_MXC_PHYADDR		0x0
#endif

 

 

 

defconfig:

 

 

CONFIG_PHYLIB=y
CONFIG_PHY_SMSC=y
CONFIG_DM_ETH_PHY=y
CONFIG_FEC_MXC=y
CONFIG_MII=y

 

 

 

U-Boot console at startup shows:

Net: Could not get PHY for FEC0: addr 0

Error: ethernet@2188000 address not set.
No ethernet found.

 

mdio list returns:

No MDIO bus found

 

mii device returns:

MII devices:

 

I have run out of ideas regarding how to debug this at this point. I've also tried unsuccessfully to add some debug output in u-boot using printf() and even tried gpio_set_value() to set some LEDs (the LEDs toggle fine using "gpio set xx" from the u-boot console) but also without success (these are separate queries / issues).

 

[P.S. Edit: Probing with an oscilloscope I can see 50MHz signal on ENET1_TX_CLK, approx. 2.357MHz signal on ENET1_MDC and some data bursts on ENET1_MDIO.]

Labels (1)
Tags (3)
0 Kudos
Reply
1 Solution
3,024 Views
daneduplooy
Contributor III

I removed the following code (which had been copied over from the EVK board) and it finally worked:

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;
}

(I literally got such a fright when it finally worked that I jumped ).

Still need to sort out setting of the MAC address from the EEPROM. Would be nice to have a device-tree only solution if possible. Thread for that query is Re: iMX6ULL Ethernet / LAN8720 / U-Boot - NXP Community.

View solution in original post

0 Kudos
Reply
8 Replies
3,006 Views
daneduplooy
Contributor III

Although the Ethernet is now working in U-Boot, it doesn't seem to be working in Linux. I am getting the following in the Linux startup messages:

[ 6.417121] libphy: fec_enet_mii_bus: probed
[ 6.502579] fec: probe of 2188000.ethernet failed with error -16

Any ideas?

0 Kudos
Reply
3,025 Views
daneduplooy
Contributor III

I removed the following code (which had been copied over from the EVK board) and it finally worked:

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;
}

(I literally got such a fright when it finally worked that I jumped ).

Still need to sort out setting of the MAC address from the EEPROM. Would be nice to have a device-tree only solution if possible. Thread for that query is Re: iMX6ULL Ethernet / LAN8720 / U-Boot - NXP Community.

0 Kudos
Reply
3,027 Views
daneduplooy
Contributor III

Hi Sanket

 

Thanks :-).

 

I have made the device tree changes which you suggested, however still no luck.

&fec1 { // ENET1 
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet1>;
	phy-mode = "rmii";
	phy-handle = <&ethphy0>;
    phy-reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
    phy-reset-duration = <5>;
	status = "okay";

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

		/*nvmem-cells = <&eth0_addr>;
		nvmem-cell-names = "mac-address";*/

		ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>; /* PHY Address 0 */
			smsc,disable-energy-detect;
			max-speed = <100>;
			clocks = <&clks IMX6UL_CLK_ENET_REF>;
			clock-names = "rmii-ref";
       		reset-names = "phy";
			reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
			reset-assert-us = <1000>;
			reset-deassert-us = <1000>;
			status = "okay";
		};
	};
};

 mii read 0 1 returns 0x782D (0b 0111 1000 0010 1101) indicating that the link is up (bit 2), however the link LED does not come on.

I still cannot ping the host computer. I have tested from u-boot on a BeagleBone Black and can ping the host computer successfully, so there must be some issue on my i.MX6 board.

mii read 0 5 returns 0xC1E1 (0b 1100 0001 1110 0001) indicating "Link code word received from partner" (bit 14).

Windows shows that the link is connected, but no bytes received or sent.

What is the next idea to try?

 

Thanks

Dane

0 Kudos
Reply
3,073 Views
daneduplooy
Contributor III

MAC address was not set. By enabling CONFIG_NET_RANDOM_ETHADDR I can now use the mdio command to interact with the PHY (LAN8720). I still get "Net: Could not get PHY for FEC0: addr 0" on the first pass after POR, after that just "Net:" (nothing following). I have a query regarding how to set the MAC from an EEPROM chip (AT24MAC402) however have posted a separate question about that.

I am still unable to ping my laptop however.

0 Kudos
Reply
3,004 Views
daneduplooy
Contributor III

reset-gpios should not be defined under both fec1 and mdio (ethernet-phy) - I removed these from under ethernet-phy and it now works ok.

0 Kudos
Reply
2,983 Views
Sanket_Parekh
NXP TechSupport
NXP TechSupport

Hi @daneduplooy 

I guess issue is resolved. Can I mark this case to close state?

Thanks & Regards

Sanket Parekh

0 Kudos
Reply
2,953 Views
daneduplooy
Contributor III

Hi Sanket

Yes you're welcome to close it.

Regards
Dane

0 Kudos
Reply
3,043 Views
Sanket_Parekh
NXP TechSupport
NXP TechSupport

Hi @daneduplooy ,

I hope you are doing well.
 
Please change the device tree and add reset properties in the device tree like below.
 
&fec1{
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>; 
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
    phy-reset-duration = <5>;

     status = "okay";

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

       ethphy0: ethernet-phy@2 {
       compatible = "ethernet-phy-ieee802.3-c22";
       reg = <0>;
       smsc,disable-energy-detect;
       interrupt-parent = <&gpio5>;
       interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
       max-speed = <100>;
       clocks = <&clks IMX6UL_CLK_ENET_REF>;
       clock-names = "rmii-ref";
       reset-names = "phy";
       reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
       reset-assert-us = <1000>;
       reset-deassert-us = <1000>;

       status = "okay";
       };
   };
};
 
For setting the MAC from an EEPROM chip, one can refer /board/freescale/common/sys_eeprom.c and set the correct configuration according to the chip 
 
Thanks & Regards
Sanket Parekh
0 Kudos
Reply