Hi,
I've connected a lan8720 (RMII) with imx6dl. We use the GPIO 16 as clock output for the phy. In our u-boot this works fine. (Thanks to Sasamy for his post Re: RMII interface on i.MX6 Solo)
But if I start the kernel the clock stops and the phy don't work.
Here is my iomux config:
MX6DL_PAD_ENET_MDIO__ENET_MDIO, |
MX6DL_PAD_ENET_MDC__ENET_MDC,
MX6DL_PAD_ENET_CRS_DV__ENET_RX_EN,
MX6DL_PAD_ENET_RX_ER__ENET_RX_ER,
MX6DL_PAD_ENET_RXD0__ENET_RDATA_0,
MX6DL_PAD_ENET_RXD1__ENET_RDATA_1,
MX6DL_PAD_ENET_TX_EN__ENET_TX_EN,
MX6DL_PAD_ENET_TXD0__ENET_TDATA_0,
MX6DL_PAD_ENET_TXD1__ENET_TDATA_1,
/* TODO Clock Generierung überprüfen */
MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
MX6DL_PAD_DISP0_DAT5__GPIO_4_26, /* PHY Interrupt */
MX6DL_PAD_DISP0_DAT9__GPIO_4_30, /* PHY Reset */
My fec init procedure:
static int spa100_fec_phy_init(struct phy_device *phydev)
{
int val;
u32 reg = 0;
s32 timeout = 100000;
/* Enable PLLs */
reg = readl(ANATOP_BASE_ADDR + 0xe0); /* ENET PLL */
if ((reg & ANATOP_PLL_PWDN_MASK) || (!(reg & ANATOP_PLL_LOCK))) {
reg &= ~ANATOP_PLL_PWDN_MASK; /* Power On */
writel(reg, ANATOP_BASE_ADDR + 0xe0);
while (timeout--) {
if (readl(ANATOP_BASE_ADDR + 0xe0) & ANATOP_PLL_LOCK)
break;
}
if (timeout <= 0)
return -1;
}
/* Enable FEC clock */
reg |= ANATOP_FEC_PLL_ENABLE_MASK;
reg &= ~ANATOP_PLL_BYPASS_MASK;
writel(reg, ANATOP_BASE_ADDR + 0xe0);
/* reset the phy */
gpio_request(SPA100_PHY_RESET_GP, "fec-rst");
gpio_direction_output(SPA100_PHY_RESET_GP, 0);
/* wait 25ms */
msleep(25);
gpio_direction_output(SPA100_PHY_RESET_GP, 1);
msleep(1);
/* check phy power */
val = phy_read(phydev, 0x0);
if (val & BMCR_PDOWN)
phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
return 0;
}
The "enable fec clock" do not help. If I read the register 0x020c80e0 in linux it has the value 0x80010001 instead of 0x80002001. Where/when should I set this register?
On the system start I get an error:
FEC Ethernet Driver
FEC: MDIO read timeout, mii_id=0
------------[ cut here ]------------
WARNING: at kernel/irq/manage.c:1182 __free_irq+0xa0/0x1a4()
Trying to free already-free IRQ 150
Modules linked in:
[<80040518>] (unwind_backtrace+0x0/0xf8) from [<80067adc>] (warn_slowpath_common+0x4c/0x64)
[<80067adc>] (warn_slowpath_common+0x4c/0x64) from [<80067b88>] (warn_slowpath_fmt+0x30/0x40)
[<80067b88>] (warn_slowpath_fmt+0x30/0x40) from [<8009b4a4>] (__free_irq+0xa0/0x1a4)
[<8009b4a4>] (__free_irq+0xa0/0x1a4) from [<8009b5dc>] (free_irq+0x34/0x5c)
[<8009b5dc>] (free_irq+0x34/0x5c) from [<804c2924>] (fec_probe+0x580/0x6b0)
[<804c2924>] (fec_probe+0x580/0x6b0) from [<80278b80>] (platform_drv_probe+0x18/0x1c)
[<80278b80>] (platform_drv_probe+0x18/0x1c) from [<80277950>] (driver_probe_device+0x90/0x19c)
[<80277950>] (driver_probe_device+0x90/0x19c) from [<80277ae8>] (__driver_attach+0x8c/0x90)
[<80277ae8>] (__driver_attach+0x8c/0x90) from [<80276b70>] (bus_for_each_dev+0x5c/0x88)
[<80276b70>] (bus_for_each_dev+0x5c/0x88) from [<80277324>] (bus_add_driver+0x17c/0x244)
[<80277324>] (bus_add_driver+0x17c/0x244) from [<80277fc8>] (driver_register+0x78/0x13c)
[<80277fc8>] (driver_register+0x78/0x13c) from [<8003535c>] (do_one_initcall+0x34/0x174)
[<8003535c>] (do_one_initcall+0x34/0x174) from [<80008960>] (kernel_init+0x84/0x124)
[<80008960>] (kernel_init+0x84/0x124) from [<8003b670>] (kernel_thread_exit+0x0/0x8)
---[ end trace d05266767f246075 ]---
Regards,
Timo
Solved! Go to Solution.
I applied a patch from freescale and I had to edit fec_enet_start_xmit in fec.c to avoid a kernel panic while sending a packet.
Hi,
I solved my problem: I had to change the .gpio_irq definition in the fec_platform_data from my gpio pin to -1. Now the kernel starts without mii timeout. But now I habe an other problem:
If I want to bring up the eth0 device then my system hangs without an error message.
freescale login: root
root@freescale ~$ ifconfig -a
eth0 Link encap:Ethernet HWaddr 1E:ED:19:27:1A:B3
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
LOOPBACK MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
tunl0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-48-00-00-00-00-00-00-00-00-00
NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@freescale ~$ ifconfig eth0 up
FEC: Open Ethernet
I found where it hangs, but I don't know why. It hangs on clk_enable:
driver/net/fec.c:
...
static int
fec_enet_open(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
int ret;
printk("FEC: Open Ethernet\n");
if (fep->use_napi)
napi_enable(&fep->napi);
printk("FEC: Open Ethernet 1\n");
/* I should reset the ring buffers here, but I don't yet know
* a simple way to do that.
*/
clk_enable(fep->clk);
...
Do I have to init the clock first? If yes, how can I do that?
Regards,
Timo
I applied a patch from freescale and I had to edit fec_enet_start_xmit in fec.c to avoid a kernel panic while sending a packet.
Just in case....if you don't use an external oscillator.... you must to redefine "MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT" in order to activate SION bit. Otherwise 50Mhz refclock comes to PHY and you can "talk" with it via MDIO but the clock doesn't come to the ENET side of the iMX6: what means that there's no reference clock for TX and RX.
Double check when you redefine if you'r code is also for Quad/Dual since the GPR iomux is in another address.
Best regards,
Manuel.
Where did you find the patch. I believe I need this patch also.
I wrote a Mail to DuanFugang. I found the e-mail address in this post: Re: iMX6 RGMII + ENET_REF_CLK/ENET_TX_CLK
I received the anwser with the patch immediately.