RMII interface on the IMX7

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

RMII interface on the IMX7

Jump to solution
5,112 Views
arnoutdiels
Contributor III

Hi,

I'm trying to get a custom board with the IMX7 processor to talk RMII to my phy. 

However, does the IMX7 fully support RMII?

Currently, I have the following device tree config:

&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
<&clks IMX7D_ENET1_TIME_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
assigned-clock-rates = <0>, <100000000>;
phy-mode = "rmii";
phy-handle = <&ethphy1>;
fsl,magic-packet;
status = "okay";

mdio {
#address-cells = <1>;
#size-cells = <0>;

ethphy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
};
};

If I change phy-mode rmii to rgmii, I see data being sent over the TXD lines. However, in RMII mode, TX_CTL is silent as wel as the TXD lines.

Thanks in advance for your feedback!

0 Kudos
1 Solution
2,577 Views
igorpadykov
NXP Employee
NXP Employee
10 Replies
2,577 Views
arnoutdiels
Contributor III

Hi,

I tested our new hardware revision (with the correct RX_CTL pin), and RMII works now!

Thanks for the help Igor, and I hope the manual/datasheet gets updated to be less confusing in the future.

Kind regards,

Arnout

0 Kudos
2,577 Views
arnoutdiels
Contributor III

Thanks, as I feared. We took the wrong pin. I hope this gets fixed in the reference manual soon.

Another note for anyone who would try to get stuck: It seems to be required in the device tree pinmux to set a pin with pinmux enet_ref_clkx, in order for it to be activated internally! (For example, I was trying to use enet_ref_clk1 for both eth0 and eth1, but eth1 simply is not active until -a- pin has the pinmux enet_ref_clk2 (regardless of whether it is connected to anything).

And yet another note: In case anybody would try to use two seperate MDIO busses (Sabre uses 1 for both phy's), you need to patch the driver to avoid it forcing this configuration.

Thanks igor for your support, and hopefully when we have a new hardware iteration ready, packets start flying happily!

2,578 Views
igorpadykov
NXP Employee
NXP Employee

pastedImage_1.jpg

Best regards
igor

2,577 Views
arnoutdiels
Contributor III

Hi,

I found it in the reference manual in Table 5-11. Clock Root Table. The clock mux has to be put to the 50Mhz.

I don't fully know how this has to be done in the device tree, but this patch did the trick:

diff --git a/arch/arm/mach-imx/clk-imx7d.c b/arch/arm/mach-imx/clk-imx7d.c
index 980a30a..d05e947 100644
--- a/arch/arm/mach-imx/clk-imx7d.c
+++ b/arch/arm/mach-imx/clk-imx7d.c
@@ -905,6 +905,9 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
imx_clk_set_rate(clks[IMX7D_ENET_AXI_ROOT_CLK], 267000000);
imx_clk_set_parent(clks[IMX7D_ENET_PHY_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_25M_CLK]);

+ imx_clk_set_parent(clks[IMX7D_ENET1_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_50M_CLK]);
+
+
/* set pcie root's parent clk source */
imx_clk_set_parent(clks[IMX7D_PCIE_CTRL_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]);
imx_clk_set_parent(clks[IMX7D_PCIE_PHY_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);

The packet transmission works now!

However, reception does not.

I fear that this might be due a wrong pin selection.

As mentionned before, Table 11-1 in the reference manual is missing RMII pin information. Like the TX_EN was not mapped anywhere clearly, the CRS_DV for RMII is also nowhere to be found.

For our reference board, we mapped this onto ENET1_CRS, but who knows, perhaps it had to be RGMII1_RX_CTL?

Igor, since you knew about the TX_EN, can you confirm which pin it has to be for the CRS_DV?

Thanks in advance for your reply!

Kind regards,

Arnout

0 Kudos
2,577 Views
arnoutdiels
Contributor III

Turns out more than just the DTS change is needed. In particular, the change done by toradex in mach-imx7d.c   is essential: 

if (!IS_ERR(gpr)) {
if (IS_ERR(enet_out_clk)) {
pr_info("%s: failed to get enet_out clock, assuming ext. clock source\n", __func__);
/* use external clock for PHY */
regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK);
regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
} else {
pr_info("%s: found enet_out clock, assuming internal clock source\n", __func__);
/* use internal clock generation and output it to PHY */
regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, IMX7D_GPR1_ENET1_CLK_DIR_MASK);
clk_put(enet_out_clk);

}
} else {
pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
}
of_node_put(np);

This, in combination with the dts change, basically succeeds in setting the enet clock to internal, and make the cpu drive the TX_EN and TXD pins, as well as produce an output on the CCM_ENET_REF_CLK1.

The only problem I'm still facing is that the output clock is 125Mhz rather than 50Mhz. The DTS example of toradex was modified to use this clock, but this does not seem to have an effect. I don't yet understand how to configure which reference clock to use. In case someone knows, feel free to share. If I find it first, I'll also complete the post.

Kind regards,

Arnout

0 Kudos
2,576 Views
igorpadykov
NXP Employee
NXP Employee

could you try to change assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;

to IMX7D_PLL_ENET_MAIN_50M_CLK

Best regards
igor

0 Kudos
2,576 Views
arnoutdiels
Contributor III

Hi Igor,

Thanks for your reply, this is very useful!

However, I still do not seem to get the TX_CTL pin to talk when I send packets, while in RGMII it does.

The changes I could see vs my DTS:

- The colibri/toradex does reconfigure the clock:

    IMX7D_PLL_ENET_MAIN_125M_CLK => IMX7D_PLL_ENET_MAIN_50M_CLK

I also tried this before, but no luck. 

- Secondly, the DTS does show how to enable or disable the ENET_CLK. However, neither in RGMII or RMII mode, I see the relevant pin outputting a clock signal.


I guess the toradex repo produces a valid working RMII, but I don't immediately see what is different from our board.
- Do we have a schematic of the colibri board for reference?
- Do you have any idea of other kernel changes (non-DTS) that toradex did to make this work?

(I am working off the linux-rel_imx_4.1.15_1.0.0_ga tag, but so does the toradex seem to be)

Thanks in advance for your reply.

(For reference, my full DTS in attachment. I did not do modifs to the linux kernel code)

0 Kudos
2,576 Views
igorpadykov
NXP Employee
NXP Employee

Hi Arnout

I think you can just buy colibri board and check.

Best regards
igor

0 Kudos
2,576 Views
arnoutdiels
Contributor III

I'm also pretty confused regarding clocking.

RMII specifies a single clock, ENET_CLK or ENET_REF_CLK or RMII_REF_CLK. These names do appear on the reference and hardware design manuals, but do not specify which pin for example this is source from or output from.

Thanks in advance for any pointers here!

0 Kudos
2,576 Views
igorpadykov
NXP Employee
NXP Employee

Hi Arnout

you are right regarding TX_EN pin, for linux settings one can look

at Colibri iMX7 linux with Micrel KSZ8041
https://github.com/Freescale/u-boot-fslc/blob/2016.07%2Bfslc/include/configs/colibri_imx7.h
http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm/boot/dts/imx7-colibri.dtsi?h=toradex_imx...

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos