summaryrefslogtreecommitdiff
path: root/drivers/net/sun8i_emac.c
diff options
context:
space:
mode:
authorPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2017-02-14 12:35:52 +0100
committerPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2017-03-09 01:40:18 +0100
commite98553a3695f846de4ce39cce04c248b24fd94f6 (patch)
tree2a5509eec322f8389352fed23666dada78fd00fc /drivers/net/sun8i_emac.c
parentb9e8f0ff8b37a1170a665396bc6bb1ade2cf0b3f (diff)
sun8i_emac: Set MDC divider for MDIO read/write
The IEEE 802.3 standard guarantees operation of the MDIO signals at up to 2.5MHz (anything above this is a vendor-specific feature, although most PHYs work at higher frequencies). With the EMAC being fed by a (typically) 300MHz clock (e.g. on the A64 this is AHB2, which should be kept at 300MHz according to the CCU documentation), we need to use the divide-by-128 setting to get us below 2.5MHz. The ~2.34MHz clock signal (i.e. assuring that the MDC clock is indeed derived from the AHB2 clock) has been verified using a A64-uQ7. Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Diffstat (limited to 'drivers/net/sun8i_emac.c')
-rw-r--r--drivers/net/sun8i_emac.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index b87210bad7..5ae17b7611 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -30,6 +30,12 @@
#define MDIO_CMD_MII_PHY_ADDR_MASK 0x0001f000
#define MDIO_CMD_MII_PHY_ADDR_SHIFT 12
+#define MDIO_CMD_MDC_DIV_RATIO_M_SHIFT 20
+#define MDIO_CMD_MDC_DIV_16 (0 << MDIO_CMD_MDC_DIV_RATIO_M_SHIFT)
+#define MDIO_CMD_MDC_DIV_32 (1 << MDIO_CMD_MDC_DIV_RATIO_M_SHIFT)
+#define MDIO_CMD_MDC_DIV_64 (2 << MDIO_CMD_MDC_DIV_RATIO_M_SHIFT)
+#define MDIO_CMD_MDC_DIV_128 (3 << MDIO_CMD_MDC_DIV_RATIO_M_SHIFT)
+
#define CONFIG_TX_DESCR_NUM 32
#define CONFIG_RX_DESCR_NUM 32
#define CONFIG_ETH_BUFSIZE 2048 /* Note must be dma aligned */
@@ -147,6 +153,10 @@ static int sun8i_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
miiaddr |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
MDIO_CMD_MII_PHY_ADDR_MASK;
+ /* The MAC block is fed by a 300MHz clock, so we need to divide by 128
+ to bring the MDC into the range permissible by the IEEE standard. */
+ miiaddr |= MDIO_CMD_MDC_DIV_128;
+
miiaddr |= MDIO_CMD_MII_BUSY;
writel(miiaddr, priv->mac_reg + EMAC_MII_CMD);
@@ -180,6 +190,10 @@ static int sun8i_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
miiaddr |= MDIO_CMD_MII_WRITE;
miiaddr |= MDIO_CMD_MII_BUSY;
+ /* The MAC block is fed by a 300MHz clock, so we need to divide by 128
+ to bring the MDC into the range permissible by the IEEE standard. */
+ miiaddr |= MDIO_CMD_MDC_DIV_128;
+
writel(val, priv->mac_reg + EMAC_MII_DATA);
writel(miiaddr, priv->mac_reg + EMAC_MII_CMD);