diff options
author | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2017-02-14 12:35:52 +0100 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2017-03-09 01:40:18 +0100 |
commit | e98553a3695f846de4ce39cce04c248b24fd94f6 (patch) | |
tree | 2a5509eec322f8389352fed23666dada78fd00fc /drivers/net/sun8i_emac.c | |
parent | b9e8f0ff8b37a1170a665396bc6bb1ade2cf0b3f (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.c | 14 |
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); |