What is need to make EQoS work RMII mode with internal 50MHz reference clock?
Board init function in u-boot:
static int setup_eqos_rmii(void) { struct blk_ctrl_wakeupmix_regs *bctrl = (struct blk_ctrl_wakeupmix_regs *)BLK_CTRL_WAKEUPMIX_BASE_ADDR; clrsetbits_le32(&bctrl->eqos_gpr, BCTRL_GPR_ENET_QOS_INTF_MODE_MASK, BCTRL_GPR_ENET_QOS_INTF_SEL_RMII | BCTRL_GPR_ENET_QOS_CLK_GEN_EN); return set_clk_eqos(ENET_50MHZ); }
Relevant Linux dts parts, imx93-14x14-evk-tja1103.dts used as a basis for this config.
&eqos { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_eqos_rmii>; phy-mode = "rmii"; phy-handle = <&eqosphy>; phy-reset-gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; phy-reset-duration = <10>; assigned-clocks = <&clk IMX93_CLK_ENET_TIMER2>, <&clk IMX93_CLK_ENET>; assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>, <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>; assigned-clock-rates = <100000000>, <50000000>; clk_csr = <5>; status = "okay"; mdio { compatible = "snps,dwmac-mdio"; #address-cells = <1>; #size-cells = <0>; clock-frequency = <2500000>; eqosphy: ethernet-phy@0 { reg = <0>; compatible = "ethernet-phy-id0007.c0f0", "ethernet-phy-ieee802.3-c22"; smsc,disable-energy-detect; }; }; };
...
&iomuxc { pinctrl_eqos_rmii: eqosrmiigrp { fsl,pins = < MX93_PAD_ENET1_TD2__CCM_ENET_QOS_CLOCK_GENERATE_REF_CLK 0x4000057e MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x57e MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x57e MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x57e MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x57e MX93_PAD_ENET2_TD2__GPIO4_IO17 0x31e >; }; ...
With the above configuration ethernet init fails with imx-dwmac 428a0000.ethernet: Failed to reset the dma
Any hints on what am I missing?
Solved! Go to Solution.
Hi,
Thank you for your interest in NXP Semiconductor products,
Please make these changes in your DTS.
assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>,
<&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>;
assigned-clock-rates = <100000000>, <100000000>;
Patch your BSP with the patch below and the net: stmmac: dwmac-imx: use platform specific reset for imx93 SoCs:
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index 2fb3fbbab7e5..7e001126243f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -40,6 +40,8 @@
#define MX93_GPR_ENET_QOS_INTF_SEL_RGMII (0x1 << 1)
#define MX93_GPR_ENET_QOS_CLK_GEN_EN (0x1 << 0)
+#define MX93_ENET_CLK_ENET_QOS_TX_CLK_SEL_MASK GENMASK(0, 0)
+#define MX93_ENET_CLK_ENET_QOS_TX_CLK_SEL (0x1 << 0)
struct imx_dwmac_ops {
u32 addr_width;
bool mac_rgmii_txclk_auto_adj;
@@ -54,7 +56,8 @@ struct imx_priv_data {
struct regmap *intf_regmap;
u32 intf_reg_off;
bool rmii_refclk_ext;
-
+ struct regmap *enet_clk_sel_regmap;
+ u32 enet_clk_sel_off; const struct imx_dwmac_ops *ops;
struct plat_stmmacenet_data *plat_dat;
};
@@ -133,7 +136,27 @@ imx8dxl_set_intf_mode(struct plat_stmmacenet_data *plat_dat)
static int imx93_set_intf_mode(struct plat_stmmacenet_data *plat_dat)
{
struct imx_priv_data *dwmac = plat_dat->bsp_priv;
- int val;
+ int val, err;
+
+ struct device_node *np = dwmac->dev->of_node;
+ if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) {
+ dwmac->enet_clk_sel_regmap = syscon_regmap_lookup_by_phandle(np,
+
"enet_clk_sel");
+ if (IS_ERR(dwmac->enet_clk_sel_regmap))
+ return PTR_ERR(dwmac->enet_clk_sel_regmap);
+
+ err = of_property_read_u32_index(np, "enet_clk_sel", 1,
+ &dwmac->enet_clk_sel_off);
+ if (err) {
+ dev_err(dwmac->dev,
+ "Can't get enet_clk_sel register offset
(%d)\n",
+ err);
+ return err;
+ }
+ val = MX93_ENET_CLK_ENET_QOS_TX_CLK_SEL;
+ regmap_update_bits(dwmac->enet_clk_sel_regmap, dwmac-
>enet_clk_sel_off,
+ MX93_ENET_CLK_ENET_QOS_TX_CLK_SEL_MASK,
val);
+ }
diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/
freescale/imx93.dtsi
index 1f25503d421c..a4f8f841e2a7 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -1079,6 +1079,8 @@
<&clk
IMX93_CLK_SYS_PLL_PFD0_DIV2>;
assigned-clock-rates = <100000000>, <250000000>;
intf_mode = <&wakeupmix_gpr 0x28>;
+ enet_clk_sel = <&wakeupmix_gpr 0x2C>;
+
clk_csr = <0>;
status = "disabled";
};
Regards
Small update. The DTS file must be modified like this to produce a 50MHz clock.
assigned-clock-rates = <100000000>, <50000000>;
Hi,
Thank you for your interest in NXP Semiconductor products,
Please make these changes in your DTS.
assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>,
<&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>;
assigned-clock-rates = <100000000>, <100000000>;
Patch your BSP with the patch below and the net: stmmac: dwmac-imx: use platform specific reset for imx93 SoCs:
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index 2fb3fbbab7e5..7e001126243f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -40,6 +40,8 @@
#define MX93_GPR_ENET_QOS_INTF_SEL_RGMII (0x1 << 1)
#define MX93_GPR_ENET_QOS_CLK_GEN_EN (0x1 << 0)
+#define MX93_ENET_CLK_ENET_QOS_TX_CLK_SEL_MASK GENMASK(0, 0)
+#define MX93_ENET_CLK_ENET_QOS_TX_CLK_SEL (0x1 << 0)
struct imx_dwmac_ops {
u32 addr_width;
bool mac_rgmii_txclk_auto_adj;
@@ -54,7 +56,8 @@ struct imx_priv_data {
struct regmap *intf_regmap;
u32 intf_reg_off;
bool rmii_refclk_ext;
-
+ struct regmap *enet_clk_sel_regmap;
+ u32 enet_clk_sel_off; const struct imx_dwmac_ops *ops;
struct plat_stmmacenet_data *plat_dat;
};
@@ -133,7 +136,27 @@ imx8dxl_set_intf_mode(struct plat_stmmacenet_data *plat_dat)
static int imx93_set_intf_mode(struct plat_stmmacenet_data *plat_dat)
{
struct imx_priv_data *dwmac = plat_dat->bsp_priv;
- int val;
+ int val, err;
+
+ struct device_node *np = dwmac->dev->of_node;
+ if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) {
+ dwmac->enet_clk_sel_regmap = syscon_regmap_lookup_by_phandle(np,
+
"enet_clk_sel");
+ if (IS_ERR(dwmac->enet_clk_sel_regmap))
+ return PTR_ERR(dwmac->enet_clk_sel_regmap);
+
+ err = of_property_read_u32_index(np, "enet_clk_sel", 1,
+ &dwmac->enet_clk_sel_off);
+ if (err) {
+ dev_err(dwmac->dev,
+ "Can't get enet_clk_sel register offset
(%d)\n",
+ err);
+ return err;
+ }
+ val = MX93_ENET_CLK_ENET_QOS_TX_CLK_SEL;
+ regmap_update_bits(dwmac->enet_clk_sel_regmap, dwmac-
>enet_clk_sel_off,
+ MX93_ENET_CLK_ENET_QOS_TX_CLK_SEL_MASK,
val);
+ }
diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/
freescale/imx93.dtsi
index 1f25503d421c..a4f8f841e2a7 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -1079,6 +1079,8 @@
<&clk
IMX93_CLK_SYS_PLL_PFD0_DIV2>;
assigned-clock-rates = <100000000>, <250000000>;
intf_mode = <&wakeupmix_gpr 0x28>;
+ enet_clk_sel = <&wakeupmix_gpr 0x2C>;
+
clk_csr = <0>;
status = "disabled";
};
Regards