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.sch...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot