net: phy: at803x: disable delay only for RGMII mode
Per "Documentation/devicetree/bindings/net/ethernet.txt" RGMII mode
should not have delay in PHY whereas RGMII_ID and RGMII_RXID/RGMII_TXID
can have delay in PHY.
So disable the delay only for RGMII mode and enable for other modes.
Also treat the default case as disabled delays.
Fixes: cd28d1d6e5
: ("net: phy: at803x: Disable phy delay for RGMII mode")
Reported-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Reviewed-by: Niklas Cassel <niklas.cassel@linaro.org>
Tested-by: Peter Ujfalusi <peter.ujflausi@ti.com>
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
43f2ebd557
commit
6d4cd041f0
@ -103,6 +103,18 @@ static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
|
|||||||
return phy_write(phydev, AT803X_DEBUG_DATA, val);
|
return phy_write(phydev, AT803X_DEBUG_DATA, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
static int at803x_disable_rx_delay(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||||
@ -241,23 +253,42 @@ static int at803x_config_init(struct phy_device *phydev)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
|
/* The RX and TX delay default is:
|
||||||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
* after HW reset: RX delay enabled and TX delay disabled
|
||||||
phydev->interface == PHY_INTERFACE_MODE_RGMII) {
|
* after SW reset: RX delay enabled, while TX delay retains the
|
||||||
ret = at803x_disable_rx_delay(phydev);
|
* 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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
|
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
||||||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
|
||||||
phydev->interface == PHY_INTERFACE_MODE_RGMII) {
|
/* If RGMII_ID or RGMII_TXID are specified enable TX delay,
|
||||||
ret = at803x_disable_tx_delay(phydev);
|
* otherwise keep it disabled
|
||||||
if (ret < 0)
|
*/
|
||||||
return ret;
|
ret = at803x_enable_tx_delay(phydev);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int at803x_ack_interrupt(struct phy_device *phydev)
|
static int at803x_ack_interrupt(struct phy_device *phydev)
|
||||||
|
Loading…
Reference in New Issue
Block a user