[U-Boot] [PATCH 0/2] net: lpc32xx: add support to RMII phy

This is an update to LPC32xx MAC driver, which needs to have small quirks in order to properly work with an external phy connected by RMII interface.
RMII mode of MAC operation is selected, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already have the same config value.
Also hopefully the first change from the series speeds up auto negotiation due to corrected configuration of MAC on intialization.
Tested with SMSC LAN8700 phy.
Vladimir Zapolskiy (2): net: lpc32xx: improve MAC configuration on reset and initialization net: lpc32xx: add RMII phy mode support
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 7 ++++- drivers/net/lpc32xx_eth.c | 51 +++++++++++++++++++------------- 2 files changed, 37 insertions(+), 21 deletions(-)

This change rearranges general MAC configuration and PHY specific configuration of MAC registers (duplex mode and speed), before this change set bits related to PHY configuration in MAC2 and COMMAND registers are rewritten by the following writing to the registers.
Without the change auto negotiation on boot quite often is not completed in reasonable time:
Waiting for PHY auto negotiation to complete......... TIMEOUT !
Additionally MAC1_SOFT_RESET clear bit is removed since it is done in preceding lpc32xx_eth_initialize() and in lpc32xx_eth_halt(), instead added missing MCFG_RESET_MII_MGMT on device initialization.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com --- drivers/net/lpc32xx_eth.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index 6033392..f883a25 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -151,7 +151,7 @@ struct lpc32xx_eth_registers { #define SUPP_SPEED 0x00000100
/* MCFG register bitfields/masks and offsets (see Table 292) */ -#define MCFG_CLOCK_SELECT_MASK 0x0000001C +#define MCFG_RESET_MII_MGMT 0x00008000 /* divide clock by 28 (see Table 293) */ #define MCFG_CLOCK_SELECT_DIV28 0x0000001C
@@ -459,8 +459,19 @@ static int lpc32xx_eth_init(struct eth_device *dev) struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; int index;
- /* Release SOFT reset to let MII talk to PHY */ - clrbits_le32(®s->mac1, MAC1_SOFT_RESET); + /* Initial MAC initialization */ + writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); + writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); + writel(PKTSIZE_ALIGN, ®s->maxf); + + /* Retries: 15 (0xF). Collision window: 57 (0x37). */ + writel(0x370F, ®s->clrt); + + /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ + writel(0x0012, ®s->ipgr); + + /* pass runt (smaller than 64 bytes) frames */ + writel(COMMAND_PASSRUNTFRAME, ®s->command);
/* Configure Full/Half Duplex mode */ if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { @@ -477,20 +488,6 @@ static int lpc32xx_eth_init(struct eth_device *dev) else writel(0, ®s->supp);
- /* Initial MAC initialization */ - writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); - writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); - writel(PKTSIZE_ALIGN, ®s->maxf); - - /* Retries: 15 (0xF). Collision window: 57 (0x37). */ - writel(0x370F, ®s->clrt); - - /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ - writel(0x0012, ®s->ipgr); - - /* pass runt (smaller than 64 bytes) frames */ - writel(COMMAND_PASSRUNTFRAME, ®s->command); - /* Save station address */ writel((unsigned long) (dev->enetaddr[0] | (dev->enetaddr[1] << 8)), ®s->sa2); @@ -604,7 +601,7 @@ int lpc32xx_eth_initialize(bd_t *bis) * Set RMII management clock rate. With HCLK at 104 MHz and * a divider of 28, this will be 3.72 MHz. */ - + writel(MCFG_RESET_MII_MGMT, ®s->mcfg); writel(MCFG_CLOCK_SELECT_DIV28, ®s->mcfg);
/* Reset all MAC logic */

Hi Vladimir,
On Sun, Jul 5, 2015 at 11:22 PM, Vladimir Zapolskiy vz@mleia.com wrote:
This change rearranges general MAC configuration and PHY specific configuration of MAC registers (duplex mode and speed), before this change set bits related to PHY configuration in MAC2 and COMMAND registers are rewritten by the following writing to the registers.
Without the change auto negotiation on boot quite often is not completed in reasonable time:
Waiting for PHY auto negotiation to complete......... TIMEOUT !
Additionally MAC1_SOFT_RESET clear bit is removed since it is done in preceding lpc32xx_eth_initialize() and in lpc32xx_eth_halt(), instead added missing MCFG_RESET_MII_MGMT on device initialization.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com
Applied to u-boot-net, thanks! -Joe

LPC32xx MAC and clock control configuration requires some minor quirks to deal with a phy connected by RMII.
It's worth to mention that the kernel and legacy BSP from NXP sets SUPP_RESET_RMII == (1 << 11) bit, however the description of this bit is missing in shared LPC32x0 User Manual UM10326 Rev. 3, July 22, 2011 and in LPC32x0 Draft User Mannual Rev. 00.27, November 20, 2008, also in my tests an SMSC LAN8700 phy device connected over RMII seems to work correctly without touching this bit.
Add support of RMII, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already define the same config value.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com --- arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 7 ++++++- drivers/net/lpc32xx_eth.c | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c index 5a453e3..9c8d655 100644 --- a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c +++ b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c @@ -45,7 +45,12 @@ void lpc32xx_mac_init(void) { /* Enable MAC interface */ writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER - | CLK_MAC_MII, &clk->macclk_ctrl); +#if defined(CONFIG_RMII) + | CLK_MAC_RMII, +#else + | CLK_MAC_MII, +#endif + &clk->macclk_ctrl); }
void lpc32xx_mlc_nand_init(void) diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index f883a25..f3ab0f4 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -168,6 +168,7 @@ struct lpc32xx_eth_registers { #define COMMAND_RXENABLE 0x00000001 #define COMMAND_TXENABLE 0x00000002 #define COMMAND_PASSRUNTFRAME 0x00000040 +#define COMMAND_RMII 0x00000200 #define COMMAND_FULL_DUPLEX 0x00000400 /* Helper: general reset */ #define COMMAND_RESETS 0x00000038 @@ -201,6 +202,7 @@ struct lpc32xx_eth_device { struct eth_device dev; struct lpc32xx_eth_registers *regs; struct lpc32xx_eth_buffers *bufs; + bool phy_rmii; };
#define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device)) @@ -359,7 +361,10 @@ int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
static struct lpc32xx_eth_device lpc32xx_eth = { .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE, - .bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS + .bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS, +#if defined(CONFIG_RMII) + .phy_rmii = true, +#endif };
#define TX_TIMEOUT 10000 @@ -471,7 +476,10 @@ static int lpc32xx_eth_init(struct eth_device *dev) writel(0x0012, ®s->ipgr);
/* pass runt (smaller than 64 bytes) frames */ - writel(COMMAND_PASSRUNTFRAME, ®s->command); + if (lpc32xx_eth_device->phy_rmii) + writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); + else + writel(COMMAND_PASSRUNTFRAME, ®s->command);
/* Configure Full/Half Duplex mode */ if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { @@ -559,6 +567,8 @@ static int lpc32xx_eth_halt(struct eth_device *dev) #if defined(CONFIG_PHYLIB) int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) { + struct lpc32xx_eth_device *lpc32xx_eth_device = + container_of(dev, struct lpc32xx_eth_device, dev); struct mii_dev *bus; struct phy_device *phydev; int ret; @@ -579,7 +589,11 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) return -ENOMEM; }
- phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); + if (lpc32xx_eth_device->phy_rmii) + phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII); + else + phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); + if (!phydev) { printf("phy_connect failed\n"); return -ENODEV;

Hi Vladimir,
I tested the patch and it is working.
However, in the legacy BSP from NXP, a 10ms delay was present after the soft reset release (to let the MII talk to the PHY) in RMII phy mode.
In my tests, the download rate was 20% to 25% slower if the 10ms delay was not present.
Sylvain Lemieux Tyco
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Vladimir Zapolskiy Sent: 6-Jul-15 12:22 AM To: Albert ARIBAUD; Joe Hershberger Cc: Tom Rini; u-boot@lists.denx.de Subject: [U-Boot] [PATCH 2/2] net: lpc32xx: add RMII phy mode support
LPC32xx MAC and clock control configuration requires some minor quirks to deal with a phy connected by RMII.
It's worth to mention that the kernel and legacy BSP from NXP sets SUPP_RESET_RMII == (1 << 11) bit, however the description of this bit is missing in shared LPC32x0 User Manual UM10326 Rev. 3, July 22, 2011 and in LPC32x0 Draft User Mannual Rev. 00.27, November 20, 2008, also in my tests an SMSC LAN8700 phy device connected over RMII seems to work correctly without touching this bit.
Add support of RMII, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already define the same config value.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com --- arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 7 ++++++- drivers/net/lpc32xx_eth.c | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c index 5a453e3..9c8d655 100644 --- a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c +++ b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c @@ -45,7 +45,12 @@ void lpc32xx_mac_init(void) { /* Enable MAC interface */ writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER - | CLK_MAC_MII, &clk->macclk_ctrl); +#if defined(CONFIG_RMII) + | CLK_MAC_RMII, +#else + | CLK_MAC_MII, +#endif + &clk->macclk_ctrl); }
void lpc32xx_mlc_nand_init(void) diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index f883a25..f3ab0f4 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -168,6 +168,7 @@ struct lpc32xx_eth_registers { #define COMMAND_RXENABLE 0x00000001 #define COMMAND_TXENABLE 0x00000002 #define COMMAND_PASSRUNTFRAME 0x00000040 +#define COMMAND_RMII 0x00000200 #define COMMAND_FULL_DUPLEX 0x00000400 /* Helper: general reset */ #define COMMAND_RESETS 0x00000038 @@ -201,6 +202,7 @@ struct lpc32xx_eth_device { struct eth_device dev; struct lpc32xx_eth_registers *regs; struct lpc32xx_eth_buffers *bufs; + bool phy_rmii; };
#define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device)) @@ -359,7 +361,10 @@ int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
static struct lpc32xx_eth_device lpc32xx_eth = { .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE, - .bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS + .bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS, #if +defined(CONFIG_RMII) + .phy_rmii = true, +#endif };
#define TX_TIMEOUT 10000 @@ -471,7 +476,10 @@ static int lpc32xx_eth_init(struct eth_device *dev) writel(0x0012, ®s->ipgr);
/* pass runt (smaller than 64 bytes) frames */ - writel(COMMAND_PASSRUNTFRAME, ®s->command); + if (lpc32xx_eth_device->phy_rmii) + writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); + else + writel(COMMAND_PASSRUNTFRAME, ®s->command);
/* Configure Full/Half Duplex mode */ if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { @@ -559,6 +567,8 @@ static int lpc32xx_eth_halt(struct eth_device *dev) #if defined(CONFIG_PHYLIB) int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) { + struct lpc32xx_eth_device *lpc32xx_eth_device = + container_of(dev, struct lpc32xx_eth_device, dev); struct mii_dev *bus; struct phy_device *phydev; int ret; @@ -579,7 +589,11 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) return -ENOMEM; }
- phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); + if (lpc32xx_eth_device->phy_rmii) + phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII); + else + phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); + if (!phydev) { printf("phy_connect failed\n"); return -ENODEV; -- 2.1.4
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
________________________________
This e-mail contains privileged and confidential information intended for the use of the addressees named above. If you are not the intended recipient of this e-mail, you are hereby notified that you must not disseminate, copy or take any action in respect of any information contained in it. If you have received this e-mail in error, please notify the sender immediately by e-mail and immediately destroy this e-mail and its attachments.

Hi Sylvain,
On 06.07.2015 21:50, LEMIEUX, SYLVAIN wrote:
Hi Vladimir,
I tested the patch and it is working.
However, in the legacy BSP from NXP, a 10ms delay was present after the soft reset release (to let the MII talk to the PHY) in RMII phy mode.
there is 10ms delay in lpc32xx_eth_initialize() and 2ms delay in lpc32xx_eth_halt(), do we need another delay in lpc32xx_eth_init()?
In fact I believe lpc32xx_eth_halt() realization may be improved, I think that soft reset is not needed there, just stopping TX/RX should be fine. But this is another patch and it needs thorough testing.
In my tests, the download rate was 20% to 25% slower if the 10ms delay was not present.
Do you compare performance of my change against my change plus added 10? Or my change against legacy BSP? Could you please send me a proposed change for testing, I'm not sure I have access to the legacy BSP from NXP.
Myself I tested a big number of adjusted/added delays and updates to lpc32xx_eth_init() and lpc32xx_eth_halt(), but my primary optimized value, as you can see from the commit message of the previous patch, is time to complete autonegotiation. Download rate can be optimized separately, may be you can send a patch on top of this series to let me test it on my side? Also which PHY do you test?
All in all thank you so much for testing and shared info!
With best wishes, Vladimir
Sylvain Lemieux Tyco
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Vladimir Zapolskiy Sent: 6-Jul-15 12:22 AM To: Albert ARIBAUD; Joe Hershberger Cc: Tom Rini; u-boot@lists.denx.de Subject: [U-Boot] [PATCH 2/2] net: lpc32xx: add RMII phy mode support
LPC32xx MAC and clock control configuration requires some minor quirks to deal with a phy connected by RMII.
It's worth to mention that the kernel and legacy BSP from NXP sets SUPP_RESET_RMII == (1 << 11) bit, however the description of this bit is missing in shared LPC32x0 User Manual UM10326 Rev. 3, July 22, 2011 and in LPC32x0 Draft User Mannual Rev. 00.27, November 20, 2008, also in my tests an SMSC LAN8700 phy device connected over RMII seems to work correctly without touching this bit.
Add support of RMII, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already define the same config value.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 7 ++++++- drivers/net/lpc32xx_eth.c | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c index 5a453e3..9c8d655 100644 --- a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c +++ b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c @@ -45,7 +45,12 @@ void lpc32xx_mac_init(void) { /* Enable MAC interface */ writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER
| CLK_MAC_MII, &clk->macclk_ctrl);
+#if defined(CONFIG_RMII)
| CLK_MAC_RMII,
+#else
| CLK_MAC_MII,
+#endif
&clk->macclk_ctrl);
}
void lpc32xx_mlc_nand_init(void) diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index f883a25..f3ab0f4 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -168,6 +168,7 @@ struct lpc32xx_eth_registers { #define COMMAND_RXENABLE 0x00000001 #define COMMAND_TXENABLE 0x00000002 #define COMMAND_PASSRUNTFRAME 0x00000040 +#define COMMAND_RMII 0x00000200 #define COMMAND_FULL_DUPLEX 0x00000400 /* Helper: general reset */ #define COMMAND_RESETS 0x00000038 @@ -201,6 +202,7 @@ struct lpc32xx_eth_device { struct eth_device dev; struct lpc32xx_eth_registers *regs; struct lpc32xx_eth_buffers *bufs;
bool phy_rmii;
};
#define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device)) @@ -359,7 +361,10 @@ int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
static struct lpc32xx_eth_device lpc32xx_eth = { .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE,
.bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS
.bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS, #if
+defined(CONFIG_RMII)
.phy_rmii = true,
+#endif };
#define TX_TIMEOUT 10000 @@ -471,7 +476,10 @@ static int lpc32xx_eth_init(struct eth_device *dev) writel(0x0012, ®s->ipgr);
/* pass runt (smaller than 64 bytes) frames */
writel(COMMAND_PASSRUNTFRAME, ®s->command);
if (lpc32xx_eth_device->phy_rmii)
writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command);
else
writel(COMMAND_PASSRUNTFRAME, ®s->command); /* Configure Full/Half Duplex mode */ if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { @@ -559,6 +567,8 @@ static int lpc32xx_eth_halt(struct eth_device *dev) #if defined(CONFIG_PHYLIB) int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) {
struct lpc32xx_eth_device *lpc32xx_eth_device =
container_of(dev, struct lpc32xx_eth_device, dev); struct mii_dev *bus; struct phy_device *phydev; int ret;
@@ -579,7 +589,11 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) return -ENOMEM; }
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII);
if (lpc32xx_eth_device->phy_rmii)
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII);
else
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII);
if (!phydev) { printf("phy_connect failed\n"); return -ENODEV;
-- 2.1.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
This e-mail contains privileged and confidential information intended for the use of the addressees named above. If you are not the intended recipient of this e-mail, you are hereby notified that you must not disseminate, copy or take any action in respect of any information contained in it. If you have received this e-mail in error, please notify the sender immediately by e-mail and immediately destroy this e-mail and its attachments.

Hi Vladimir,
I did the same port, using the legacy BSP as a reference; my port was not yet submitted to the maillist. I migrated to your patch and find the download rate was slower.
By comparing with the legacy BSP, I find a missing 10ms delay, when using RMII, that seem to impact the download rate. This extra 10ms delay is in the lpc32xx_eth_initialize() function just before the call to register the driver after the soft reset is release.
I am fully agree that the download rate can be optimize in a separate patch; I will send a patch for it.
The phy we are using is Micrel KSZ8031RNL; I will be submitting a patch to add the support for that phy in u-boot.
Sylvain Lemieux Tyco
-----Original Message----- From: Vladimir Zapolskiy [mailto:vz@mleia.com] Sent: 6-Jul-15 4:45 PM To: LEMIEUX, SYLVAIN Cc: Albert ARIBAUD; Joe Hershberger; Tom Rini; u-boot@lists.denx.de Subject: Re: [U-Boot] [PATCH 2/2] net: lpc32xx: add RMII phy mode support
Hi Sylvain,
On 06.07.2015 21:50, LEMIEUX, SYLVAIN wrote:
Hi Vladimir,
I tested the patch and it is working.
However, in the legacy BSP from NXP, a 10ms delay was present after the soft reset release (to let the MII talk to the PHY) in RMII phy mode.
there is 10ms delay in lpc32xx_eth_initialize() and 2ms delay in lpc32xx_eth_halt(), do we need another delay in lpc32xx_eth_init()?
In fact I believe lpc32xx_eth_halt() realization may be improved, I think that soft reset is not needed there, just stopping TX/RX should be fine. But this is another patch and it needs thorough testing.
In my tests, the download rate was 20% to 25% slower if the 10ms delay was not present.
Do you compare performance of my change against my change plus added 10? Or my change against legacy BSP? Could you please send me a proposed change for testing, I'm not sure I have access to the legacy BSP from NXP.
Myself I tested a big number of adjusted/added delays and updates to lpc32xx_eth_init() and lpc32xx_eth_halt(), but my primary optimized value, as you can see from the commit message of the previous patch, is time to complete autonegotiation. Download rate can be optimized separately, may be you can send a patch on top of this series to let me test it on my side? Also which PHY do you test?
All in all thank you so much for testing and shared info!
With best wishes, Vladimir
Sylvain Lemieux Tyco
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Vladimir Zapolskiy Sent: 6-Jul-15 12:22 AM To: Albert ARIBAUD; Joe Hershberger Cc: Tom Rini; u-boot@lists.denx.de Subject: [U-Boot] [PATCH 2/2] net: lpc32xx: add RMII phy mode support
LPC32xx MAC and clock control configuration requires some minor quirks to deal with a phy connected by RMII.
It's worth to mention that the kernel and legacy BSP from NXP sets SUPP_RESET_RMII == (1 << 11) bit, however the description of this bit is missing in shared LPC32x0 User Manual UM10326 Rev. 3, July 22, 2011 and in LPC32x0 Draft User Mannual Rev. 00.27, November 20, 2008, also in my tests an SMSC LAN8700 phy device connected over RMII seems to work correctly without touching this bit.
Add support of RMII, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already define the same config value.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 7 ++++++- drivers/net/lpc32xx_eth.c | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c index 5a453e3..9c8d655 100644 --- a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c +++ b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c @@ -45,7 +45,12 @@ void lpc32xx_mac_init(void) { /* Enable MAC interface */ writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER
| CLK_MAC_MII, &clk->macclk_ctrl);
+#if defined(CONFIG_RMII)
| CLK_MAC_RMII,
+#else
| CLK_MAC_MII,
+#endif
&clk->macclk_ctrl);
}
void lpc32xx_mlc_nand_init(void) diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index f883a25..f3ab0f4 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -168,6 +168,7 @@ struct lpc32xx_eth_registers { #define COMMAND_RXENABLE 0x00000001 #define COMMAND_TXENABLE 0x00000002 #define COMMAND_PASSRUNTFRAME 0x00000040 +#define COMMAND_RMII 0x00000200 #define COMMAND_FULL_DUPLEX 0x00000400 /* Helper: general reset */ #define COMMAND_RESETS 0x00000038 @@ -201,6 +202,7 @@ struct lpc32xx_eth_device { struct eth_device dev; struct lpc32xx_eth_registers *regs; struct lpc32xx_eth_buffers *bufs;
bool phy_rmii;
};
#define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device)) @@ -359,7 +361,10 @@ int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
static struct lpc32xx_eth_device lpc32xx_eth = { .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE,
.bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS
.bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS, #if
+defined(CONFIG_RMII)
.phy_rmii = true,
+#endif };
#define TX_TIMEOUT 10000 @@ -471,7 +476,10 @@ static int lpc32xx_eth_init(struct eth_device *dev) writel(0x0012, ®s->ipgr);
/* pass runt (smaller than 64 bytes) frames */
writel(COMMAND_PASSRUNTFRAME, ®s->command);
if (lpc32xx_eth_device->phy_rmii)
writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command);
else
writel(COMMAND_PASSRUNTFRAME, ®s->command); /* Configure Full/Half Duplex mode */ if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { @@
-559,6 +567,8 @@ static int lpc32xx_eth_halt(struct eth_device *dev) #if defined(CONFIG_PHYLIB) int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) {
struct lpc32xx_eth_device *lpc32xx_eth_device =
container_of(dev, struct lpc32xx_eth_device, dev); struct mii_dev *bus; struct phy_device *phydev; int ret;
@@ -579,7 +589,11 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) return -ENOMEM; }
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII);
if (lpc32xx_eth_device->phy_rmii)
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII);
else
phydev = phy_connect(bus, phyid, dev,
- PHY_INTERFACE_MODE_MII);
if (!phydev) { printf("phy_connect failed\n"); return -ENODEV;
-- 2.1.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
This e-mail contains privileged and confidential information intended for the use of the addressees named above. If you are not the intended recipient of this e-mail, you are hereby notified that you must not disseminate, copy or take any action in respect of any information contained in it. If you have received this e-mail in error, please notify the sender immediately by e-mail and immediately destroy this e-mail and its attachments.
________________________________
This e-mail contains privileged and confidential information intended for the use of the addressees named above. If you are not the intended recipient of this e-mail, you are hereby notified that you must not disseminate, copy or take any action in respect of any information contained in it. If you have received this e-mail in error, please notify the sender immediately by e-mail and immediately destroy this e-mail and its attachments.

Hi Vladimir & Albert,
As stated before, I tested this patch and the 3 patches listed below using a Micrel KSZ8031RNL phy connected over RMII. Everything is working properly. 1) http://patchwork.ozlabs.org/patch/489100/ 2) http://patchwork.ozlabs.org/patch/489190/ 3) http://patchwork.ozlabs.org/patch/491419/
Tested-by: Sylvain Lemieux slemieux@tycoint.com
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Vladimir Zapolskiy Sent: 6-Jul-15 12:22 AM To: Albert ARIBAUD; Joe Hershberger Cc: Tom Rini; u-boot@lists.denx.de Subject: [U-Boot] [PATCH 2/2] net: lpc32xx: add RMII phy mode support
LPC32xx MAC and clock control configuration requires some minor quirks to deal with a phy connected by RMII.
It's worth to mention that the kernel and legacy BSP from NXP sets SUPP_RESET_RMII == (1 << 11) bit, however the description of this bit is missing in shared LPC32x0 User Manual UM10326 Rev. 3, July 22, 2011 and in LPC32x0 Draft User Mannual Rev. 00.27, November 20, 2008, also in my tests an SMSC LAN8700 phy device connected over RMII seems to work correctly without touching this bit.
Add support of RMII, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already define the same config value.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com --- arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 7 ++++++- drivers/net/lpc32xx_eth.c | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c index 5a453e3..9c8d655 100644 --- a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c +++ b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c @@ -45,7 +45,12 @@ void lpc32xx_mac_init(void) { /* Enable MAC interface */ writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER - | CLK_MAC_MII, &clk->macclk_ctrl); +#if defined(CONFIG_RMII) + | CLK_MAC_RMII, +#else + | CLK_MAC_MII, +#endif + &clk->macclk_ctrl); }
void lpc32xx_mlc_nand_init(void) diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index f883a25..f3ab0f4 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -168,6 +168,7 @@ struct lpc32xx_eth_registers { #define COMMAND_RXENABLE 0x00000001 #define COMMAND_TXENABLE 0x00000002 #define COMMAND_PASSRUNTFRAME 0x00000040 +#define COMMAND_RMII 0x00000200 #define COMMAND_FULL_DUPLEX 0x00000400 /* Helper: general reset */ #define COMMAND_RESETS 0x00000038 @@ -201,6 +202,7 @@ struct lpc32xx_eth_device { struct eth_device dev; struct lpc32xx_eth_registers *regs; struct lpc32xx_eth_buffers *bufs; + bool phy_rmii; };
#define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device)) @@ -359,7 +361,10 @@ int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
static struct lpc32xx_eth_device lpc32xx_eth = { .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE, - .bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS + .bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS, #if +defined(CONFIG_RMII) + .phy_rmii = true, +#endif };
#define TX_TIMEOUT 10000 @@ -471,7 +476,10 @@ static int lpc32xx_eth_init(struct eth_device *dev) writel(0x0012, ®s->ipgr);
/* pass runt (smaller than 64 bytes) frames */ - writel(COMMAND_PASSRUNTFRAME, ®s->command); + if (lpc32xx_eth_device->phy_rmii) + writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); + else + writel(COMMAND_PASSRUNTFRAME, ®s->command);
/* Configure Full/Half Duplex mode */ if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { @@ -559,6 +567,8 @@ static int lpc32xx_eth_halt(struct eth_device *dev) #if defined(CONFIG_PHYLIB) int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) { + struct lpc32xx_eth_device *lpc32xx_eth_device = + container_of(dev, struct lpc32xx_eth_device, dev); struct mii_dev *bus; struct phy_device *phydev; int ret; @@ -579,7 +589,11 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) return -ENOMEM; }
- phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); + if (lpc32xx_eth_device->phy_rmii) + phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII); + else + phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); + if (!phydev) { printf("phy_connect failed\n"); return -ENODEV; -- 2.1.4
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
________________________________
This e-mail contains privileged and confidential information intended for the use of the addressees named above. If you are not the intended recipient of this e-mail, you are hereby notified that you must not disseminate, copy or take any action in respect of any information contained in it. If you have received this e-mail in error, please notify the sender immediately by e-mail and immediately destroy this e-mail and its attachments.

From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Vladimir Zapolskiy Sent: 6-Jul-15 12:22 AM
LPC32xx MAC and clock control configuration requires some minor quirks to deal with a phy connected by RMII.
It's worth to mention that the kernel and legacy BSP from NXP sets SUPP_RESET_RMII == (1 << 11) bit, however the description of this bit is missing in shared LPC32x0 User Manual UM10326 Rev. 3, July 22, 2011 and in LPC32x0 Draft User Mannual Rev. 00.27, November 20, 2008, also in my tests an SMSC LAN8700 phy device connected over RMII seems to work correctly without touching this bit.
Add support of RMII, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already define the same config value.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 7 ++++++- drivers/net/lpc32xx_eth.c | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-)
Resent as the original tested by e-mail did not record on patchwork;
I tested this patch and the 3 patches listed below using a Micrel KSZ8031RNL phy connected over RMII. Everything is working properly. - http://patchwork.ozlabs.org/patch/489100/ - http://patchwork.ozlabs.org/patch/489190/ - http://patchwork.ozlabs.org/patch/491419/
Tested-by: Sylvain Lemieux slemieux@tycoint.com
________________________________
This e-mail contains privileged and confidential information intended for the use of the addressees named above. If you are not the intended recipient of this e-mail, you are hereby notified that you must not disseminate, copy or take any action in respect of any information contained in it. If you have received this e-mail in error, please notify the sender immediately by e-mail and immediately destroy this e-mail and its attachments.

Hi Vladimir,
On Sun, Jul 5, 2015 at 11:22 PM, Vladimir Zapolskiy vz@mleia.com wrote:
LPC32xx MAC and clock control configuration requires some minor quirks to deal with a phy connected by RMII.
It's worth to mention that the kernel and legacy BSP from NXP sets SUPP_RESET_RMII == (1 << 11) bit, however the description of this bit is missing in shared LPC32x0 User Manual UM10326 Rev. 3, July 22, 2011 and in LPC32x0 Draft User Mannual Rev. 00.27, November 20, 2008, also in my tests an SMSC LAN8700 phy device connected over RMII seems to work correctly without touching this bit.
Add support of RMII, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already define the same config value.
Signed-off-by: Vladimir Zapolskiy vz@mleia.com
Applied to u-boot-net, thanks! -Joe

Hello Vladimir,
On Mon, 6 Jul 2015 07:22:09 +0300, Vladimir Zapolskiy vz@mleia.com wrote:
This is an update to LPC32xx MAC driver, which needs to have small quirks in order to properly work with an external phy connected by RMII interface.
RMII mode of MAC operation is selected, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already have the same config value.
Also hopefully the first change from the series speeds up auto negotiation due to corrected configuration of MAC on intialization.
Tested with SMSC LAN8700 phy.
Vladimir Zapolskiy (2): net: lpc32xx: improve MAC configuration on reset and initialization net: lpc32xx: add RMII phy mode support
This series actually requires two other lpc32xx patches that you posted earlier but which are not yet in u-boot/master or u-boot-arm/master:
http://patchwork.ozlabs.org/patch/489100/ http://patchwork.ozlabs.org/patch/489190/
In the future, please indicate when such a dependency is required, so that testers know how to apply your patchs beforehand.
This point aside, I've tested the four patches above u-boot-arm/master on a work_92105 target which has CONFIG_MII, and found no regression... and a dramatic increase in TFTP throughput, so thanks. :)
(not adding my Tested-by because I don't want to mislead anyone: I haven't tested RMII)
Amicalement,

Hello Albert,
On 06.07.2015 09:46, Albert ARIBAUD (3ADEV) wrote:
Hello Vladimir,
On Mon, 6 Jul 2015 07:22:09 +0300, Vladimir Zapolskiy vz@mleia.com wrote:
This is an update to LPC32xx MAC driver, which needs to have small quirks in order to properly work with an external phy connected by RMII interface.
RMII mode of MAC operation is selected, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already have the same config value.
Also hopefully the first change from the series speeds up auto negotiation due to corrected configuration of MAC on intialization.
Tested with SMSC LAN8700 phy.
Vladimir Zapolskiy (2): net: lpc32xx: improve MAC configuration on reset and initialization net: lpc32xx: add RMII phy mode support
This series actually requires two other lpc32xx patches that you posted earlier but which are not yet in u-boot/master or u-boot-arm/master:
http://patchwork.ozlabs.org/patch/489100/ http://patchwork.ozlabs.org/patch/489190/
In the future, please indicate when such a dependency is required, so that testers know how to apply your patchs beforehand.
my fault, certainly will add such a note in future...
This point aside, I've tested the four patches above u-boot-arm/master on a work_92105 target which has CONFIG_MII, and found no regression... and a dramatic increase in TFTP throughput, so thanks. :)
Thank you so much for testing MII, this is something I'm unable to do on my end.
(not adding my Tested-by because I don't want to mislead anyone: I haven't tested RMII)
Amicalement,
-- With best wishes, Vladimir

Hi Joe,
On 06.07.2015 10:55, Vladimir Zapolskiy wrote:
Hello Albert,
On 06.07.2015 09:46, Albert ARIBAUD (3ADEV) wrote:
Hello Vladimir,
On Mon, 6 Jul 2015 07:22:09 +0300, Vladimir Zapolskiy vz@mleia.com wrote:
This is an update to LPC32xx MAC driver, which needs to have small quirks in order to properly work with an external phy connected by RMII interface.
RMII mode of MAC operation is selected, if CONFIG_RMII is defined, this option is aligned with a number of boards, which already have the same config value.
Also hopefully the first change from the series speeds up auto negotiation due to corrected configuration of MAC on intialization.
Tested with SMSC LAN8700 phy.
Vladimir Zapolskiy (2): net: lpc32xx: improve MAC configuration on reset and initialization net: lpc32xx: add RMII phy mode support
This series actually requires two other lpc32xx patches that you posted earlier but which are not yet in u-boot/master or u-boot-arm/master:
http://patchwork.ozlabs.org/patch/489100/ http://patchwork.ozlabs.org/patch/489190/
In the future, please indicate when such a dependency is required, so that testers know how to apply your patchs beforehand.
my fault, certainly will add such a note in future...
This point aside, I've tested the four patches above u-boot-arm/master on a work_92105 target which has CONFIG_MII, and found no regression... and a dramatic increase in TFTP throughput, so thanks. :)
Thank you so much for testing MII, this is something I'm unable to do on my end.
(not adding my Tested-by because I don't want to mislead anyone: I haven't tested RMII)
Amicalement,
ping.
It's a pity that merge window is closed, please review/merge the changes.
Thank you in advance.
-- With best wishes, Vladimir
participants (4)
-
Albert ARIBAUD (3ADEV)
-
Joe Hershberger
-
LEMIEUX, SYLVAIN
-
Vladimir Zapolskiy