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
已解决! 转到解答。
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
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),
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.
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.
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.
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
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
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
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.
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
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
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
};
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
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)