Ethernet device tree configuration

来自百问网嵌入式Linux wiki

Article purpose

本文介绍如何在将 Ethernet 分配给Linux® 操作系统时对其进行配置。 在这种情况下,它由Ethernet framework控制。

使用device tree 机制执行配置,该机制提供STM32 DWMAC驱动程序使用的以太网外围设备的硬件描述。

DT bindings documentation

“以太网”是一种多功能设备。 每个函数由一个单独的绑定文档表示:

  • “通用”以太网设备树绑定 [1]
  • 特定的STM32 ETH设备树绑定[2]

DT configuration

本硬件描述是STM32微处理器设备树文件(".dtsi"扩展名)和 板卡设备树文件(".dts"扩展名)的组合。有关设备树文件分割的说明,请参见 Device tree

DT configuration (STM32 level)

以太网外围节点位于stm32mp157c.dtsi[3] 文件,该文件具有禁用状态和一些必需的属性,例如:

  • 物理基址和设备寄存器映射的大小
  • STMMAC中断
  • stmmaceth时钟和Rx,Tx时钟

这是一组属性,这些属性对于给定的STM32MP器件可能不会改变,例如:寄存器地址,中断,时钟等。

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";
};

必需属性和可选属性在 bindings files中有详细描述。

Warning.png 该设备树部分与STM32微处理器有关。 它必须保持原样,而不能由最终用户修改。

Ethernet DT configuration (board level)

设备树板文件(.dts)包含与板设计有关的所有硬件配置。 DT节点( ethernet)应该更新为:

  • 通过设置status = okay启用以太网块。
  • 通过 pinctrl,通过 pinctrl-0 (默认管脚), pinctrl-1 (睡眠管脚) and pinctrl-names来配置正在使用的管脚。
  • 配置以太网接口使用 phy-mode = "rgmii"., (rmii, mii, gmii).
  • 配置以太网最大速度 max-speed = <1000>"..
&ethernet0 {
	status = "okay";
	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
	pinctrl-1 = <&ethernet0_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

以下示例显示了如何在板级配置和启用以太网实例:

&ethernet0 {
   status = "okay";                             /* enable ethernet0 */ 
   pinctrl-0 = <&ethernet0_rmii_pins_a>;        /* configure pinctrl modes for ethernet0 */
   pinctrl-1 = <&ethernet0_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 */
       };
   };
};

如何为以下配置以太网:

  • 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";
};
&ethernet0 {
 status = "okay";
 pinctrl-0 = <&ethernet0_rmii_pins_a>;
 pinctrl-1 = <&ethernet0_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";
};
&ethernet0 {
 status = "okay";
 pinctrl-0 = <&ethernet0_rmii_pins_a>;
 pinctrl-1 = <&ethernet0_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 */

还需要更新 TFA 以生成25Mhz 时钟(从 PLL4P 或 PLL3Q) : < br >

例如如果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";
};
&ethernet0 {
 status = "okay";
 pinctrl-0 = <&ethernet0_rmii_pins_a>;
 pinctrl-1 = <&ethernet0_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:
例如:

 <STM32_PINMUX('G', 8, AF2)>, /* ETH_RMII_ETHCK */

还需要更新 TFA 以生成50Mhz 时钟(从 PLL4P 或 PLL3Q) :
例如如果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";
};
&ethernet0 {
 status = "okay";
 pinctrl-0 = <&ethernet0_rgmii_pins_a>;
 pinctrl-1 = <&ethernet0_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";
};
&ethernet0 {
 status = "okay";
 pinctrl-0 = <&ethernet0_rgmii_pins_a>;
 pinctrl-1 = <&ethernet0_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:
例如:

 <STM32_PINMUX('G', 8, AF2)>, /* ETH_RMII_ETHCK */

还需要更新TFA以生成25Mhz时钟(来自PLL4P或PLL3Q):
例如,如果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";
};
&ethernet0 {
 status = "okay";
 pinctrl-0 = <&ethernet0_rgmii_pins_a>;
 pinctrl-1 = <&ethernet0_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)

还需要更新TFA以生成125Mhz时钟(来自PLL4P或PLL3Q):
例如,如果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) >;
 };

How to configure Ethernet using CubeMX

STM32CubeMX 工具可用于配置STM32MPU设备并获取相应的 platform configuration device tree 文件。
STM32CubeMX可能不支持以上 DT bindings documentation段中描述的所有属性。 如果是这样,该工具会在生成的设备树中插入 用户部分 。 然后可以编辑这些部分以添加一些属性,并将它们一代一代地保留下来。 有关更多信息,请参见STM32CubeMX用户手册。