aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller2019-02-22 15:30:03 -0800
committerDavid S. Miller2019-02-22 15:30:03 -0800
commite59d790959b48a42874fa2cb16475a621663f085 (patch)
tree65cea3fcbc0e15e87ae9d17873567ae3560c2982
parent14215108a1fd7e002c0a1f9faf8fbaf41fdda50d (diff)
parent6d4cd041f0af5b4c8fc742b4a68eac22e420e28c (diff)
Merge branch 'net-phy-at803x-Update-delays-for-RGMII-modes'
Vinod Koul says: ==================== net: phy: at803x: Update delays for RGMII modes Peter[1] reported that patch cd28d1d6e52e: ("net: phy: at803x: Disable phy delay for RGMII mode") caused regression on am335x-evmsk board. This board expects the Phy delay to be enabled but specified RGMII mode which refers to delays being disabled. So fix this by disabling delay only for RGMII mode and enable for RGMII_ID and RGMII_TXID/RXID modes. While at it, as pointed by Dave, don't inline the helpers. [1]: https://www.spinics.net/lists/netdev/msg550749.html Changes in v4: - fix log & comments nbased on Marc's feedback ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/at803x.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 90dc62c15fc5..f3e96191eb6f 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -103,13 +103,25 @@ static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
return phy_write(phydev, AT803X_DEBUG_DATA, val);
}
-static inline int at803x_disable_rx_delay(struct phy_device *phydev)
+static int at803x_enable_rx_delay(struct phy_device *phydev)
+{
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
+ AT803X_DEBUG_RX_CLK_DLY_EN);
+}
+
+static int at803x_enable_tx_delay(struct phy_device *phydev)
+{
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
+ AT803X_DEBUG_TX_CLK_DLY_EN);
+}
+
+static int at803x_disable_rx_delay(struct phy_device *phydev)
{
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
AT803X_DEBUG_RX_CLK_DLY_EN, 0);
}
-static inline int at803x_disable_tx_delay(struct phy_device *phydev)
+static int at803x_disable_tx_delay(struct phy_device *phydev)
{
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
AT803X_DEBUG_TX_CLK_DLY_EN, 0);
@@ -241,23 +253,42 @@ static int at803x_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
- phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
- phydev->interface == PHY_INTERFACE_MODE_RGMII) {
- ret = at803x_disable_rx_delay(phydev);
+ /* The RX and TX delay default is:
+ * after HW reset: RX delay enabled and TX delay disabled
+ * after SW reset: RX delay enabled, while TX delay retains the
+ * value before reset.
+ *
+ * So let's first disable the RX and TX delays in PHY and enable
+ * them based on the mode selected (this also takes care of RGMII
+ * mode where we expect delays to be disabled)
+ */
+
+ ret = at803x_disable_rx_delay(phydev);
+ if (ret < 0)
+ return ret;
+ ret = at803x_disable_tx_delay(phydev);
+ if (ret < 0)
+ return ret;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
+ /* If RGMII_ID or RGMII_RXID are specified enable RX delay,
+ * otherwise keep it disabled
+ */
+ ret = at803x_enable_rx_delay(phydev);
if (ret < 0)
return ret;
}
- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
- phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
- phydev->interface == PHY_INTERFACE_MODE_RGMII) {
- ret = at803x_disable_tx_delay(phydev);
- if (ret < 0)
- return ret;
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+ /* If RGMII_ID or RGMII_TXID are specified enable TX delay,
+ * otherwise keep it disabled
+ */
+ ret = at803x_enable_tx_delay(phydev);
}
- return 0;
+ return ret;
}
static int at803x_ack_interrupt(struct phy_device *phydev)