RMII interface on i.MX6 Solo

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

RMII interface on i.MX6 Solo

Jump to solution
16,711 Views
oliverkuo
Contributor IV

Hi all,

We connect an external PHY (Micrel KSZ8031RNL) through RMII interface to imx6 Solo, when I try to ping a peer under uboot, no packet is sent even the TX buffer has been updated.

I find below workaround for similar issue on MCF5275 (MAC 10/100 Mb), is it possible happened on iMX6 Solo RMII interface? Because TDAR never be cleared.

/* FEC fix for MCF5275, FEC unable to initial transmit data packet.
* A nop will ensure the descriptor polling active completed.
*/
__asm__("nop");


My IOMUX setting:

iomux_v3_cfg_t enet_pads[] = {

  MX6DL_PAD_CSI0_DAT11__GPIO_5_29,     /* PHY reset */

  MX6DL_PAD_ENET_MDIO__ENET_MDIO,

  MX6DL_PAD_ENET_MDC__ENET_MDC,

  MX6DL_PAD_ENET_CRS_DV__ENET_RX_EN,

  MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK,

  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,

};

And change pad_ctrl to "MX6DL_ENET_PAD_CTRL".

The uboot log as below:

Using FEC0 device

TX timeout packet at 278245a0

mxc_fec.c[616] fec_send: cycles: 50000    status: 8c00  retry cnt: 0

=====

ievent       2188004 - 0

imask        2188008 - 0

r_des_active 2188010 - 1000000

x_des_active 2188014 - 1000000

ecntrl       2188024 - f0000102

mii_mframe   2188040 - 6006786d

mii_speed    2188044 - 1a

mii_ctrlstat 2188064 - c0000000

r_cntrl      2188084 - 5ee0104

x_cntrl      21880c4 - 4

padr_l       21880e4 - 10203

padr_u       21880e8 - 4058808

op_pause     21880ec - 10000

iadr_u       2188118 - 0

iadr_l       218811c - 0

gadr_u       2188120 - 0

gadr_l       2188124 - 0

x_wmrk       2188144 - 100

r_bound      218814c - 600

r_fstart     2188150 - 500

r_drng       2188180 - 27602a80

x_drng       2188184 - 27602ac0

r_bufsz      2188188 - 5f0

TX timeout packet at 278245a0

mxc_fec.c[616] fec_send: cycles: 50000    status: ac00  retry cnt: 0

=====

ievent       2188004 - 0

imask        2188008 - 0

r_des_active 2188010 - 1000000

x_des_active 2188014 - 1000000

ecntrl       2188024 - f0000102

mii_mframe   2188040 - 6006786d

mii_speed    2188044 - 1a

mii_ctrlstat 2188064 - c0000000

r_cntrl      2188084 - 5ee0104

x_cntrl      21880c4 - 4

padr_l       21880e4 - 10203

padr_u       21880e8 - 4058808

op_pause     21880ec - 10000

iadr_u       2188118 - 0

iadr_l       218811c - 0

gadr_u       2188120 - 0

gadr_l       2188124 - 0

x_wmrk       2188144 - 100

r_bound      218814c - 600

r_fstart     2188150 - 500

r_drng       2188180 - 27602a80

x_drng       2188184 - 27602ac0

r_bufsz      2188188 - 5f0


We can find MAC doesn't clean TDAR and process TX descriptor.


Thanks,

Oliver

Labels (3)
Tags (4)
0 Kudos
1 Solution
3,868 Views
DuanFugang
NXP Employee
NXP Employee

hi, Oliver,

The issue must be the clock quality and clock phase between phy and enet issue.

So, you must ensure:  

     1. GPIO_16 have no other layout lines, only connect to phy clk_in

     2. phy and enet clock must keep the in-phase, the clock source must be the same:

               - come from OSC:    enet <----GPIO_16<------OSC------>phy

               - come from internal PLL8_enet:  PLL8_enet-----> GPIO_16 ------> phy

                                                                                            |       

                                                                                            |

                                                                                         enet

You current clock design is not right, so it cannot work well.

If you have any question, pls connect me: b38611@freescale.com

Thanks,

Andy

View solution in original post

0 Kudos
15 Replies
3,868 Views
shefft
Contributor IV

2

Hi all,

Posting here with an RMII PHY problem on a custom board.  We have it working just fine in uboot, followed the HW dev guide RMII chapter no problems.  Despite matching the pad setting, the ref clk register settings, and even every single CCM register value from uboot in Linux the Eth ref clock on GPIO_16 will NOT generate with Linux.  I've done this manually after b

My question for the Freescale folks is - what am I missing to enable the ENET_REF_CLK on GPIO_16?  There must be something that worked just fine in uboot, but Linux messes it up on boot and I can't recover even with all the proper register writes I can find.

In my board file:

static struct fec_platform_data fec_data __initdata = {

    .init = mx6_fec_phy_init,

    //.phy = PHY_INTERFACE_MODE_RGMII,

     .phy = PHY_INTERFACE_MODE_RMII,

    .phy_irq = gpio_to_irq(ENET_PHY_IRQ)

};

In my pads file:

/* Ethernet - ENET */

    MX6PAD(ENET_MDIO__ENET_MDIO),

    MX6PAD(ENET_MDC__ENET_MDC),

   MX6PAD(ENET_RXD0__ENET_RDATA_0),

   MX6PAD(ENET_RXD1__ENET_RDATA_1),

   MX6PAD(ENET_CRS_DV__ENET_RX_EN),

   MX6PAD(ENET_RX_ER__ENET_RX_ER),

   MX6PAD(ENET_TXD0__ENET_TDATA_0),

   MX6PAD(ENET_TXD1__ENET_TDATA_1),

   MX6PAD(ENET_TX_EN__ENET_TX_EN),

    NEW_PAD_CTRL(MX6PAD(RGMII_RD0__GPIO_6_25), WEAK_IRQ),        /* Phy - Interrupt */

    NEW_PAD_CTRL(MX6PAD(RGMII_RD1__GPIO_6_27), WEAK),        /* Phy - Reset */

    MX6PAD(GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT),

0 Kudos
3,868 Views
shefft
Contributor IV

2Solution:  I thought I had checked the pad control IOMUXC_SW_PAD_CTL_PAD_GPIO16 a while back before my other explorations, and that it matched.  As I was double checking everything, it didn't.

0 Kudos
3,868 Views
oliverkuo
Contributor IV

I answer this question by myself.

According to the "Hardware Development Guide", RMII reference clock should be connected to GPIO_16 or RGMII_TX_CTL not ENET_REF_CLK, after hardware rework packet can be sent, but TX/RX quality is really bad.

Under investigation.

3,868 Views
Yuri
NXP Employee
NXP Employee

   According to Chapter 11 (Using the RMII Interface) of the Hardware Development

Guide for i.MX6  : "There are two possible pins that can either source or sink

the reference clock: GPIO_16 and RGMII_TX_CTL."

  I just want to remind, that  GPIO_16 is intended for RMII reference clock; ENET_REF_CLK
is intended for RGMII reference clock.

Please pay attention, ENET_REF_CLK is input clock, that is - an external source

should be applied.

3,868 Views
oliverkuo
Contributor IV

Hi Muhin,

Though transmission is workable now, but the stability is really bad, sent 100 ARP packets only 1~3 packets were captured by wireshark at peer side.

The receiver is worse, no packet received successfully, error code is 0x884 or 0x890!

Do you have any idea about which setting may affect reliability?

Currently, the reference clock is generated by KSZ8031RNL and connected to GPIO_16.

Thanks,

Oliver

0 Kudos
3,868 Views
Yuri
NXP Employee
NXP Employee
0 Kudos
3,869 Views
DuanFugang
NXP Employee
NXP Employee

hi, Oliver,

The issue must be the clock quality and clock phase between phy and enet issue.

So, you must ensure:  

     1. GPIO_16 have no other layout lines, only connect to phy clk_in

     2. phy and enet clock must keep the in-phase, the clock source must be the same:

               - come from OSC:    enet <----GPIO_16<------OSC------>phy

               - come from internal PLL8_enet:  PLL8_enet-----> GPIO_16 ------> phy

                                                                                            |       

                                                                                            |

                                                                                         enet

You current clock design is not right, so it cannot work well.

If you have any question, pls connect me: b38611@freescale.com

Thanks,

Andy

0 Kudos
3,868 Views
satoshishimoda
Senior Contributor I

Hi Andy,

I got your RMII patch(0001-ENGR00217372-01-MX6Q_ARM2-bringup-MX6q-ENET-RMII.patch) from service request, and I'm checking the code.

Then, I want to confirm my understanding about the patch.

According the code, I understand the patch provides the setting for the following connection, is this right?

- come from internal PLL8_enet:  PLL8_enet-----> RGMII_TX_CTL------> phy


In fact, I'm using the following design same as Oliver's one, and it has not worked well.

OSC 25MHz --> Ether PHY --> 50MHz REF_CLK --> GPIO_16

So I'm checking what should I modify the patch.

If my understanding is correct, I will modify the patch about GPR1[21] and SION, and clock pin from RGMII_TX_CTL to GPIO_16.


Best Regards,

Satoshi Shimoda

0 Kudos
3,868 Views
xray
Contributor III

Hi Satoshi,

Can you post your modified patch?  I'm also using GPIO_16 for my clk and I tried to modify this patch (0001-ENGR00217372-01-MX6Q_ARM2-bringup-MX6q-ENET-RMII.patch).  However, the ethernet is still not working. I'm wondering if I made a mistake in my modifications.

0 Kudos
3,868 Views
satoshishimoda
Senior Contributor I

Hi jb,

Sorry, I don't have the modified patch because our customer modified the issue by themselves practically.

For your information, I heard the root cause was PHY and MAC reset sequence in our case.

These were not suitable for the custom board.

So I recommend checking whether your PHY and MAC reset sequence is suitable for your board.

Best Regards,

Satoshi Shimoda

0 Kudos
3,868 Views
oliverkuo
Contributor IV

Hi Andy,

Thanks for your precious information.

I also think the bad transmission quality is caused by hardware rework of reference clock, KSZ8031 REF_CLK was connected to ENET_REF_CLK in our original design.

We're trying to connect GPIO_16 via KSZ8031 REF_CLK output, I think it is same as external reference clock input from GPIO_16, if I misunderstand please correct me.

OSC 25MHz --> KSZ8031 --> 50MHz REF_CLK --> GPIO_16

BTW, from another thread Yuri Muhin mentioned, you said "Kernel driver don’t support RMII, but we have patch for this.", anywhere I can download it?

And ... why RMII is disabled in kernel driver? I think it's disabled in u-boot as well. Any risk I may face if I use RMII interface?

Thanks,

Oliver

0 Kudos
3,868 Views
Sasamy
Contributor IV

Hi Oliver.

We use i.MX6 Solo and RMII with on chip clock generator, PHY lan8720 as described in "Hardware Development Guide for i.MX 6Quad, 6Dual, 6DualLite 6Solo Families of Applications Processors"

http://cache.freescale.com/files/32bit/doc/user_guide/IMX6DQ6SDLHDG.pdf

Chapter 12 Using the RMII Interface

u-boot and linux kernel rel_imx_3.0.35_4.0.0

The major changes required in u-boot:

board/freescale/mx6q_xx/mx6q_xx.c

#define ANATOP_PLL_LOCK                 0x80000000

#define ANATOP_PLL_PWDN_MASK            0x00001000

#define ANATOP_PLL_BYPASS_MASK          0x00010000

#define ANATOP_FEC_PLL_ENABLE_MASK      0x00002000

static int setup_fec(void)

{

        u32 reg = 0;

        s32 timeout = 100000;

        /*

         * get enet tx reference clk from internal clock from anatop

         * GPR1[21] = 1

         */

        reg =  readl(IOMUXC_BASE_ADDR + 0x4);

        reg |= (0x1 << 21);

        writel(reg, IOMUXC_BASE_ADDR + 0x4);

        /* 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;

                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);

        return 0;

}

....

int board_init(void)

{

...

        setup_uart();

++        setup_fec();

...

iomux_v3_cfg_t enet_pads[] = {

        MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,

        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_TX_EN__ENET_TX_EN,

        MX6DL_PAD_ENET_RXD0__ENET_RDATA_0,

        MX6DL_PAD_ENET_RXD1__ENET_RDATA_1,

        MX6DL_PAD_ENET_TXD0__ENET_TDATA_0,

        MX6DL_PAD_ENET_TXD1__ENET_TDATA_1,

        MX6DL_PAD_ENET_REF_CLK__GPIO_1_23, /* phy reset: gpio1-23 */

};

...

drivers/net/mxc_fec.c

int fec_init(struct eth_device *dev, bd_t *bd)

{

...

#if defined(CONFIG_MX6Q) || defined(CONFIG_MX6DL)

--        fecp->rcr &= ~(0x100);

--        fecp->rcr |= 0x44;

++        fecp->rcr &= ~(0x40);

++        fecp->rcr |= 0x104;

#endif

....

not sure this is required:

include/asm-arm/arch-mx6/mx6dl_pins.h

#define MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT                        \

--                IOMUX_PAD(0x05E4, 0x0214, 0x2, 0x080C, 0, NO_PAD_CTRL)

++                IOMUX_PAD(0x05E4, 0x0214, 0x12, 0x080C, 0, NO_PAD_CTRL)

Linux:

arch/arm/mach-mx6/board-mx6q_xx.c

static struct fec_platform_data fec_data __initdata = {

    .init = mx6q_xx_fec_phy_init,

--    .phy = PHY_INTERFACE_MODE_RGMII,

++    .phy = PHY_INTERFACE_MODE_RMII,

#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO

    .gpio_irq = MX6_ENET_IRQ,

#endif  

};

0 Kudos
3,868 Views
EgleTeam
Contributor V

Alexander,

We've used your patch and it works fine also for: MX6DL (ENET rail at 2.5V) +  RGMII_TX_CTL pin + LAN8710 (IO at 2.5V), on u-boot.

However we can't make ethernet work on Linux (3.0.35). I can see  "FEC MII Bus: probed"  in the log but no device (i.e.: "eth0") is registered. I can see, using a probe, how the 50Mhz clock disappears/appears/disappears forever while the kernel is booting. Any advice?

Thanks,

Manuel

0 Kudos
3,868 Views
EgleTeam
Contributor V

Hi,

udev wasn't compiled. Besides we had some "overrides" in the ENET PADS configuration. Now the kernel is working :-)

Best regards,

Manuel.

0 Kudos
3,868 Views
rabeeh
Contributor II

The following is also required (enable the SION bit).

Without it the fec mac would timeout on u-boot.

#define MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT                        \

--                IOMUX_PAD(0x05E4, 0x0214, 0x2, 0x080C, 0, NO_PAD_CTRL)

++                IOMUX_PAD(0x05E4, 0x0214, 0x12, 0x080C, 0, NO_PAD_CTRL)

0 Kudos