imx6ul: PHY on fec1 not found by mdio when fec2 is used too

465 Views Asked by At

I want to use fec1 and fec2 of an imx6ul device.
Each fec is connected to a PHY. The management interface to both PHY's are on the same mdio bus which is a sub-node of fec2.
PHY on fec1 has address 0 and PHY on fec2 has address 1 on the mdio bus.
Now I have the issue, that PHY connected to fec1 cannot be found when mdio searches for it:
[ 3.701404] mdio_bus 20b4000.ethernet-1: MDIO device at address 0 is missing.
Also at later phase the message appears that there is no connection to phy:
[ 24.683268] fec 2188000.ethernet eth1: Unable to connect to phy

When I use a bootloader e.g. u-boot or barebox which sets up the fec's already before linux starts, then everything works fine.
What we found is, that the CLK for PHY on fec1 is not turned on when bootloader does not set it up previously.
Due to fec2 address is lower than fec1 address --> fec2 is probed before fec1 in linux.
This seems to be the reason why the pinmux of fec1 is not executed when fec2 probes --> alternative function for fec1 is not set at this time and therefore no CLK to PHY on fec1.
At later phase, when fec1 becomes probed the CLK will be turned on but at this time the mdio already states that this phy is not reachable.
If we reboot linux, the PHY on FEC1 will be found because its function is already set.

How can this be solved, that already at initial boot, without setup of fec's in bootloader, the PHY on fec1 will be recognized by linux?

Used DeviceTree snippet:

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>/*,
                <&pinctrl_enet1_mdio>,
                <&pinctrl_enet1_gpio>*/;
                
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-supply = <&reg_fec_3v3>;

    status = "okay";
};

&fec2 {

    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet2>, 
                <&pinctrl_enet2_mdio>,
                <&pinctrl_enet1_gpio>,
                <&pinctrl_enet2_gpio>;
                
    phy-mode = "rmii";
    phy-supply = <&reg_fec_3v3>;
    phy-handle = <&ethphy1>;

    status = "okay";

    /*
     * The MDIO bus is shared between ENET1 and ENET2. If you only want
     * to enable ENET1, this node must be moved to fec1 node, and the
     * pinctrl-0 of fec1 must contain the IOMUX for the MDIO bus on ENET1
     * (pintrl_enet1_mdio).
     */
    mdio {
        #address-cells = <1>;
        #size-cells = <0>;

        /* mdio address "0" */
        ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <0>;
            max-speed = <100>;
            clocks = <&clks IMX6UL_CLK_ENET_REF>;
            reset-gpios = <&gpio3 9 GPIO_ACTIVE_LOW>;
            reset-assert-us = <200>;
            reset-deassert-us = <1000>;
            reset-names = "phy-reset1";
        };      

        /* mdio address "1" */
        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <1>;
            max-speed = <100>;
            clocks = <&clks IMX6UL_CLK_ENET2_REF_125M>;
            reset-gpios = <&gpio3 10 GPIO_ACTIVE_LOW>;
            reset-assert-us = <200>;
            reset-deassert-us = <1000>;
            reset-names = "phy-reset2";
        };
    };  
};

&iomuxc {

    pinctrl_enet1: enet1grp {
        fsl,pins = <
            MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x1b0b0
            MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x1b0b0
            MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
            MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
            MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
            MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
            MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0b0
            MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b0a8
        >;
    };

    pinctrl_enet2: enet2grp {
        fsl,pins = <
            MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN      0x1b0b0
            MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER      0x1b0b0
            MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
            MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
            MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0a0
            MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0a0
            MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN      0x1b0b0
            MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2      0x4001b0a8
        >;
    };

    pinctrl_enet2_mdio: mdioenet2grp {
        fsl,pins = <
            /* mdio */
            MX6UL_PAD_GPIO1_IO07__ENET2_MDC     0x1b0b0
            MX6UL_PAD_GPIO1_IO06__ENET2_MDIO    0x1b0b0
        >;
    };

    pinctrl_enet1_gpio: enet1gpiogrp {
        fsl,pins = <
            /* PHY reset */     
            MX6UL_PAD_LCD_DATA04__GPIO3_IO09    0x1b0b0 /* ENET1_RESET */
        >;
    };  

    pinctrl_enet2_gpio: enet2gpiogrp {
        fsl,pins = <
            /* PHY reset */
            MX6UL_PAD_LCD_DATA05__GPIO3_IO10    0x1b0b0 /* ENET2_RESET */
        >;
    };
};

Boot-Log with relevant data (short version otherwise bodysize is violated):

[    0.000000] Booting Linux on physical CPU 0x0
...
[    0.000000] Kernel command line: bootchooser.active=system0 console=ttymxc0,115200n8   systemd.machine_id=61f6da2724f38d0f1c202fb743ec3557 root=/dev/mmcblk0p3 rauc.slot=system0 rootwait
...
[    3.361074] mdio_bus 20b4000.ethernet-1: MDIO device at address 0 is missing.
[    3.383677] fec 20b4000.ethernet eth0: registered PHC device 0
[    3.408859] pps pps1: new PPS source ptp1
[    4.002064] fec 2188000.ethernet eth1: registered PHC device 1
...
[   20.108429] systemd[1]: Started Network Configuration.
[  OK  ] Started Network Configuration.
[   21.529085] Generic PHY 20b4000.ethernet-1:01: attached PHY driver (mii_bus:phy_addr=20b4000.ethernet-1:01, irq=POLL)
[   21.686217] fec 20b4000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   21.851450] fec 2188000.ethernet eth1: Unable to connect to phy
[   22.000309] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
...

Output of user@myboard:~# cat /sys/kernel/debug/pinctrl/20e0000.pinctrl/pingroups


user@myboard:~# cat /sys/kernel/debug/pinctrl/20e0000.pinctrl/pingroups
registered pin groups:

...

group: enet2grp
pin 59 (MX6UL_PAD_ENET2_RX_EN)
pin 64 (MX6UL_PAD_ENET2_RX_ER)
pin 57 (MX6UL_PAD_ENET2_RX_DATA0)
pin 58 (MX6UL_PAD_ENET2_RX_DATA1)
pin 60 (MX6UL_PAD_ENET2_TX_DATA0)
pin 61 (MX6UL_PAD_ENET2_TX_DATA1)
pin 62 (MX6UL_PAD_ENET2_TX_EN)
pin 63 (MX6UL_PAD_ENET2_TX_CLK)

group: mdioenet2grp
pin 30 (MX6UL_PAD_GPIO1_IO07)
pin 29 (MX6UL_PAD_GPIO1_IO06)

group: enet1gpiogrp
pin 20 (MX6UL_PAD_JTAG_TDI)

group: enet2gpiogrp
pin 22 (MX6UL_PAD_JTAG_TRST_B)

...

group: enet1grp
pin 51 (MX6UL_PAD_ENET1_RX_EN)
pin 56 (MX6UL_PAD_ENET1_RX_ER)
pin 49 (MX6UL_PAD_ENET1_RX_DATA0)
pin 50 (MX6UL_PAD_ENET1_RX_DATA1)
pin 52 (MX6UL_PAD_ENET1_TX_DATA0)
pin 53 (MX6UL_PAD_ENET1_TX_DATA1)
pin 54 (MX6UL_PAD_ENET1_TX_EN)
pin 55 (MX6UL_PAD_ENET1_TX_CLK)

group: mdioenet1grp
pin 30 (MX6UL_PAD_GPIO1_IO07)
pin 29 (MX6UL_PAD_GPIO1_IO06)

...
0

There are 0 best solutions below