summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2020-07-06 03:40:45 +0300
committerJagan Teki <jagan@amarulasolutions.com>2020-10-21 21:15:39 +0300
commit4f0278dac56a658ef1e0967fec0bb95372a875bd (patch)
treeb8e1b4190d414e87347411451d1907cafd82476d /drivers/net
parent88ae8fba84d85454008e3c89fcb790f8d077d7b5 (diff)
downloadu-boot-4f0278dac56a658ef1e0967fec0bb95372a875bd.tar.xz
net: sun8i-emac: Lower MDIO frequency
When sending a command via the MDIO bus, the Designware MAC expects some bits in the CMD register to describe the clock divider value between the main clock and the MDIO clock. So far we were omitting these bits, resulting in setting "00", which means "/ 16", so ending up with an MDIO frequency of either 18.75 or 12.5 MHz. All the internal PHYs in the H3/H5/H6 SoCs as well as the Gbit Realtek PHYs seem to be fine with that - although it looks like to be severly overclocked (the MDIO spec limits the frequency to 2.5 MHz). However the external 100Mbit PHY on the Pine64 (non-plus) board is not happy with that, Ethernet was actually never working there, as the PHY didn't probe. As we set the EMAC clock (via AHB2) to 300 MHz in ATF (on the 64-bit SoCs), and use 200 MHz on the H3, we need the highest divider of 128 to let the MDIO clock end up below the required 2.5 MHz. This enables Ethernet on the Pine64(non-plus). Signed-off-by: Andre Przywara <andre.przywara@arm.com> Acked-by: Maxime Ripard <mripard@kernel.org> Tested-by: Amit Singh Tomar <amittomer25@gmail.com> # Pine64+ Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sun8i_emac.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index 985ac961f1..4524604126 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -41,6 +41,11 @@
#define MDIO_CMD_MII_PHY_REG_ADDR_SHIFT 4
#define MDIO_CMD_MII_PHY_ADDR_MASK 0x0001f000
#define MDIO_CMD_MII_PHY_ADDR_SHIFT 12
+#define MDIO_CMD_MII_CLK_CSR_DIV_16 0x0
+#define MDIO_CMD_MII_CLK_CSR_DIV_32 0x1
+#define MDIO_CMD_MII_CLK_CSR_DIV_64 0x2
+#define MDIO_CMD_MII_CLK_CSR_DIV_128 0x3
+#define MDIO_CMD_MII_CLK_CSR_SHIFT 20
#define CONFIG_TX_DESCR_NUM 32
#define CONFIG_RX_DESCR_NUM 32
@@ -199,6 +204,12 @@ static int sun8i_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
mii_cmd |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
MDIO_CMD_MII_PHY_ADDR_MASK;
+ /*
+ * The EMAC clock is either 200 or 300 MHz, so we need a divider
+ * of 128 to get the MDIO frequency below the required 2.5 MHz.
+ */
+ mii_cmd |= MDIO_CMD_MII_CLK_CSR_DIV_128 << MDIO_CMD_MII_CLK_CSR_SHIFT;
+
mii_cmd |= MDIO_CMD_MII_BUSY;
writel(mii_cmd, priv->mac_reg + EMAC_MII_CMD);
@@ -224,6 +235,12 @@ static int sun8i_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
mii_cmd |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
MDIO_CMD_MII_PHY_ADDR_MASK;
+ /*
+ * The EMAC clock is either 200 or 300 MHz, so we need a divider
+ * of 128 to get the MDIO frequency below the required 2.5 MHz.
+ */
+ mii_cmd |= MDIO_CMD_MII_CLK_CSR_DIV_128 << MDIO_CMD_MII_CLK_CSR_SHIFT;
+
mii_cmd |= MDIO_CMD_MII_WRITE;
mii_cmd |= MDIO_CMD_MII_BUSY;