diff mbox

[U-Boot,2/2] net: lpc32xx: add RMII phy mode support

Message ID 1436156531-302-3-git-send-email-vz@mleia.com
State Accepted
Delegated to: Joe Hershberger
Headers show

Commit Message

Vladimir Zapolskiy July 6, 2015, 4:22 a.m. UTC
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(-)

Comments

LEMIEUX, SYLVAIN July 29, 2015, 6:53 p.m. UTC | #1
> 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>
Joe Hershberger Aug. 12, 2015, 7:34 p.m. UTC | #2
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
diff mbox

Patch

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, &regs->ipgr);
 
 	/* pass runt (smaller than 64 bytes) frames */
-	writel(COMMAND_PASSRUNTFRAME, &regs->command);
+	if (lpc32xx_eth_device->phy_rmii)
+		writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, &regs->command);
+	else
+		writel(COMMAND_PASSRUNTFRAME, &regs->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;