Ethernet device tree configuration
目录
Article purpose
本文介绍如何在将 Ethernet 分配给Linux® 操作系统时对其进行配置。 在这种情况下,它由Ethernet framework控制。
使用device tree 机制执行配置,该机制提供STM32 DWMAC驱动程序使用的以太网外围设备的硬件描述。
DT bindings documentation
The Ethernet is a multifunction device.
Each function is represented by a separate binding document:
DT configuration
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.
DT configuration (STM32 level)
Ethernet peripheral nodes are located in stm32mp157c.dtsi [3] file with a disabled status and some required properties such as:
- Physical base address and size of the device register map
- STMMAC 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_NONE>; interrupt-names = "macirq"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "ethstp", "syscfg-clk"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHSTP>, <&rcc SYSCFG>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; 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.
This device tree part is related to STM32 microprocessors. It must be kept as is, without being modified by the end-user. |
Ethernet DT configuration (board level)
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>; }; }; };
DT configuration examples
The example below shows how to configure and enable an Ethernet instance at board level:
ð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 :
- RMII with Crystal on PHY:
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>, <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "eth_wake_irq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&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"; };
ð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>; }; }; };
- RMII with 25MHz on ETH_CLK (no PHY Crystal), REF_CLK from PHY:
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>, <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "eth_wake_irq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "eth-ck", "mac-clk-tx", "mac-clk-rx", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHCK_K>, <&rcc ETHTX>, <&rcc ETHRX>, <&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"; };
ð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 Pinctrl to add ETHCK pin:
For example:
<STM32_PINMUX('G', 8, AF2)>, /* ETH_RMII_ETHCK */
Need also to update TFA to generate 25Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P:
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 { cfg = < 1 49 23 11 11 PQR(1,1,1) >; };
- RMII with 50MHz on ETH_CLK (no PHY Crystal), internal REF_CLK from RCC:
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>, <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "eth_wake_irq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "eth-ck", "mac-clk-tx", "mac-clk-rx", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHCK_K>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,eth_ref_clk_sel; 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 Pinctrl to add ETHCK pin:
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:
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 { cfg = < 1 49 11 9 9 PQR(1,1,1) >; };
4- RGMII with Crystal on PHY, CLK125 from PHY:
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>, <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "eth_wake_irq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&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"; };
ð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>; }; }; };
5- RGMII with 25MHz on ETH_CLK (no PHY Crystal), CLK125 from PHY:
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>, <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "eth_wake_irq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "eth-ck", "mac-clk-tx", "mac-clk-rx", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHCK_K>, <&rcc ETHTX>, <&rcc ETHRX>, <&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"; };
ð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 Pinctrl to add ETHCK pin:
For example:
<STM32_PINMUX('G', 8, AF2)>, /* ETH_RMII_ETHCK */
Need also to update TFA to generate 25Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P:
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 { cfg = < 1 49 23 11 11 PQR(1,1,1) >; };
6- RGMII with Crystal on PHY, no 125Mhz from PHY:
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>, <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "eth_wake_irq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "eth-ck", "mac-clk-tx", "mac-clk-rx", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHCK_K>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,eth_clk_sel; 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 Pinctrl to delete CLK125 pin (also no need of ETHCK pin)
Need also to update TFA to generate 125Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P:
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 { cfg = < 3 124 5 11 11 PQR(1,1,1) >; };
<securetransclude src="ProtectedTemplate:ReviewsComments" params="-- ECO 26 March2020 : Many customers loose time to set-up the device tree configuration. We miss here PHY clock info (BZ 83364) and PHY reset pin info (BZ 82747)"></securetransclude>{{#set:Has reviews comments=true}}
How to configure Ethernet using CubeMX
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.
References
- ↑ Documentation/devicetree/bindings/net/stmmac.txt| |}} Documentation/devicetree/bindings/net/stmmac.txt
- ↑ Documentation/devicetree/bindings/net/stm32-dwmac.txt| |}} Documentation/devicetree/bindings/net/stm32-dwmac.txt
- ↑ arch/arm/boot/dts/stm32mp157c.dtsi | |}} arch/arm/boot/dts/stm32mp157c.dtsi , STM32MP157C device tree file