Skip to main content
velaros
Associate
August 4, 2021
Solved

Bringing up Ethernet on STM32MP153 with KSZ8081RNB in RMII mode and 25 MHz clock on ETH_CLK (no PHY Crystal)

  • August 4, 2021
  • 7 replies
  • 9019 views

Hello!

I have an issue on a custom board with STM32MP153CAB and KSZ8081RNB.

TF-A, FIP and kernel were built in Developer package. Linux distribution was built as startard configuration st-image-core in Distribution package.

Clocks and device trees are configured like specified in https://wiki.st.com/stm32mpu/wiki/Ethernet_device_tree_configuration#RMII_with_25MHz_on_ETH_CLK_-28no_PHY_Crystal-29-2C_REF_CLK_from_PHY_-28Reference_clock_-28standard_RMII_clock_name-29_is_provided_by_a_RCC_SoC_internal_clock-29

Here are fragments of device tree for U-Boot and kernel (generated by STM32CubeIDE and manually edited):

eth1_pins_mx: eth1_mx-0 {
		pins1 {
			pinmux = <STM32_PINMUX('A', 1, AF11)>, /* ETH1_REF_CLK */
					 <STM32_PINMUX('C', 1, AF11)>, /* ETH1_MDC */
					 <STM32_PINMUX('G', 8, AF2)>, /* ETH1_CLK */
					 <STM32_PINMUX('G', 13, AF11)>, /* ETH1_TXD0 */
					 <STM32_PINMUX('G', 14, AF11)>; /* ETH1_TXD1 */
			bias-disable;
			drive-push-pull;
			slew-rate = <1>;
		};
		pins2 {
			pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH1_MDIO */
			bias-disable;
			drive-push-pull;
			slew-rate = <0>;
		};
		pins3 {
			pinmux = <STM32_PINMUX('A', 7, AF11)>, /* ETH1_CRS_DV */
					 <STM32_PINMUX('C', 4, AF11)>, /* ETH1_RXD0 */
					 <STM32_PINMUX('C', 5, AF11)>; /* ETH1_RXD1 */
			bias-disable;
		};
		pins4 {
			pinmux = <STM32_PINMUX('B', 11, AF11)>; /* ETH1_TX_EN */
		};
	};
 
	eth1_sleep_pins_mx: eth1_sleep_mx-0 {
		pins {
			pinmux = <STM32_PINMUX('A', 1, ANALOG)>, /* ETH1_REF_CLK */
					 <STM32_PINMUX('A', 2, ANALOG)>, /* ETH1_MDIO */
					 <STM32_PINMUX('A', 7, ANALOG)>, /* ETH1_CRS_DV */
					 <STM32_PINMUX('B', 11, ANALOG)>, /* ETH1_TX_EN */
					 <STM32_PINMUX('C', 1, ANALOG)>, /* ETH1_MDC */
					 <STM32_PINMUX('C', 4, ANALOG)>, /* ETH1_RXD0 */
					 <STM32_PINMUX('C', 5, ANALOG)>, /* ETH1_RXD1 */
					 <STM32_PINMUX('G', 8, ANALOG)>, /* ETH1_CLK */
					 <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_TXD0 */
					 <STM32_PINMUX('G', 14, ANALOG)>; /* ETH1_TXD1 */
		};
	};
 
&ethernet0{
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&eth1_pins_mx>;
	pinctrl-1 = <&eth1_sleep_pins_mx>;
	status = "okay";
 
	/* USER CODE BEGIN ethernet0 */
 
	phy-mode = "rmii";
	max-speed = <100>;
	phy-handle = <&phy0>;
	local-mac-address = [XX XX XX XX XX XX];
	mdio0 {
			#address-cells = <1>;
			#size-cells = <0>;
			compatible = "snps,dwmac-mdio";
			phy0: ethernet-phy@1 {
					reg = <1>;
					clocks = <&rcc ETHCK_K>;
					clock-names = "rmii-ref";
 		};
	};
 
	/* USER CODE END ethernet0 */
};

At first, I tested it in U-Boot.

After power on and reset it seems like MPU does not see PHY (and leds on RJ-45 are off). "mdio list" command shows only this: 

ethernet@5800a000:

After I set ipaddr and make ping, leds on RJ-45 become on and the answer to ping is received. The same thing after dhcp or bootp command.

"mdio list" now shows: 

ethernet@5800a000:
1 - Micrel KSZ8081 <--> ethernet@5800a000

When kernel loads, the following log appears: 

...
[ 2.828774] stm32-dwmac 5800a000.ethernet: IRQ eth_lpi not found
[ 2.833564] stm32-dwmac 5800a000.ethernet: PTP uses main clock
[ 2.839294] stm32-dwmac 5800a000.ethernet: no reset control found
[ 2.845980] stm32-dwmac 5800a000.ethernet: User ID: 0x40, Synopsys ID: 0x42
[ 2.852185] stm32-dwmac 5800a000.ethernet: DWMAC4/5
[ 2.857216] stm32-dwmac 5800a000.ethernet: DMA HW capability register supported
[ 2.864426] stm32-dwmac 5800a000.ethernet: RX Checksum Offload Engine supported
[ 2.871772] stm32-dwmac 5800a000.ethernet: TX Checksum insertion supported
[ 2.878618] stm32-dwmac 5800a000.ethernet: Wake-Up On Lan supported
[ 2.884974] stm32-dwmac 5800a000.ethernet: TSO supported
[ 2.890173] stm32-dwmac 5800a000.ethernet: Enable RX Mitigation via HW Watchdog Timer
[ 2.897994] stm32-dwmac 5800a000.ethernet: Enabled Flow TC (entries=2)
[ 2.904475] stm32-dwmac 5800a000.ethernet: TSO feature enabled
[ 2.910324] stm32-dwmac 5800a000.ethernet: Using 32 bits DMA width
[ 2.917336] libphy: stmmac: probed
...
[ 14.178529] stm32-dwmac 5800a000.ethernet eth0: PHY [stmmac-0:01] driver [Micrel KSZ8081 or KSZ8091] (irq=POLL)
[ 14.264265] stm32-dwmac 5800a000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
[ 14.333679] stm32-dwmac 5800a000.ethernet eth0: registered PTP clock
[ 14.369464] stm32-dwmac 5800a000.ethernet eth0: configuring for phy/rmii link mode
...

And I can not make ethernet work in kernel though it must start work automatically with DHCP.

ifconfig says that link is up, but ethtool shows that link is not detected. Autonegotiation does not start on "ethtool -r eth0".

I launched the same linux image (with my builds of TF-A, FIP and device trees) on STM32MP157C-DK2 board. Ethernet starts work immediately after kernel booting or cable plugging in RJ-45. In U-Boot it works the same way as on my board.

What can be the isuue?

This topic has been closed for replies.
Best answer by velaros

I checked this and it seems that SYSCFG ETH_REF_CLK_SEL bit is set, so MAC is really clocked wrongly.

I digged in the linux driver (https://github.com/STMicroelectronics/linux/blob/v5.10-stm32mp/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c) and discovered that in stm32mp1_set_mode() function it always sets this bit with enabling clock.

So using 25 MHz mode without crystal is impossible at all:

...
case PHY_INTERFACE_MODE_RMII:
	val = SYSCFG_PMCR_ETH_SEL_RMII;
	if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
		(dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
		dwmac->enable_eth_ck = true;
		val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
	}
	pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
	break;
...

I changed this to the following:

...
case PHY_INTERFACE_MODE_RMII:
	val = SYSCFG_PMCR_ETH_SEL_RMII;
	if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) {
		dwmac->enable_eth_ck = true;
		if (clk_rate == ETH_CK_F_50M && 
			(dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
			val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
		}
	}
	pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
	break;
...

And now it finally works fine in 25 MHz mode, and I can see clock on PCB.

I don't really get the meaning of "st,ext-phyclk" so my patch may be wrong. But the current driver definitely seems buggy. I didn't checked U-Boot but there also may be similar bugs.

As I understand, in the master of the ST Linux repository this driver is reworked, so it may be not the issue in future releases.

7 replies

OlivierK
Technical Moderator
August 27, 2021

Hi velaros (Community Member)

Some remarks/hints

  • To me it is strange to see clocks and clock-names in the phy node, these should be added in the stm32mp151.dtsi in U-boot/Kernel DT source files.

clocks = <&rcc ETHCK_K>;

clock-names = "rmii-ref";

  • I guess you've updated TFA devicetree to generate 25Mhz clock (from PLL4P or PLL3Q)
  • Are you sure you are using the Micrel PHY?

>make menuconfig

Symbol: PHY_MICREL_KSZ8XXX [=n] │

│ Type : bool │

│ Prompt: Micrel KSZ8xxx family support │

│ Location: │

│ -> Device Drivers │

│ -> Ethernet PHY (physical media interface) support (PHYLIB [=y]) │

│ (2) -> Micrel Ethernet PHYs support (PHY_MICREL [=n])

  • Digging the subject, we had a similar case (autonegociation fails) with the same PHY because the u-boot driver was not up to date.

PHY patch:

diff --git a/drivers/net/phy/micrel_ksz8xxx.c b/drivers/net/phy/micrel_ksz8xxx.c

index 60d42fe984..7f96d1e393 100644

--- a/drivers/net/phy/micrel_ksz8xxx.c

+++ b/drivers/net/phy/micrel_ksz8xxx.c

@@ -28,6 +28,11 @@ static struct phy_driver KSZ804_driver = {

#define KSZPHY_OMSO_FACTORY_TEST BIT(15)

#define KSZPHY_OMSO_B_CAST_OFF (1 << 9)

+#define MII_KSZPHY_CTRL_1 0x1e

+#define MII_KSZPHY_CTRL_2 0x1f

+#define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2

+#define KSZPHY_RMII_REF_CLK_SEL BIT(7)

+

static int ksz_genconfig_bcastoff(struct phy_device *phydev)

{

int ret;

@@ -102,13 +107,24 @@ static int ksz8081_config(struct phy_device *phydev)

int ret;

ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO);

+

if (ret < 0)

return ret;

ret &= ~KSZPHY_OMSO_FACTORY_TEST;

+ ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO, ret);

+

+ if (ret < 0)

+ return ret;

+

+ ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_CTRL);

+

+ if (ret < 0)

+ return ret;

+

+ ret |= KSZPHY_RMII_REF_CLK_SEL;

+ ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_CTRL, ret);

- ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO,

- ret | KSZPHY_OMSO_B_CAST_OFF);

if (ret < 0)

return ret;

Hope it helps.

Regards,

Olivier

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.
velaros
velarosAuthor
Associate
August 30, 2021

Hi, Olivier!

Сlocks and clock-names in phy node is specifically requested for micrel PHYs to specify the frequency (https://www.kernel.org/doc/Documentation/devicetree/bindings/net/micrel.txt). Of course, this clock is declared in the dts header stm32mp151.dtsi. 

TFA devicetree is configured for using 25 MHz from PLL3Q.

The Micrel PHY is selected in menuconfig (as you can see, U-Boot shows the correct name of the PHY).

As far as I understand, your U-Boot patch force PHY to 50 MHz clk mode. I tried it and PHY not worked at all (negotiation failed), while before patching it worked after "dhcp" command.

I checked the settings written to PHY by kernel, and seems like kernel writes correct '0' value to clock select bit.

velaros
velarosAuthor
Associate
August 31, 2021

I have found that actually I don't need to use 25 MHz clock at ETH_CLK.

I changed settings to 50 MHz and patched device trees as specified at https://wiki.st.com/stm32mpu/wiki/Ethernet_device_tree_configuration#RMII_with_50MHz_on_ETH_CLK_-28no_PHY_Crystal-29-2C_internal_REF_CLK_from_RCC_-28Reference_clock_-28standard_RMII_clock_name-29_is_provided_by_a_RCC_SoC_internal_clock-29

With these setting eth0 is working right after kernel booting.

My problem is solved because it is not critical for me to use 25 MHz clock but there still may be some issue if someone really need this mode.

PatrickF
Technical Moderator
August 31, 2021

Hi,

Could you share your HW Setup around KSZ8081RNB ?

Do you have 25MHz crystal on XI/XO pins or XI connected to ETH_CLK ?

Is the KSZ8081RNB REF_CLK pin connected to STM32MP15x REF_CLK pin ?

What is the config of KSZ8081RNB SW setting between 25MHz and 50MHz mode ?

I suggest to carefully map the right Device Tree from wiki with your HW. See also AN5031.

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.NEW ! Sidekick STM32 AI agent, see here
velaros
velarosAuthor
Associate
September 6, 2021

Hi, Patrick.

The fragment of schematic is attached.

There is no crystal, XI is connected to ETH_CLK, REF_CLK is connected to STM32MP153.

I wrote my device tree as said in wiki, the ethernet fragment is shown in the first message. As I can see, my settings satisfy requirements from AN5031.

To use 50MHz the config was changed as follows:

- ETH_CLK was set to 50MHz (TFA and U-Boot device trees generated from STM32CubeIDE);

- pinctrl changed, and added "st,eth-ref-clk-sel" to ethernet node:

	eth1_pins_mx: eth1_mx-0 {
		pins1 {
			pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH1_MDIO */
			bias-disable;
			drive-push-pull;
			slew-rate = <0>;
		};
		pins2 {
			pinmux = <STM32_PINMUX('A', 7, AF11)>, /* ETH1_CRS_DV */
					 <STM32_PINMUX('C', 4, AF11)>, /* ETH1_RXD0 */
					 <STM32_PINMUX('C', 5, AF11)>, /* ETH1_RXD1 */
					 <STM32_PINMUX('G', 12, AF11)>; /* ETH1_PHY_INTN */
			bias-disable;
		};
		pins3 {
			pinmux = <STM32_PINMUX('B', 11, AF11)>; /* ETH1_TX_EN */
		};
		pins4 {
			pinmux = <STM32_PINMUX('C', 1, AF11)>, /* ETH1_MDC */
					 <STM32_PINMUX('G', 8, AF2)>, /* ETH1_CLK */
					 <STM32_PINMUX('G', 13, AF11)>, /* ETH1_TXD0 */
					 <STM32_PINMUX('G', 14, AF11)>; /* ETH1_TXD1 */
			bias-disable;
			drive-push-pull;
			slew-rate = <1>;
		};
	};
 
	eth1_sleep_pins_mx: eth1_sleep_mx-0 {
		pins {
			pinmux = <STM32_PINMUX('A', 2, ANALOG)>, /* ETH1_MDIO */
					 <STM32_PINMUX('A', 7, ANALOG)>, /* ETH1_CRS_DV */
					 <STM32_PINMUX('B', 11, ANALOG)>, /* ETH1_TX_EN */
					 <STM32_PINMUX('C', 1, ANALOG)>, /* ETH1_MDC */
					 <STM32_PINMUX('C', 4, ANALOG)>, /* ETH1_RXD0 */
					 <STM32_PINMUX('C', 5, ANALOG)>, /* ETH1_RXD1 */
					 <STM32_PINMUX('G', 8, ANALOG)>, /* ETH1_CLK */
					 <STM32_PINMUX('G', 12, ANALOG)>, /* ETH1_PHY_INTN */
					 <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_TXD0 */
					 <STM32_PINMUX('G', 14, ANALOG)>; /* ETH1_TXD1 */
		};
	};
 
&ethernet0{
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&eth1_pins_mx>;
	pinctrl-1 = <&eth1_sleep_pins_mx>;
	status = "okay";
 
	/* USER CODE BEGIN ethernet0 */
	
	phy-mode = "rmii";
	max-speed = <100>;
	phy-handle = <&phy0>;
	st,eth-ref-clk-sel;
	local-mac-address = [XX XX XX XX XX XX];
	mdio0 {
			#address-cells = <1>;
			#size-cells = <0>;
			compatible = "snps,dwmac-mdio";
			phy0: ethernet-phy@1 {
					reg = <1>;
					clocks = <&rcc ETHCK_K>;
					clock-names = "rmii-ref";
 		};
	};
	
	/* USER CODE END ethernet0 */
};

0693W00000DmHrUQAV.png

OlivierK
Technical Moderator
September 6, 2021

Hi,

The issue might be linked to the 50MHz Eth ref clk coming from the PHY not seen by the MAC in the initial 25MHz configuration. Did you checked at the oscilloscope you truly had the Eth_ref_clk=50MHz on PA1 ?

Rgds,

Olivier

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.
velaros
velarosAuthor
Associate
September 10, 2021

Replied your answer below, in answer to Patrick's message.

PatrickF
Technical Moderator
September 6, 2021

Hi,

if you feed 50MHz to PHY (and btw 50MHz internally from RCC to GMAC), you don't need to connect the REF_CLK, but this should not hurt (you could gain one pin).

Note that st,eth-ref-clk-sel (or st,eth_ref_clk_sel for uBoot) is for ecosystem v2.1 using kernel 5.4

For ecosystem v3 and kernel 5.10, it is st,ext-phyclk (for both kernel and uBoot).

Did you check that your PHY is correctly setup to use 50MHz on XI ?

I understand from KSZ8081RNB datasheet that driver need to set internal KSZ8081RNB registers 0x1F bit 7 to enable that.

Did you check that the 50MHz output is present on pin PG8 ?

Did you check you correctly enabled the 50MHz clock tree with right frequency in TF-A ?

e.g. with PLL4P (VCO @ 600MHz)

st,pkcs = <
....
 CLK_ETH_PLL4P
....
 pll4: st,pll@3 {
 compatible = "st,stm32mp1-pll";
 reg = <3>;
 cfg = < 1 49 11 9 9 PQR(1,1,1) >;
 };

You could use cat /sys/kernel/debug/clk/clk_summary to check PLL4P or PLL3Q frequency and usage

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.NEW ! Sidekick STM32 AI agent, see here
velaros
velarosAuthor
Associate
September 10, 2021

When I use ETH_CLK at 50 MHz all works perfectly, so I think the PHY is set up correctly.

I checked PHY setup when ETH_CLK was at 25 MHz and it seems that it also get correct setup (I added printf to kernel code and this register was set it should be).

Unfortunately I cannot test signals directly on STM32 pins because of BGA package. So I tested ETH_CLK on the R3 resistor and KSZ8081 input pin. At 50 MHz the signal is correct, but at 25 MHz there is no clock.

I checked clk_summary and got the following:

At 50 MHz:

enable prepare protect duty
 clock count count count rate accuracy phase cycle
---------------------------------------------------------------------------------------------
...
 pll3_q 1 1 0 50000000 0 0 50000
 ethptp_k 0 0 0 50000000 0 0 50000
 ethck_k 1 1 0 50000000 0 0 50000

At 25 MHz:

enable prepare protect duty
 clock count count count rate accuracy phase cycle
---------------------------------------------------------------------------------------------
...
 pll3_q 0 0 0 25000000 0 0 47619
 ethptp_k 0 0 0 25000000 0 0 50000
 ethck_k 0 0 0 25000000 0 0 50000

I see that "enable count" for pll3_q and ethck_k is 0 at 25 MHz, so it explains the absence of clock but I don't know why it is not enabled.

I also tried to use pll4_p as source for ETH_CLK, but result was the same.

I tested ETH_REF_CLK when 25 MHz was absent and got a signal of about 28 MHz. As I cannot test in on STM32 BGA package I tested in using PCB via in the middle of the signal.

At the same time Ethernet worked in U-Boot but I don't know how.

My clock setting in device trees:

 At 50 MHz (PLL3Q), not using ETH_REF_CLK:

st,pkcs = <
		CLK_CKPER_DISABLED
		CLK_FMC_ACLK
		CLK_ETH_PLL3Q
		CLK_SDMMC12_PLL3R
		CLK_STGEN_HSI
		CLK_USBPHY_PLL4R
...
	pll3:st,pll@2 {
		compatible = "st,stm32mp1-pll";
		reg = <2>;
		cfg = < 1 49 2 11 2 PQR(1,1,1) >;
	};
	pll4:st,pll@3 {
		compatible = "st,stm32mp1-pll";
		reg = <3>;
		cfg = < 2 59 1 1 19 PQR(0,0,1) >;
	};

At 25 MHz (PLL3Q):

st,pkcs = <
		CLK_CKPER_DISABLED
		CLK_FMC_ACLK
		CLK_ETH_PLL3Q
		CLK_SDMMC12_PLL3R
		CLK_STGEN_HSI
		CLK_USBPHY_PLL4R
...
	pll3:st,pll@2 {
		compatible = "st,stm32mp1-pll";
		reg = <2>;
		cfg = < 1 42 2 20 2 PQR(1,1,1) >;
		frac = < 0x1800 >;
	};
	pll4:st,pll@3 {
		compatible = "st,stm32mp1-pll";
		reg = <3>;
		cfg = < 2 59 1 1 19 PQR(0,0,1) >;
	};

At 25 MHz (PLL4P):

st,pkcs = <
		CLK_CKPER_DISABLED
		CLK_FMC_ACLK
		CLK_ETH_PLL4P
		CLK_SDMMC12_PLL3R
		CLK_STGEN_HSI
		CLK_USBPHY_HSE
...
	pll3:st,pll@2 {
		compatible = "st,stm32mp1-pll";
		reg = <2>;
		cfg = < 1 42 2 20 2 PQR(1,0,1) >;
		frac = < 0x1800 >;
	};
	pll4:st,pll@3 {
		compatible = "st,stm32mp1-pll";
		reg = <3>;
		cfg = < 1 49 23 1 11 PQR(1,0,1) >;
	};

Pins at 25 MHz:

eth1_pins_mx: eth1_mx-0 {
		pins1 {
			pinmux = <STM32_PINMUX('A', 1, AF11)>, /* ETH1_REF_CLK */
					 <STM32_PINMUX('C', 1, AF11)>, /* ETH1_MDC */
					 <STM32_PINMUX('G', 8, AF2)>, /* ETH1_CLK */
					 <STM32_PINMUX('G', 13, AF11)>, /* ETH1_TXD0 */
					 <STM32_PINMUX('G', 14, AF11)>; /* ETH1_TXD1 */
			bias-disable;
			drive-push-pull;
			slew-rate = <1>;
		};
		pins2 {
			pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH1_MDIO */
			bias-disable;
			drive-push-pull;
			slew-rate = <0>;
		};
		pins3 {
			pinmux = <STM32_PINMUX('A', 7, AF11)>, /* ETH1_CRS_DV */
					 <STM32_PINMUX('C', 4, AF11)>, /* ETH1_RXD0 */
					 <STM32_PINMUX('C', 5, AF11)>, /* ETH1_RXD1 */
					 <STM32_PINMUX('G', 12, AF11)>; /* ETH1_PHY_INTN */
			bias-disable;
		};
		pins4 {
			pinmux = <STM32_PINMUX('B', 11, AF11)>; /* ETH1_TX_EN */
		};
	};

PatrickF
Technical Moderator
September 13, 2021

Hi,

I'm puzzled with your statements, what is your target ?

  • ETH_CLK providing 25MHz to XI. REF_CLK signal from PHY to STM32MP15x ETH pin.
  • ETH_CLK providing 50MHz to XI. No REF_CLK wire (i.e. internal STM32MP15x connection to ETH IP)

I'm not sure the Micrel driver support the 1st option (i.e. it might support only crystal for 25MHz), so might explain why there is no 25MHz.

I'm not SW expert, but as far as I have understand the Micrel driver might assume 50MHz as soon as external clock is defined in the DT.

Could you please confirm which ecosystem are you using (ecosystem v2.1 / kernel 5.4 or ecosystem v3.0 / kernel 5.10) ?

It is important to know as I already mentioned, the device Tree for ETH_CLK setting has evolved between this 2 ecosystems versions.

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.NEW ! Sidekick STM32 AI agent, see here
OlivierK
Technical Moderator
September 14, 2021

Hi velaros (Community Member)

Looking at the Ethernet driver in <linux-5.10.10>/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c

0693W00000Dn9X1QAJ.jpg 

Indeed the st,ext-phyclk seems also needed for the RMII 25MHz no crystal configuration with the ostl DV 3.0 version. Which is not what the wiki documentation says, apologies for that. Each DV version and each configuration has a specific DT configuration to respect (DV2.x, DV3.0, DV3.1)

Regarding the fact ping is still not available in 25MHz configuration, check the SYSCFG ETH_REF_CLK_SEL bit as explained by Patrick above.

I think when you use st,ext-phyclk , you select clocking of the MAC from ETH_CLK instead of REF_CLK (see SYSCFG ETH_REF_CLK_SEL bit), so the MAC is wrongly clocked with 25MHz instead of 50MHz.

Regards,

Olivier

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.
velaros
velarosAuthorBest answer
Associate
September 15, 2021

I checked this and it seems that SYSCFG ETH_REF_CLK_SEL bit is set, so MAC is really clocked wrongly.

I digged in the linux driver (https://github.com/STMicroelectronics/linux/blob/v5.10-stm32mp/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c) and discovered that in stm32mp1_set_mode() function it always sets this bit with enabling clock.

So using 25 MHz mode without crystal is impossible at all:

...
case PHY_INTERFACE_MODE_RMII:
	val = SYSCFG_PMCR_ETH_SEL_RMII;
	if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
		(dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
		dwmac->enable_eth_ck = true;
		val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
	}
	pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
	break;
...

I changed this to the following:

...
case PHY_INTERFACE_MODE_RMII:
	val = SYSCFG_PMCR_ETH_SEL_RMII;
	if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) {
		dwmac->enable_eth_ck = true;
		if (clk_rate == ETH_CK_F_50M && 
			(dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
			val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
		}
	}
	pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
	break;
...

And now it finally works fine in 25 MHz mode, and I can see clock on PCB.

I don't really get the meaning of "st,ext-phyclk" so my patch may be wrong. But the current driver definitely seems buggy. I didn't checked U-Boot but there also may be similar bugs.

As I understand, in the master of the ST Linux repository this driver is reworked, so it may be not the issue in future releases.

OlivierK
Technical Moderator
September 15, 2021

Hi velaros (Community Member)

Indeed you've just found a bug in the dwmac-stm32.c driver DV3.0 version. And you are right in the next versions (DV3.1 +) the "st,ext-phyclk" will be removed for the 25MHz no crystal configuration. Your patch is correct, I will report that as bug for correction on the DV3.0 version.

Thank you for this thread of messages and for your contribution in solving this issue.

Regards,

Olivier

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.
velaros
velarosAuthor
Associate
September 16, 2021

Thank you for help and tips!

PatrickF
Technical Moderator
September 22, 2021

In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

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.NEW ! Sidekick STM32 AI agent, see here