cancel
Showing results for 
Search instead for 
Did you mean: 

No PHY link with DP83867 (RGMII) on STM32MP2 — missing 125MHz clock config?

Bar01
Associate II

 Hi,

I've been struggling for a while now with the STM32MP257D, specifically trying to get the TI DP83867 Ethernet PHY working over RGMII. The issue is that my custom board layout doesn't provide a CLK_125MHZ signal from the PHY, so based on the ST tutorial from this link, I add the st,ext-phyclk flag to the eth1/eth2 nodes in the stm32mp251.dtsi and stm32mp253.dtsi files. I also updated my board's .dtsi with the proper compatible and reg entries. Here’s what the eth2 node looks like:

 

&eth2 {
	status = "okay";
	pinctrl-0 = <&eth2_rgmii_pins_a>;
	pinctrl-1 = <&eth2_rgmii_sleep_pins_a>;
	pinctrl-names = "default", "sleep";
	phy-mode = "rgmii-id";
	max-speed = <100>;
	phy-handle = <&phy1_eth2>;
	st,eth-ptp-from-rcc;

	mdio1 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "snps,dwmac-mdio";

		phy1_eth2: ethernet-phy@12 {
			reg = <12>;
			compatible = "ethernet-phy-id2000.a231";
			ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
			ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
		};
	};
};

But when I boot the board I get this error:

stm32-dwmac 482d0000.eth2 end2: __stmmac_open: Cannot attach to PHY (error: -22)

 Interestingly, if I patch /usr/sbin/ttt-ip-init-systemd.sh to tweak the reg addresses, I do get this in the logs:

sw0p3: Connected PHY TI DP83867 at 'stmmac-1:00' to port
sw0p2: Connected PHY TI DP83867 at 'stmmac-1:03' to port

So it looks like the driver sees the PHY, but still, no actual communication is happening on any port.

 

Now, according to the ST guide I linked above, I should be generating the 125 MHz clock from pll4p or pll3q, but that part of the page seems incomplete (especially for MP2 devices), and I'm not sure if it's even required or how exactly I should do it.

Can someone confirm if that 125MHz clock generation from RCC is mandatory in this case, and maybe give a quick example of how to do it correctly for STM32MP25x?

Thanks in advance!

8 REPLIES 8
Erwan SZYMANSKI
ST Employee

Hello @Bar01 ,
I think there is a misunderstanding somewhere regarding your inputs.

eth2 node refers to ETH2 that is the standalone ethernet interface (not linked to the internal TSN switch)

/usr/sbin/ttt-ip-init-systemd.sh script refers to the switch configuration script, involving ETH1 + ETH3 that are connected to the internal switch. They both have their own PHY and this is what you see here 

sw0p3: Connected PHY TI DP83867 at 'stmmac-1:00' to port
sw0p2: Connected PHY TI DP83867 at 'stmmac-1:03' to port

Can you precise on which Ethernet you have trouble that you want to fix ? Maybe you also have some schematics ?

(From my understanding, your issue is only on standalone Ethernet right ?)

Kind regards,
Erwan. 

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Bar01
Associate II

 

Hi,

Thanks for the clarification — yes, I'm aware that the /usr/sbin/ttt-ip-init-systemd.sh script refers to the internal switch configuration (ETH1 and ETH3).
However, the core issue seems to be deeper — specifically at the PHY configuration level.

All three PHYs on my board are TI DP83867, each using the same configuration, with different strap resistors to set unique reg addresses, but none of them respond properly, regardless of whether they are connected to the internal TSN switch (ETH1/ETH3) or the standalone interface (ETH2).
The PHYs are physically functional — the same schematic works in another project (not based on MP2), and the RJ45 link LEDs light up when a cable is connected — but there's still no communication between devices.

From what I understand, the issue likely comes from the fact that the PHYs do not provide a 125 MHz clock via CLK_125MHZ, and I need to generate it from the RCC using PLL4P or PLL3Q, as it was mentioned here.

The ST wiki shows a general approach for STM32MP1, but I couldn’t find a clear example for STM32MP2.
The MP2 device tree structure seems quite different, and I’m unsure how to correctly define the 125 MHz clock.

For example, in stm32mp257f-ev1-ca35tdcid-rcc.dtsi, I found the following node:

pll4: st,pll-4 {
		st,pll = <&pll4_cfg_1200Mhz>;

		pll4_cfg_1200Mhz: pll4-cfg-1200Mhz {
			cfg = <30 1 1 1>;
			src=<MUX_CFG(MUX_MUXSEL0, MUXSEL_HSE)>;
		};
	};
 

…but I’m not sure how to interpret or adapt this for generating a 125 MHz output clock for the PHY via RCC.

Would you be able to confirm:

  1. Is generating the 125 MHz reference clock mandatory when using RGMII without CLK_125 from the PHY?

  2. If so, could you provide an example (or point me to one) of how to generate this clock correctly on STM32MP2?

Thanks again for your support!

Hello @Bar01 ,
First let's focus on ETH2 investigations to debug the PHY. You can also refer to the Reference Manual of STM32MP2, RCC--> RCC functionnal description - Clocks --> Ethernet interface clocking --> Clock diagram.

Did you check the /sys/kernel/debug/clk/clk_summary ? Can you share here the output concerning eth2 clocks ?

I think the ck_ker_eth2 should be to 125M by default with our ecosystem release, but let's check.

According the device tree modification you saw, st,ext-phyclk parameter is used to change the ETHX_CLK_SEL value you see in the refman chapter I mentioned above (better to add this property directly in the board DTS and not in DTSI, so that I can better follow your modifications live, dtsi files are not supposed to be changed as it is part of SoC config).

Then you should probe the 125M signal with an oscilloscope, see if well goes out the MP2 pin you are expected for. If not, maybe check the pinctrl configuration you have.

Keep me in touch after your different tests.

Kind regards,
Erwan.

 

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Bar01
Associate II

Hi Erwan,

Thanks for the follow-up. I checked the clocks via /sys/kernel/debug/clk/clk_summary and everything looks as expected. Here's the relevant part for grep eth2:

clock enable prepareprotectrateaccuracyphasedutyenableconsumer idconnection id
ck_ker_eth2rx1102000000000050000Y482d0000.eth2mac-clk-rx
ck_ker_eth2tx1102000000000050000Y482d0000.eth2mac-clk-tx
ck_ker_eth2mac1102000000000050000Y482d0000.eth2stmmaceth
ck_ker_eth2stp0002000000000050000N482d0000.eth2ethstp
ck_icn_p_eth20002000000000050000Ydevicelessno_connection_id
ck_ker_eth2ptp0002000000000050000Y482d0000.eth2ptp_ref
ck_ker_eth21101250000000050000Y482d0000.eth2eth-ck

I also configured the ETH_RGMII_CLK125 pin (PF8) in the device tree, based on STM32CubeMX output:

eth2_rgmii_pins_a: eth2-rgmii-0 {
		pins1 {
			pinmux = <STM32_PINMUX('C', 7, AF10)>, /* ETH_RGMII_TXD0 */
				 <STM32_PINMUX('C', 8, AF10)>, /* ETH_RGMII_TXD1 */
				 <STM32_PINMUX('C', 9, AF10)>, /* ETH_RGMII_TXD2 */
				 <STM32_PINMUX('C', 10, AF10)>, /* ETH_RGMII_TXD3 */
				 <STM32_PINMUX('C', 4, AF10)>; /* ETH_RGMII_TX_CTL */
			bias-disable;
			drive-push-pull;
			slew-rate = <3>;
			st,io-retime = <1>;
			st,io-clk-edge = <1>;
		};
		pins2 {
			pinmux = <STM32_PINMUX('F', 7, AF10)>, /* ETH_RGMII_GTX_CLK */
				 <STM32_PINMUX('C', 6, AF10)>; /* ETH_MDC */
			bias-disable;
			drive-push-pull;
			slew-rate = <3>;
		};
		pins3 {
			pinmux = <STM32_PINMUX('C', 5, AF10)>; /* ETH_MDIO */
			bias-disable;
			drive-push-pull;
			slew-rate = <0>;
		};
		pins4 {
			pinmux = <STM32_PINMUX('G', 0, AF10)>, /* ETH_RGMII_RXD0 */
				 <STM32_PINMUX('C', 12, AF10)>, /* ETH_RGMII_RXD1 */
				 <STM32_PINMUX('F', 9, AF10)>, /* ETH_RGMII_RXD2 */
				 <STM32_PINMUX('C', 11, AF10)>, /* ETH_RGMII_RXD3 */
				 <STM32_PINMUX('C', 3, AF10)>; /* ETH_RGMII_RX_CTL */
			bias-disable;
			st,io-retime = <1>;
			st,io-clk-edge = <1>;
		};
		pins5 {
			pinmux = <STM32_PINMUX('F', 6, AF10)>; /* ETH_RGMII_RX_CLK */
			bias-disable;
		};
		/* ADDED */
		pins6 {
			pinmux = <STM32_PINMUX('F', 8, AF10)>; /* ETH_RGMII_CLK125 */
		};
	};

And the system correctly reports this pin as active:

pin 88 (PF8): device 482d0000.eth2 function af10 group PF8

However, after probing the PF8 pin with an oscilloscope (even after plugging in ethernet cable), I noticed only a small DC bias around 0,3V. So it seems the output clock is not being driven despite the device tree and clock summary being seemingly correct.

And after all I’m still getting the same error during boot:

stm32-dwmac 482d0000.eth2 end2: validation of rgmii-id with support 00,00000000,00000000,00006280 and advertisement 00,00000000,00000000,00006280 failed: -EINVAL
stm32-dwmac 482d0000.eth2 end2: __stmmac_open: Cannot attach to PHY (error: -22)

I verified the other clock-related pins as well:

  • X_I (external clock input to PHY) receives a clean 25 MHz from an external oscillator,
  • GTX_CLK from the PHY runs at 125 MHz as expected (based on datasheet behavior).
  • However, RX_CLK is outputting 2,5 MHz when configured for 100 Mbps via devicetree (it should be 25MHz), which seems more like the behavior for 10 Mbps — this inconsistency feels suspicious.

Maybe the problem is something simple, like PF8 not being fully configured to actually output the clock?

Or maybe I’m missing some mux or pinctrl setting that would make ETH_RGMII_CLK125 actually drive the signal out?

Any pointers on what else I could check would be great.

 

Hello @Bar01 ,
I do not know exactly your PHY reference, but are you sure you do not need any reset-gpios declared ? I found strange that you have nothing related to a kind of init sequence in your device tree (see example below)

&eth2 {
	status = "okay";
	pinctrl-0 = <&eth2_rgmii_pins_a>;
	pinctrl-1 = <&eth2_rgmii_sleep_pins_a>;
	pinctrl-names = "default", "sleep";
	phy-mode = "rgmii-id";
	max-speed = <1000>;
	phy-handle = <&phy1_eth2>;
	st,eth-ptp-from-rcc;

	mdio1 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "snps,dwmac-mdio";
		phy1_eth2: ethernet-phy@1 {
			compatible = "ethernet-phy-id001c.c916";
			reset-gpios =  <&gpiog 6 GPIO_ACTIVE_LOW>;
			reset-assert-us = <10000>;
			reset-deassert-us = <80000>;
			realtek,eee-disable;
			reg = <1>;
		};
	};
};

In your own design, you have no GPIO link to any kind of RST signal on your PHY ? 

Kind regards,
Erwan.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Bar01
Associate II

Hi,

Thanks for pointing that out. I'm attaching the schematics for the PHY connection to help clarify things — just note that they don’t show the strap resistor used to set reg = <12>; that was added later.

eth2_scheme.png

You're right, I don’t have a reset-gpios declared in the device tree, because in my design the RESET (pin 43) of the DP83867 is tied to GND through a 10nF capacitor (C10), which handles power on reset behavior.

I do have a signal connected to PWDN (pin 44), but it's not currently used in device tree— this pin puts the PHY into low power mode, which I don’t need right now, so it's left inactive, always tied to 3V3.

I don’t think the issue is related to reset — the PHY seems to be responding. When I plug in a cable, the link is detected and the PHY link/activity LEDs light up correctly, so it doesn't appear to be stuck in reset or powerdown.

Let me know if anything in the schematic looks off — happy to double-check.

Best regards

Hi @Bar01 


  • GTX_CLK from the PHY runs at 125 MHz as expected (based on datasheet behavior).
  • However, RX_CLK is outputting 2,5 MHz when configured for 100 Mbps via devicetree (it should be 25MHz), which seems more like the behavior for 10 Mbps — this inconsistency feels suspicious.

GTX_CLK is an output from STM32MP25 and an input to the PHY, so this should confirm the RCC is correctly feeding internally the 125MHz clock to the GMAC.

RX_CLK is an output from the PHY and I think it is recovered from the MDI, so the actual frequency might depend on the detected link on the RJ45 and not from the device tree.

Hope this will help to go further.

Regards.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Bar01
Associate II

I was finally able to identify the cause by carefully probing each signal with an oscilloscope and comparing it to the reference design.

It turned out the issue was not related to the lack of a dedicated reset pin for the PHY — the power-on reset using a properly selected capacitor works just fine for this setup.

The real problem was a misconfiguration of the strap resistors, specifically those related to the MDIO delay mode. Their values were chosen very unluckily and should not have been installed at all (R4/R5/R6/R7).  Based on the PHY requirements, the delay for TX_CLK and RX_CLK must be in the range of 1.0 ns to 2.6 ns (1.5 ns to 2.0 ns is a safe zone).
On my layout, the strap resistor combination selected an invalid mode, which effectively pulled the MDIO line low, similar issue was described here. As a result, the PHY failed to expose its registers properly during initialization, causing the driver to be unable to attach.

Once I corrected the strap configuration to match a valid delay mode, everything started working as expected.