15 Replies Latest reply on Oct 2, 2014 10:53 AM by Tyler Sheffield

    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.

          1 of 1 people found this helpful
            • 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.

              1 of 1 people found this helpful
                • 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
                        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 2

                                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 2

                                      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 4

                                    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

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

                                        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.

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

                                            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

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

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