Second Ethernet Port

I’m using the Colibri i.MX 8QXP that connects to a custom PCB which brings out the second ethernet port (connected to a Microchip LAN8710A). I’m trying to get the MDIO interface working. We currently have a working ethernet on the first port, and I can see the MDIO signal toggling on the Saleae when reading registers using mdio-tool. However, when I attempt to read the registers from the second ethernet port there is no activity on the MDC/MDIO lines. I suspect that my device tree overlay isn’t configured correctly since the MDC/MDIO lines are shared between the two different ethernet ports on this device.

I’m also unsure how to connect the interrupt and reset signals, but I don’t think that’s relevant regarding the MDIO communication but will be important later if I can get past this MDIO communication issue.

Here is my dmesg output related to the second ethernet port:

[    1.790521] fec 5b050000.ethernet: Invalid MAC address: 00:00:00:00:00:00
[    1.797401] fec 5b050000.ethernet: Using random MAC address: 92:41:e0:42:ba:26
[    1.802356] fec 5b050000.ethernet eth1: registered PHC device 1
[   10.517661] Generic PHY 5b050000.ethernet-2:01: attached PHY driver [Generic PHY] (mii_bus:phy_addr=5b050000.ethernet-2:01, irq=POLL)

As you can see, it attaches the driver and doesn’t show any pin conflicts but also doesn’t establish a link. Below is the current state of my device tree. Any help would be appreciated to get this moving forward.

#define ESAI0_TX3_RX2                      62   
#define ESAI0_TX5_RX0                      64   
#define SPDIF0_TX                          66   
#define ESAI0_SCKR                         57   
#define ESAI0_TX4_RX1                      63   
#define GPIO_71                           159  
#define ESAI0_TX1                          60   
#define SPDIF0_RX                          65   
#define ESAI0_FSR                          55   
#define ESAI0_TX2_RX3                      61   
#define ENET0_MDIO                         52   
#define ENET0_MDC                          53
#define COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0  43
#define COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1  50

#define CONN_ENET1_RGMII_RXD0     SPDIF0_RX      3
#define CONN_ENET1_RGMII_RXD1     ESAI0_TX3_RX2  3
#define CONN_ENET1_RGMII_RX_CTL   SPDIF0_TX      3
#define CONN_ENET1_RGMII_RX_ER    ESAI0_TX2_RX3  1

#define CONN_ENET1_RGMII_TXD0     ESAI0_TX4_RX1  3
#define CONN_ENET1_RGMII_TXD1     ESAI0_TX5_RX0  3
#define CONN_ENT1_RGMII_TX_CTL    ESAI0_SCKR     3
#define CONN_ENET1_RCLK50M_OUT    ESAI0_FSR      1

#define CONN_ENET1_MDIO           ENET0_MDIO     2
#define CONN_ENET1_MDC            ENET0_MDC      2

#define CONN_ENET1_RGMII_RXD3     ESAI0_TX1      3
#define LSIO_GPIO3_IO12           GPIO_71        4

// #define CONN_ENET1_PPS // This pin is listed in the torizon pinout web based gui but not part of our design?

/dts-v1/;
/plugin/;

/ {
    compatible = "toradex,colibri-imx8x";
};

// Enable FastEthernet 2 interface
&fec2 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_fec2>;
    phy-mode = "rmii";
    phy-handle = <&ethphy1>;
    fsl,magic-packet;
    fsl,mii-exclusive;

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

        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <1>;
            device_type = "ethernet-phy";
            max-speed = <100>;

            /* Configure reset timing */
			reset-assert-us = <10000>;
			reset-deassert-us = <10000>;
			reset-names = "phy-reset";
        };
    };
};

&iomuxc {
    cpinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hog0>, <&pinctrl_hog1>, <&pinctrl_hog2>,
            <&pinctrl_ext_io0>, <&pinctrl_lpspi2_cs2>;

    colibri-imx8qxp {
        pinctrl_fec2: fec2grp {
            fsl,pins = <
                // Somehow defining this removes the pin conflicts for MDC/MDIO
                COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0 0x000014a0 // Use pads in 3v3 mode 
                COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1 0x000014a0 // Use pads in 3v3 mode 

                CONN_ENET1_MDC                    0x06000020 //MDC
                CONN_ENET1_MDIO                   0x06000020 //MDIO

                CONN_ENET1_RCLK50M_OUT            0x06000061 //REF_50MHZ
                CONN_ENET1_RGMII_RXD0             0x00000061 //ETH2_RXD0
                CONN_ENET1_RGMII_RXD1             0x00000061 //ETH2_RXD1
                CONN_ENET1_RGMII_RX_ER            0x00000061 //ETH2_RXER
                CONN_ENET1_RGMII_RX_CTL           0x00000061 //RX_CTL
                CONN_ENET1_RGMII_TXD0             0x00000061 //ETH2_TXD0
                CONN_ENET1_RGMII_TXD1             0x00000061 //ETH2_TXD1
                CONN_ENT1_RGMII_TX_CTL            0x00000061 //TX_CTL
        
                LSIO_GPIO3_IO12                   0x00000061 //ETH2_INTRP additional
                CONN_ENET1_RGMII_RXD3             0x00000061 //RESET_ETH2_N additional
            >;
        };
    };
};

*** UPDATE ***
I’m still having issues with the device tree, however I was able to determine that the hardware is functional by manually inserting a 16MHz clock signal onto the XTAL1/CLKIN (pin 5) of the LAN8710A PHY and then use a cross-compiled version of mii-diag to force a read of the internal registers. It should be noted that I’m using the working ethernet0 interface to do this with the following commnd:

./mii-diag-aarch64 ethernet0 -p 1 -v --force

This forces a read of the PHY attached to address 1 using the working ethernet interface. I point this out because I still don’t have the mdio/mdc signals working for the second ethernet port. The values read back from the registers were then validated with expected values from the datasheet as well as visually on a Saleae.

At this point in order to really do any device tree overlay debugging, I need to have a valid reference clock signal generated by the hardware, however I’m having a difficult time getting this to work. In essence based on the device tree overlay originally posted, I need to generate a 50MHz clock on CONN_ENET1_RCLK50M_OUT, however I’ve been unsuccessful thus far.

From the uboot environment settings, the device tree appears to be imx8qxp-colibri-eval-v3.dtb, so I believe that my custom overlay is applied against this specific version.

Other links of interest when drilling down into the device tree design are:
imx8x-colibri-eval-v3.dtsi
imx8qxp.dtsi
imx8-clock.h
imx8qxp-clock.h (this is in the u-boot repo, not the linux repo)

So in summary, I have a working LAN8710A PHY when a clock is driving XTAL1/CLKIN which should be coming from CONN_ENET1_RCLK50M_OUT in the device tree overlay, however I can’t get it to work. Any help would be greatly appreciated.

*** UPDATE ***
I was able to determine the proper way to configure the device tree overlay to utilize a single MDIO interface for both ethernet ports without receiving an error message about unavailable pins from the pin controller. Essentially I needed to add an overlay for &fec1 and include the second ethernet configuration in the mdio section.

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

        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <1>;
            device_type = "ethernet-phy";
            max-speed = <100>;

            /* Configure reset timing */
			reset-assert-us = <10000>;
			reset-deassert-us = <10000>;
			reset-names = "phy-reset";
        };
    };

};

// Enable FastEthernet 2 interface
&fec2 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_fec2>, <&pinctrl_fec2_power>;
    phy-mode = "rmii";
    phy-handle = <&ethphy1>;
    fsl,magic-packet;
    fsl,mii-exclusive;
};

I’ve also been able to utilize /sys/kernel/debug/pinctrl/scu:pinctrl to find out that my mux configuration is actually correct (see the abbreviated output showing linkage to 5b050000.ethernet from pinmux-pins below):

pin 55 (IMX8QXP_ESAI0_FSR): 5b050000.ethernet (GPIO UNCLAIMED) function colibri-imx8qxp group fec2grp

Where I’m at right now is trying to get a clock output on CONN_ENET1_RCLK50M_OUT. What is interesting is that with this value defined in my &iomuxc overlay section, I actually see a 50MHz clock on the oscilloscope sometime during the power up cycle. It only lasts for ~0.5 seconds and then it’s gone. I’m not sure why this is happening (probably related to probing the ethernet at start up) or if there is a conflict with the other ethernet port which leads to it stopping, but it is there if only for a brief amount of time.

Something else of note is that the first ethernet is setting COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0 and COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1. I’m trying to set these as well in my device tree overlay, but it doesn’t appear to be working based on feedback from /sys/kernel/debug/pinctrl/ output. At this point I’m not even sure if this is important. The first ethernet is setting these registers to 0x5d4a0 and I’m trying to set them to 0x000014a0 for the second ethernet. Does anyone know where to lookup the difference in these values?

Also, the LAN8710A datasheet lists an expected value of 25.0MHz for the XTAL1/CLKIN pin, but I’m trying to drive it with 50MHz. I’m assuming that is correct since I want to operate in RMII mode instead of MII mode?

I’m getting closer to getting this to work, and I feel like generating a clock signal on CONN_ENET1_RCLK50M_OUT at the proper frequency will solve a lot if not all of my issues. Any help would be greatly appreciated.

My clock summary from cat /sys/kernel/debug/clk/clk_summary | grep enet1 is below:

 enet1_bypass_clk                     0        0        0    24000000          0     0  50000
 enet1_rgmii_rx_clk                   0        0        0    24000000          0     0  50000
 enet1_root_clk                       0        0        0   250000000          0     0  50000
    enet1_lpcg_txc_sampling_clk       0        0        0   250000000          0     0  50000
    enet1_lpcg_timer_clk              0        0        0   250000000          0     0  50000
    enet1_ref_div                     0        0        0   125000000          0     0  50000
       enet1_rgmii_txc_sel            0        0        0   125000000          0     0  50000
          enet1_lpcg_rgmii_txc_clk    0        0        0   125000000          0     0  50000
    enet1_lpcg_ipg_s_clk              0        0        0    83333333          0     0  50000
    enet1_lpcg_ipg_clk                0        0        0    83333333          0     0  50000
    enet1_lpcg_ahb_clk                0        0        0   333333333          0     0  50000
    enet1_ref_50_clk                  0        0        0           0          0     0  50000

Notice how enet1_ref_50_clk has a frequency of zero.

Latest update is that I see a 50MHz clock at startup, however the voltage level is only at 1.5v. This is problematic because the PHY is running at 3.3v. I’m assuming that the MAC is trying to communicate using this clock, but the PHY doesn’t respond, therefore causing these issues. So I’m currently trying to understand how I can change the voltage level on this clock to 3.3v.

I’m looking to the following pins as they might be relevant?

IMX8QXP_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0
IMX8QXP_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1

However, regardless of how I configure these pins in the device tree I’m always unable to have ethernet 2 @5b050000 claim and therefore control these pins.

I have been able to monitor the reference clock (pin 9) on the KSZ8041 coming from the SOM and it is running at 50MHz at an amplitude of ~1.5v. Furthermore, pin 2 on the KSZ8041 is connected to a reference voltage of 1.8v. This leads me to believe that the voltage on these ethernet signals is locked into 1.8v and might not be configurable. This would be problematic for our design because the PHY on out carrier board has a VDDIO of 3.3v.

At this point I’m fairly confident that this will require a modification to my carrier board to tie VDDIO to 1.8v. To confirm this I’m trying to better understand the functionality of VDD_ENET0_VSELECT_1P8_2P5_3P3 and VDD_ENET0_1P8_2P5_3P3 on the NXP processor. I have seen a reference design which ties these two pins together and connects this to a 1.8v power rail. The naming of VDD_ENET0_VSELECT_1P8_2P5_3P3 leads me to believe that the voltage at this pin selects the voltage that the ethernet signals are operating at. Can someone confirm if this is accurate?

Also, if I need to access 1.8v from my carrier card then can I access a 1.8v rail from the SOM?

Finally, is it possible to get a schematic of the imx8x SOM?

Unfortunately, the i.MX8X SOM schematic is proprietary and cannot be shared. However, we can provide schematic snippets for the required circuits.