1. Article purpose[edit source]
This article explains how to configure the Ethernet when it is assigned to the Linux® OS. In that case, it is controlled by the Ethernet framework.
The configuration is performed using the device tree mechanism that provides a hardware description of the Ethernet peripheral, used by the STM32 DWMAC driver.
2. DT bindings documentation[edit source]
The Ethernet is a multifunction device.
Each function is represented by a separate binding document:
3. DT configuration[edit source]
This hardware description is a combination of the STM32 microprocessor device tree files (.dtsi extension) and board device tree files (.dts extension). See the Device tree for an explanation of the device tree file split.
3.1. DT configuration (STM32 level)[edit source]
Ethernet peripheral nodes are located in stm32mp151.dtsi [3] file with a disabled status and some required properties such as:
- Physical base address and size of the device register map
- STM32 DWMAC interrupts
- stmmaceth clock and Rx, Tx clocks
This is a set of properties that may not vary for a given STM32MP device, such as: register addresses, interrupts, clocks, ...
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq", "eth_wake_irq"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
The required and optional properties are fully described in the bindings files.
3.2. Ethernet DT configuration (board level)[edit source]
The device tree board file (.dts) contains all hardware configurations related to board design. The DT node ("ethernet") should be updated to:
- Enable the Ethernet block by setting status = "okay".
- Configure the pins in use via pinctrl, through pinctrl-0 (default pins), pinctrl-1 (sleep pins) and pinctrl-names.
- Configure Ethernet interface used phy-mode = "rgmii"., (rmii, mii, gmii).
- Configure Ethernet max speed max-speed = <1000>"..
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@1 { reg = <1>; }; }; };
3.3. DT configuration examples at board level[edit source]
The example below shows how to configure and enable an Ethernet instance
ðernet0 { status = "okay"; /* enable ethernet0 */ pinctrl-0 = <ðernet0_rmii_pins_a>; /* configure pinctrl modes for ethernet0 */ pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; /* configure ethernet0_rmii_pins_sleep_a as sleep pinctrl configuration for ethernet0 */ pinctrl-names = "default", "sleep"; phy-mode = "rmii"; /* configure ethernet phy mode for ethernet0 */ max-speed = <100>; /* configure ethernet max speed for ethernet0 */ phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@1 { reg = <1>; /* configure ethernet phy @ for ethernet0 */ }; }; };
How to configure Ethernet for :
3.3.1. RMII with Crystal on PHY (Reference clock (standard RMII clock name) is provided by a Phy Crystal)[edit source]
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rmii_pins_a>; pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rmii"; max-speed = <100>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
3.3.2. RMII with 25MHz on ETH_CLK (no PHY Crystal), REF_CLK from PHY (Reference clock (standard RMII clock name) is provided by a PHY)[edit source]
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rmii_pins_a>; pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rmii"; max-speed = <100>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
+ update stm32mp15-pinctrl.dtsi [4] to add ETHCK pin in ethernet0_rmii_pins_* node:
For example:
<STM32_PINMUX('G', 8, AF2)>, /* ETH_RMII_ETHCK */
+ Need also to update TFA devicetree to generate 25Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P in ed1 board:
update fdts/stm32mp15xx-edx.dtsi
st,pkcs = < CLK_CKPER_HSE CLK_FMC_ACLK CLK_QSPI_ACLK - CLK_ETH_DISABLED + CLK_ETH_PLL4P ... /* VCO = 600.0 MHz => P = 25, Q = 50, R = 50 */ pll4: st,pll@3 { compatible = "st,stm32mp1-pll"; reg = <3>; cfg = < 1 49 23 11 11 PQR(1,1,1) >; };
3.3.3. RMII with 50MHz on ETH_CLK (no PHY Crystal), internal REF_CLK from RCC (Reference clock (standard RMII clock name) is provided by a RCC SoC internal clock)[edit source]
For ecosystem release ≤ v3.0.0
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,eth_ref_clk_sel; /* In case of U-Boot */ or st,eth-ref-clk-sel; /* In case of Linux Kernel */ snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
For ecosystem release v3.1.0
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,eth-ref-clk-sel; /* In case of U-Boot */ or st,ext-phyclk; /* In case of Linux Kernel */ snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
For ecosystem release > v3.1.0
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,ext-phyclk; snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rmii_pins_a>; pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rmii"; max-speed = <100>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
+ update stm32mp15-pinctrl.dtsi to add ETHCK pin in ethernet0_rmii_pins_* node:
For example:
<STM32_PINMUX('G', 8, AF2)>, /* ETH_RMII_ETHCK */
+ Need also to update TFA to generate 50Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P in ed1 board:
update fdts/stm32mp15xx-edx.dtsi
st,pkcs = < CLK_CKPER_HSE CLK_FMC_ACLK CLK_QSPI_ACLK - CLK_ETH_DISABLED + CLK_ETH_PLL4P ... /* VCO = 508.0 MHz => P = 50, Q = 60, R = 60 */ pll4: st,pll@3 { compatible = "st,stm32mp1-pll"; reg = <3>; cfg = < 1 49 11 9 9 PQR(1,1,1) >; };
3.3.4. RGMII with Crystal on PHY, CLK125 from PHY (Reference clock (standard RGMII clock name) is provided by a Phy Crystal)[edit source]
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
3.3.5. RGMII with 25MHz on ETH_CLK (no PHY Crystal), CLK125 from PHY (Reference clock (standard RGMII clock name) is provided by a RCC SoC internal clock)[edit source]
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
+ update stm32mp15-pinctrl.dtsi to add ETHCK pin in ethernet0_rgmii_pins_* node:
For example:
<STM32_PINMUX('G', 8, AF2)>, /* ETH_RGMII_ETHCK */
+ Need also to update TFA to generate 25Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P in ed1 board:
update fdts/stm32mp15xx-edx.dtsi
st,pkcs = < CLK_CKPER_HSE CLK_FMC_ACLK CLK_QSPI_ACLK - CLK_ETH_DISABLED + CLK_ETH_PLL4P ... /* VCO = 600.0 MHz => P = 25, Q = 50, R = 50 */ pll4: st,pll@3 { compatible = "st,stm32mp1-pll"; reg = <3>; cfg = < 1 49 23 11 11 PQR(1,1,1) >; };
3.3.6. RGMII with Crystal on PHY, no 125Mhz from PHY[edit source]
For ecosystem release ≤ v3.0.0
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,eth_clk_sel; /* In case of U-Boot */ or st,eth-clk-sel; /* In case of Linux Kernel */ snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
For ecosystem release v3.1.0
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,eth-clk-sel; /* In case of U-Boot */ or st,ext-phyclk; /* In case of Linux Kernel */ snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
For ecosystem release > v3.1.0
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,ext-phyclk; snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
+ update stm32mp15-pinctrl.dtsi to delete CLK125 pin (also no need of ETHCK pin) in ethernet0_rgmii_pins_* node:
+ Need also to update TFA to generate 125Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P in ed1 board:
update fdts/stm32mp15xx-edx.dtsi
st,pkcs = < CLK_CKPER_HSE CLK_FMC_ACLK CLK_QSPI_ACLK - CLK_ETH_DISABLED + CLK_ETH_PLL4P ... /* VCO = 750.0 MHz => P = 125, Q = 62.5, R = 62.5 */ pll4: st,pll@3 { compatible = "st,stm32mp1-pll"; reg = <3>; cfg = < 3 124 5 11 11 PQR(1,1,1) >; };
4. How to configure a PHY reset signal[edit source]
Some Ethernet PHY have possibility to drive PHY reset using GPIO
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { compatible = "ethernet-phy-id0007.c131"; reset-gpios = <&gpioa 4 GPIO_ACTIVE_LOW | GPIO_PULL_UP> reset-assert-us = <1000>; reset-deassert-us = <2000>; reg = <0>; }; }; };
For kernel update see "reset-gpios" in Documentation/devicetree/bindings/net/ethernet-phy.yaml[5]
You need to find and replace value 0007.c131 corresponding to your Ethernet PHY: this can be found in datasheet of the Ethernet PHY, and find PHY Identifier 1 and PHY Identifier 2 registers.
For U-Boot same syntax of kernel, except that "reset-assert-us" and "reset-deassert-us" properties which are not managed (values of this properties are hardcoded in driver (udelay(2)), so you can change these value in function eqos_start_resets_stm32 of file dwc_eth_qos.c[6]
5. How to configure Ethernet using CubeMX[edit source]
The STM32CubeMX tool can be used to configure the STM32MPU device and get the corresponding platform configuration device tree files.
The STM32CubeMX may not support all the properties described in the above DT bindings documentation paragraph. If so, the tool inserts user sections in the generated device tree. These sections can then be edited to add some properties and they are preserved from one generation to another. Refer to STM32CubeMX user manual for further information.
6. References[edit source]
- ↑ Documentation/devicetree/bindings/net/snps%2Cdwmac.yaml
- ↑ Documentation/devicetree/bindings/net/stm32-dwmac.yaml
- ↑ arch/arm/boot/dts/stm32mp151.dtsi , STM32MP151 device tree file
- ↑ arch/arm/boot/dts/stm32mp15-pinctrl.dtsi , STM32MP15 pinctrl device tree file
- ↑ https://www.kernel.org/doc/Documentation/devicetree/bindings/net/ethernet-phy.yaml, More information
- ↑ https://github.com/u-boot/u-boot/blob/master/drivers/net/dwc_eth_qos.c, More information