[U-Boot] [PATCH] net: designware: set the PS bit when resetting DMA bus in MII configuration

Quentin Schulz quentin.schulz at bootlin.com
Mon Jun 4 10:17:33 UTC 2018


On the SPEAr600 SoC, which has the dwmac1000 variant of the IP block,
the DMA reset never succeeds when a MII PHY is used (no problem with a
GMII PHY). The designware_eth_init() function sets the
DMAMAC_SRST bit in the DMA_BUS_MODE register, and then
polls until this bit clears. When a MII PHY is used, with the current
driver, this bit never clears and the driver therefore doesn't work.

The reason is that the PS bit of the GMAC_CONTROL register should be
correctly configured for the DMA reset to work. When the PS bit is 0,
it tells the MAC we have a GMII PHY, when the PS bit is 1, it tells
the MAC we have a MII PHY.

Doing a DMA reset clears all registers, so the PS bit is cleared as
well. This makes the DMA reset work fine with a GMII PHY. However,
with MII PHY, the PS bit should be set.

We have identified this issue thanks to two SPEAr600 platform:

- One equipped with a GMII PHY, with which the existing driver was
working fine.

- One equipped with a MII PHY, where the current driver fails because
the DMA reset times out.

Note: Taken from https://www.spinics.net/lists/netdev/msg432578.html

Signed-off-by: Quentin Schulz <quentin.schulz at bootlin.com>
---

Note, it looks like dw_adjust_link[1] already tries to handle this.
However, the condition is the speed of the link (if not 1Gbps set
the bit), not the mode of communication between the MAC and the PHY.
We could definitely have a 100Mbps with e.g. a GMII mode, and thus we
should not clear the MII_PORTSELECT bit.

Do you agree with regards to the commit log above?

[1] https://elixir.bootlin.com/u-boot/latest/source/drivers/net/designware.c#L243

 drivers/net/designware.c |  9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index cf12521..10a8709 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -280,6 +280,15 @@ int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr)
 
 	writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
 
+	/*
+	 * When a MII PHY is used, we must set the PS bit for the DMA
+	 * reset to succeed.
+	 */
+	if (priv->phydev->interface == PHY_INTERFACE_MODE_MII)
+		writel(readl(&mac_p->conf) | MII_PORTSELECT, &mac_p->conf);
+	else
+		writel(readl(&mac_p->conf) & ~MII_PORTSELECT, &mac_p->conf);
+
 	start = get_timer(0);
 	while (readl(&dma_p->busmode) & DMAMAC_SRST) {
 		if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) {

base-commit: b5351a439088dfffd83bfaac81f604344ee2e3bd
-- 
git-series 0.9.1


More information about the U-Boot mailing list