11 Replies Latest reply: Mar 26, 2014 6:25 PM by Satoshi Shimoda RSS

RMII interface on i.MX6 Solo

Oliver Kuo Level 1

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

  • Re: RMII interface on i.MX6 Solo
    Oliver Kuo Level 1

    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.

    • Re: RMII interface on i.MX6 Solo
      Yuri Muhin 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.

      • Re: RMII interface on i.MX6 Solo
        Oliver Kuo Level 1

        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

        • Re: RMII interface on i.MX6 Solo
          Yuri Muhin Employee
          • Re: RMII interface on i.MX6 Solo
            Fugang Duan 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

            • Re: RMII interface on i.MX6 Solo
              Oliver Kuo Level 1

              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

              • Re: RMII interface on i.MX6 Solo
                Alexander Kudjashev Level 1

                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  

                };

                • Re: RMII interface on i.MX6 Solo
                  rabeeh Level 1

                  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)

                • Re: RMII interface on i.MX6 Solo
                  EgleTeam Level 1

                  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

            • Re: RMII interface on i.MX6 Solo
              Satoshi Shimoda Level 3

              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