AnsweredAssumed Answered

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

Question asked by Timo Lange on Oct 8, 2013
Latest reply on Dec 11, 2013 by Timo Lange

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 Alexander Kudjashev 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

Outcomes