RMII on i.MX6 (L3.0.35_4.1.0)

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

RMII on i.MX6 (L3.0.35_4.1.0)

Jump to solution
5,179 Views
timolange
Contributor II

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

Labels (2)
Tags (2)
0 Kudos
1 Solution
1,130 Views
timolange
Contributor II

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.

View solution in original post

0 Kudos
5 Replies
1,130 Views
timolange
Contributor II

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

0 Kudos
1,131 Views
timolange
Contributor II

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.

0 Kudos
1,130 Views
EgleTeam
Contributor V

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.

0 Kudos
1,130 Views
mikeredd
Contributor I

Where did you find the patch.  I believe I need this patch also.

0 Kudos
1,130 Views
timolange
Contributor II

I wrote a Mail to . 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.

0 Kudos