[U-Boot] [PATCH 1/2] mx6cuboxi: Fix the delay for the AR8035 PHY

From: Fabio Estevam fabio.estevam@nxp.com
As per the AR8035 datasheet:
"For a reliable power on reset, suggest to keep asserting the reset low long enough (10ms) to ensure the clock is stable and clock-to-reset 1ms requirement is satisfied."
So do as suggested and keep the reset low for 10ms.
Signed-off-by: Fabio Estevam fabio.estevam@nxp.com --- board/solidrun/mx6cuboxi/mx6cuboxi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index fc37f1e..20faffc 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -143,7 +143,7 @@ static void setup_iomux_enet(void) SETUP_IOMUX_PADS(enet_pads);
gpio_direction_output(ETH_PHY_RESET, 0); - mdelay(2); + mdelay(10); gpio_set_value(ETH_PHY_RESET, 1); }

From: Fabio Estevam fabio.estevam@nxp.com
Since commit 59370f3fcd1350 ("net: phy: delay only if reset handler is registered") Ethernet is no longer functional:
Booting from net ... FEC Waiting for PHY auto negotiation to complete......... TIMEOUT ! BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4
This commit does not have an issue in itself, but it revelead a problem with the Ethernet initialization.
Configure the AR8035 PHY in the same manner as done in mx6sabresd and wandboard, so that we can get a reliable Ethernet operation.
Signed-off-by: Fabio Estevam fabio.estevam@nxp.com --- board/solidrun/mx6cuboxi/mx6cuboxi.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index 20faffc..3bb7573 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -147,8 +147,33 @@ static void setup_iomux_enet(void) gpio_set_value(ETH_PHY_RESET, 1); }
+static int mx6_rgmii_rework(struct phy_device *phydev) +{ + unsigned short val; + + /* Enable AR8035 ouput a 125MHz clk from CLK_25M */ + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); + + val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); + val &= 0xffe3; + val |= 0x18; + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); + + /* introduce tx clock delay */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); + val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); + val |= 0x0100; + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); + + return 0; +} + int board_phy_config(struct phy_device *phydev) { + mx6_rgmii_rework(phydev); + if (phydev->drv->config) phydev->drv->config(phydev);

On Mon, Jan 04, 2016 at 02:36:18PM -0200, Fabio Estevam wrote:
From: Fabio Estevam fabio.estevam@nxp.com
Since commit 59370f3fcd1350 ("net: phy: delay only if reset handler is registered") Ethernet is no longer functional:
Booting from net ... FEC Waiting for PHY auto negotiation to complete......... TIMEOUT ! BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4
This commit does not have an issue in itself, but it revelead a problem with the Ethernet initialization.
Configure the AR8035 PHY in the same manner as done in mx6sabresd and wandboard, so that we can get a reliable Ethernet operation.
Signed-off-by: Fabio Estevam fabio.estevam@nxp.com
Note: CPU: Freescale i.MX6D rev1.5 996 MHz (running at 792 MHz) CPU: Extended Commercial temperature grade (-20C to 105C) at 14C Reset cause: POR Board: MX6 Hummingboard ... => setenv autoload no => dhcp FEC Waiting for PHY auto negotiation to complete......... TIMEOUT ! BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4 BOOTP broadcast 5 BOOTP broadcast 6 BOOTP broadcast 7 DHCP client bound to address 192.168.0.219 (7901 ms) => tftp ramdisk-pm.gz Using FEC device TFTP from server 192.168.0.3; our IP address is 192.168.0.219 Filename 'ramdisk-pm.gz'. Load address: 0x12000000 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ###### 1.4 MiB/s done Bytes transferred = 2022580 (1edcb4 hex) => crc32 $loadaddr $filesize CRC32 for 12000000 ... 121edcb3 ==> 775dd44d =>
CRC32 matches: $ rhash -C /tftpboot/ramdisk-pm.gz ; Generated by RHash v1.2.8 on 2016-01-04 at 12:04.37 ; Written by Aleksey (Akademgorodok) - http://rhash.sourceforge.net/ ; ; 2022580 13:41.29 2013-06-25 /tftpboot/ramdisk-pm.gz /tftpboot/ramdisk-pm.gz 775DD44D
Tested-by: Tom Rini trini@konsulko.com

On 1/4/2016 9:36 AM, Fabio Estevam wrote:
From: Fabio Estevam fabio.estevam@nxp.com
Since commit 59370f3fcd1350 ("net: phy: delay only if reset handler is registered") Ethernet is no longer functional:
Booting from net ... FEC Waiting for PHY auto negotiation to complete......... TIMEOUT ! BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4
This commit does not have an issue in itself, but it revelead a problem with the Ethernet initialization.
Configure the AR8035 PHY in the same manner as done in mx6sabresd and wandboard, so that we can get a reliable Ethernet operation.
Signed-off-by: Fabio Estevam fabio.estevam@nxp.com
board/solidrun/mx6cuboxi/mx6cuboxi.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index 20faffc..3bb7573 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -147,8 +147,33 @@ static void setup_iomux_enet(void) gpio_set_value(ETH_PHY_RESET, 1); }
+static int mx6_rgmii_rework(struct phy_device *phydev) +{
- unsigned short val;
- /* Enable AR8035 ouput a 125MHz clk from CLK_25M */
- phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
- phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
- phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
- val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
- val &= 0xffe3;
- val |= 0x18;
Except for clearing bit 2 (which is undocumented), this looks just like the default implementation, which you are still calling below.
So, it looks like this subroutine can be replaced with an appropriate delay. If bit 2 does matter, perhaps the default ar8035_config should be changed instead.
- phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
- /* introduce tx clock delay */
- phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
- val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
- val |= 0x0100;
- phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
- return 0;
+}
int board_phy_config(struct phy_device *phydev) {
- mx6_rgmii_rework(phydev);
- if (phydev->drv->config) phydev->drv->config(phydev);
As a test perhaps you can call config twice instead of mx6_rgmii_rework if (phydev->drv->config) { phydev->drv->config(phydev); phydev->drv->config(phydev); }

Hi Troy,
On Mon, Jan 4, 2016 at 6:40 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
Except for clearing bit 2 (which is undocumented), this looks just like the default implementation, which you are still calling below.
So, it looks like this subroutine can be replaced with an appropriate delay. If bit 2 does matter, perhaps the default ar8035_config should be changed instead.
Just realized that ar8035_config() is never called in my case, so doing:
int board_phy_config(struct phy_device *phydev) { mx6_rgmii_rework(phydev);
return 0; }
, is enough here.
Any idea as to why ar8035_config() is never called?

On 1/4/2016 2:50 PM, Fabio Estevam wrote:
Hi Troy,
On Mon, Jan 4, 2016 at 6:40 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
Except for clearing bit 2 (which is undocumented), this looks just like the default implementation, which you are still calling below.
So, it looks like this subroutine can be replaced with an appropriate delay. If bit 2 does matter, perhaps the default ar8035_config should be changed instead.
Just realized that ar8035_config() is never called in my case, so doing:
int board_phy_config(struct phy_device *phydev) { mx6_rgmii_rework(phydev);
return 0;
}
, is enough here.
Any idea as to why ar8035_config() is never called?
=> mii read 6 2 004D => mii read 6 3 D072 =>
Do you get a different value?

On Mon, Jan 4, 2016 at 8:06 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
=> mii read 6 2 004D => mii read 6 3 D072 =>
Do you get a different value?
Yes, I get all FFFF:
=> mii read 6 3 FFFF => mii read 6 2 FFFF

On Mon, Jan 4, 2016 at 8:08 PM, Fabio Estevam festevam@gmail.com wrote:
On Mon, Jan 4, 2016 at 8:06 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
=> mii read 6 2 004D => mii read 6 3 D072 =>
Do you get a different value?
Yes, I get all FFFF:
=> mii read 6 3 FFFF => mii read 6 2 FFFF
Ops, in my case the PHY address is 0.
By adjust the address I get the same values as you reported:
=> mii read 0 2 004D => mii read 0 3 D072

On 1/4/2016 3:10 PM, Fabio Estevam wrote:
On Mon, Jan 4, 2016 at 8:08 PM, Fabio Estevam festevam@gmail.com wrote:
On Mon, Jan 4, 2016 at 8:06 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
=> mii read 6 2 004D => mii read 6 3 D072 =>
Do you get a different value?
Yes, I get all FFFF:
=> mii read 6 3 FFFF => mii read 6 2 FFFF
Ops, in my case the PHY address is 0.
By adjust the address I get the same values as you reported:
=> mii read 0 2 004D => mii read 0 3 D072
Can you add
printf("%s at %d\n", phydev->drv->name, phydev->addr);

On Mon, Jan 4, 2016 at 8:45 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
Can you add
printf("%s at %d\n", phydev->drv->name, phydev->addr);
It prints:
Generic PHY at 0
Not sure why it picks the Generic PHY driver instead of the Atheros PHY one.

On 1/4/2016 3:50 PM, Fabio Estevam wrote:
On Mon, Jan 4, 2016 at 8:45 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
Can you add
printf("%s at %d\n", phydev->drv->name, phydev->addr);
It prints:
Generic PHY at 0
Not sure why it picks the Generic PHY driver instead of the Atheros PHY one.
Try adding a delay after releasing reset
mdelay(2); gpio_set_value(ETH_PHY_RESET, 1); udelay(100);
Perhaps the first time it didn't read 4dd072

On Mon, Jan 4, 2016 at 9:11 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
Try adding a delay after releasing reset
mdelay(2); gpio_set_value(ETH_PHY_RESET, 1); udelay(100);
Perhaps the first time it didn't read 4dd072
That works :-)
Here is a minimal fix:
--- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -143,8 +143,9 @@ static void setup_iomux_enet(void) SETUP_IOMUX_PADS(enet_pads);
gpio_direction_output(ETH_PHY_RESET, 0); - mdelay(2); + mdelay(10); gpio_set_value(ETH_PHY_RESET, 1); + udelay(100); }
Will send a formal patch shortly.
Thanks for your help, Troy!

On 1/4/2016 3:08 PM, Fabio Estevam wrote:
On Mon, Jan 4, 2016 at 8:06 PM, Troy Kisky troy.kisky@boundarydevices.com wrote:
=> mii read 6 2 004D => mii read 6 3 D072 =>
Do you get a different value?
Yes, I get all FFFF:
=> mii read 6 3 FFFF => mii read 6 2 FFFF .
Sorry, your phy is not at 6, you can either print it out, or try 0 to 7

On Mon, Jan 04, 2016 at 02:36:17PM -0200, Fabio Estevam wrote:
From: Fabio Estevam fabio.estevam@nxp.com
As per the AR8035 datasheet:
"For a reliable power on reset, suggest to keep asserting the reset low long enough (10ms) to ensure the clock is stable and clock-to-reset 1ms requirement is satisfied."
So do as suggested and keep the reset low for 10ms.
Signed-off-by: Fabio Estevam fabio.estevam@nxp.com
Tested-by: Tom Rini trini@konsulko.com
participants (3)
-
Fabio Estevam
-
Tom Rini
-
Troy Kisky