imx6ull doesn't reset LAN8720A after clk enable

cancel
Showing results for 
Search instead for 
Did you mean: 

imx6ull doesn't reset LAN8720A after clk enable

863 Views
janne_terho
Contributor III

We have imx6ull and lan8720A. Many board works fine but there is couple of chips where ethernet do not always start up correctly. The main reason of bug is that phy's clock need to be always on for LAN8720A , but from some reason the clock goes down at kernel start-up. It is known bug and there is lot of patches for it like:

https://lore.kernel.org/patchwork/patch/861449/

,but error still occurs sometimes with kernel imx_5.4.24_2.1.0

 

When the device starts in error mode, we can see:

  • Network connector leds blinking every 1 second
  • Kernel shows eth0 link up and link down every 1 second

 

There is only two way to get ethernet works correctly

  • Cool chip down during kernel start-up
  • Active RST-pin manually when kernel is running

 

In the fec_main.c is function phy_reset_after_clk_enable() which should fix problem, but it do not change physical pin status to phy's RST pin (from SNVS_TAMPER9). I have measured pins with oscilloscope and RST pin change status at startup and seguence, but clock will disable after it. After that driver do not reset phy via RST-pin never.

Clock and RST sequence at kernel start-up looks like

RST    111110000111111111111111111111111111111111
CLK    000011111111000000000000000000000000011111

 

There is fec_reset_phy() function in main.c which should active RST-pin. I tried to use it in fec_main.c but I can see error in kernel:

fec 20b4000.ethernet: failed to get phy-reset-gpios: -16

Is there any way to get RST-pin works from driver?

 

I have also tried to keep clock always on by comment line "fec_enet_clk_enable(ndev, false);" from end of function fec_probe() in fec_main.c, but the kernel stuck after that.

 

Clock is connected from imx6ull ENET2_TX_CLK__ENET2_REF_CLK2 to LAN8720 XTAL1/CLKIN. Is that correct way to use clock? I haven't change any iomuxc pad settings to clock.

Devicetree:

&fec2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet2
	             &pinctrl_enet2_mdio
	             &pinctrl_enet1_int_and_reset>;
	phy-mode = "rmii";
	phy-handle = <&ethphy0>;
	phy-reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
	phy-reset-duration = <5>;
	status = "okay";

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

		ethphy0: ethernet-phy@2 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>;
			smsc,disable-energy-detect;
			interrupt-parent = <&gpio5>;
			interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
			status = "okay";
		};
	};
};


&iomuxc_snvs {
	pinctrl_enet1_int_and_reset: enet1intandresetgrp {
		fsl,pins = <
			MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05	0x1b0b0	/* ENET1_nINT */
			MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09	0x79	/* ENET1_nRESET */

		>;
	};
};


&iomuxc {
	pinctrl-names = "default";

	pinctrl_enet2: enet2grp {
		fsl,pins = <
			MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN	0x1b0b0
			MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER	0x1b0b0
			MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00	0x1b0b0
			MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01	0x1b0b0
			MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN	0x1b0b0
			MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00	0x1b0b0 
			MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01	0x1b0b0 	
			MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2	0x4001b031	
		>;
	};

	pinctrl_enet2_mdio: mdioenet2grp {
		fsl,pins = <
			MX6UL_PAD_GPIO1_IO07__ENET2_MDC		0x1b0b0
			MX6UL_PAD_GPIO1_IO06__ENET2_MDIO	0x1b0b0
		>;
	};

};

 

0 Kudos
22 Replies

519 Views
janne_terho
Contributor III

Now I found some kind of solution.

 

I changed to kernel version lf-5.10.y.

Reset pin is used in mdio region.

&fec2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet2>;
	phy-mode = "rmii";
	phy-handle = <&ethphy0>;
	//phy-reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
	//phy-reset-duration = <5>;
	status = "okay";

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

		ethphy0: ethernet-phy@2 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>;
			smsc,disable-energy-detect;
			interrupt-parent = <&gpio5>;
			interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
			reset-names = "phy";
			reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
			reset-assert-us = <1000>;
			reset-deassert-us = <1000>;
			status = "okay";
		};
	};
};

 

And then add the reset flag back, which has removed from this chip.

https://source.codeaurora.org/external/imx/linux-imx/commit/drivers/net/phy/smsc.c?h=lf-5.10.y&id=d6...

Now we have reset after and before clock enabled and ethernet works in all chips, but I'm not happy about the comment in the linked patch. It sounds like don't do that.

 

-Janne

729 Views
Danube
Contributor IV

Is PHY work in U-boot state ?

I had this issue before , I add PHY reset function in U-boot , and fixed this issue.

0 Kudos

721 Views
janne_terho
Contributor III

Hi Danude,

There is something wrong in u-boot also. I haven't try to get net work in u-boot. 

I try to get it work in u-boot.

 

Best regards

Janne

0 Kudos

702 Views
janne_terho
Contributor III

Hi,

Net doesn't work in uboot at all.

=> mdio list
No MDIO bus found
=> mii device
MII devices:
=>

dts is like in kernel.

 

Best regards

Janne

 

 

 

0 Kudos

680 Views
janne_terho
Contributor III

I fixed u-boot's device tree and added reset function to u-boot. Now ping 8.8.8.8 works perfect in u-boot, so I think that network is ok in u-boot.

It didn't help in kernel side. I think that reason for this is that clock is disabled at the kernel startup, but RST pin doesn't active after clock is enabled again.

 

Best regards

Janne

0 Kudos

824 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi,

The following configuration is correct:

&fec2 {
 pinctrl-names = "default";
 pinctrl-0 = <&pinctrl_enet2
 &pinctrl_enet2_mdio
 &pinctrl_enet1_int_and_reset>;
 phy-mode = "rmii";
 phy-handle = <&ethphy0>;
 phy-reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
 phy-reset-duration = <5>;
 status = "okay";

......

But firstly you should confirm if the SNVS_TAMPER9 can be configured GPIO, we can know that by read fuse value.

weidong_sun_0-1622441093532.png

you can operate fuse like below:

------------------------------------------------

To view or modify eFuse in the uboot phase, the syntax is as follows.

=> fuse read <bank> <word> [<cnt>]
//Read the value of eFuse from the shadow register

=> fuse sense <bank> <word> [<cnt>]
Reads the eFuse value directly from the fusebox.

=> fuse prog [-y] <bank> <word> <hexval>
//Write eFuse value to fusebox, this operation is irreversible, wrong operation may damage the chip

=> fuse override <bank> <word> <hexval> [<hexval>…]
//Only overwrite the value of the shadow register, this operation does not affect the physical fusebox. If the system is reset, this value will be cleared.
//This command is especially useful in testing.

So what are bank and word in the command line and how to calculate it?
In i.mx6ul and 6ull, a word is 32 bits, and 8 words form a bank. The bit number of word is from 0 to 31, and the word number of bank is from 0 to 7. So taking MAC as an example, you can calculate:
The base address of eFuse is: 21B_C000h base + 400h offset = 21B_C400h
The MAC address is: 21B_C000h base + 620h offset = 21B_C620h
(620h-400h) / 0x10 = 22h = 34d, here is the total number of words calculated, the address of the word is in steps of 0x10 (0x400, 0x410, 0x420...), so it must be divided by 0x10.
22h / 08h = 04h = 4d, because 8 words are a bank, so divide by 8 here, and finally get bank=4.
22h% 08h = 02h = 2d, after calculating the remainder, the second word of the fourth bank is obtained.

Read shadow register example
=> fuse read 4 2
Reading bank 4:
Word 0x00000002: 00000000
//00000000 is a hexadecimal number

---------------------------------------------------------------

If TAMPER_PIN_DISABLE[1:0]=01 or 11, it means SNVS_TAMPER9 pin can be used GPIO.

 

Try it, please!

Have a nice day!

B.R,

weidong

0 Kudos

815 Views
janne_terho
Contributor III

Thanks for the answer.

I calculated

(430h-400h)/10h = 3h = 3d
3h / 08h = 0h
3h% 08h = 03h

So,

=> fuse read 0 3
Reading bank 0:

Word 0x00000003: 713100d4

Calculator shows that bits 20:21 are 1

janne_terho_0-1622448127186.png

best regards

Janne

 

0 Kudos

811 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi,

try the following device tree:

pinctrl_enet2: enet2grp {
fsl,pins = <
            MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
            MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
            MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
            MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
            MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
            MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
            MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
            MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
            MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
            MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031

            MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x79 /* LAN8720 PHY Reset */
            MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x1b0b0 /* ENET1_nINT */
       >;
};

&fec2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet2>;
        phy-mode = "rmii";
        phy-handle = <&ethphy1>;
        phy-reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
        phy-reset-duration = <5>;
        status = "okay";

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

      ethphy1: ethernet-phy@2 {
                    compatible = "ethernet-phy-ieee802.3-c22";
                    reg = <2>; /* Phy address*/
                    smsc,disable-energy-detect;
                    interrupt-parent = <&gpio5>;
                    interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
                };
          };
};

 

Have a nice day!

B.R,

weidong

0 Kudos

808 Views
janne_terho
Contributor III

Hi,

It didn't help.

Just for remaining, that we have 20 prototypes and other boards works fine. Only 2 boards starts with fault if we do not cool PHY-chip down in the kernel start-up.

Should processor atcive RST-pin after clk enabled?

0 Kudos

804 Views
weidong_sun
NXP TechSupport
NXP TechSupport

>>Should processor atcive RST-pin after clk enabled?

Yes, this order is correct.

0 Kudos

801 Views
janne_terho
Contributor III

Now it active RST-pin before disable clk, but not after enable clk.

If I use reset-gpios inside ethphy0 (not in fec2) in device tree, processor active RST-pin every time when try to reset phy. I can't use reset-gpios in the fec2 and ethphy0 at same time.

Is this new feature to reset inside ethphy0, or is it only for other chips?

 

0 Kudos

799 Views
weidong_sun
NXP TechSupport
NXP TechSupport

The reset of the PHY is done by the MAC driver, fec_main.c on the CPU side, . the reset gpio shouldn't be placed in the PHY driver.

0 Kudos

795 Views
janne_terho
Contributor III

Okay. Good to know.

Should mdio_device_reset() reset RST-pin? In this case it return from first if condition
if (!mdiodev->reset_gpio && !mdiodev->reset_ctrl)

https://github.com/codeaurora-unofficial/linux-msm/blob/fe07bfda2fb9cdef8a4d4008a409bb02f35f1bd8/dri...

this function is called from phy_reset_after_clk_enable()

0 Kudos

784 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi,

LAN8720 is supported by a device tree of i.MX6SX board.

so you can read relevent code in it.
reset-gpio is only used to reset PHY after Phy's power , clock etc get ready, and the reset operation is controlled by MAC driver on cpu side. in other words, it is only Low to High operation of a GPIO, which is not related to mdio (used to manage phy).

 

Have a nice day!

B.R

weidong

Tags (1)
0 Kudos

780 Views
janne_terho
Contributor III

Hi,

It's not enough to reset LAN8720 after it get power. It need to reset every time after clock has been disabled.

I found patch which uses gpio-reset in PHY in later kernel version:

https://source.codeaurora.org/external/imx/linux-imx/commit/?h=git.kernel.org/linux-stable/linux-5.9...

I know that mdio should be to the communication with PHY registers, but if I use reset-gpio inside PHY like link above, it looks like mdio_device_reset() resets phy after every clock enabled via gpio-reset.

If it's not right place. Please show me where is correct function to reset phy after clock enabled.

 

Best regards

Janne Terho

0 Kudos

770 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi,

I am considering whether we are in the wrong direction, we return to this phenomenon:

>> we have 20 prototypes and other boards works fine. Only 2 boards starts with fault if we do not cool PHY-chip down in the kernel start-up.

18 boards work well, only 2 boards have ethernet errors. This shows that there are no issues with hardware and software.

Therefore, do issues come from production and manufacturing?

Can you consider looking for issues in this direction?

 

Have a nice day!

B.R,

weidong

 

0 Kudos

766 Views
janne_terho
Contributor III

Hi,

 

We started to find solution from producting and manufacturing first. We have changed lot of components and tried to find solutions in many many ways. After all tests and informations it looks like it is known issue and it should work when code is correct.

Like in my first messages link and many other patches says

https://lore.kernel.org/patchwork/patch/861449/

In our specific case (PCB) this problem does occur at
about every 10th to 50th POR of an LAN8710 connected to an i.MX6SOLO
SoC.

 

We have noticed that it should works when reset PHY after clock enable and now I want to try it via kernel driver, but I haven't find to way to test it. If it will not work, it could be good idea to change chip.

 

Best regards,

Janne

0 Kudos

763 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi  Janne,

Maybe replacing the PHY chip is a way, but this should be the choice when there is no other way.


You mentioned earlier that you manually reset the LAN8720, and it will work normally.
If you operate reset in this way, can you make it work normally?
--multiplex SNVS_TAMPER9 as GPIO
--remove reset-gpio from fec2 node
--After the linux boot is complete, operate this GPIO on the command line to reset the PHY.
Can PHY work normally? Can you test it?

 

Have a great day!

B.R,

weidong

0 Kudos

760 Views
janne_terho
Contributor III

Hi weidong,

 

Yes. I have tested it and it works correct from command line, but I think that it's better way to do it from driver than manually.

Best regards

Janne

0 Kudos

754 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi Janne,

I checked source code just now.

Did you add lan8720a to linux-imx/arch/arm/mach-imx/mach-imx6ul.c ?

ksz8081 on evk board is handled in the file.

 

Have a nice day!

B.R,

weidong

0 Kudos