Skip to content

Commit 6d4cd04

Browse files
vinodkouldavem330
authored andcommitted
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: cd28d1d: ("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>
1 parent 43f2ebd commit 6d4cd04

File tree

1 file changed

+42
-11
lines changed

1 file changed

+42
-11
lines changed

drivers/net/phy/at803x.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
103103
return phy_write(phydev, AT803X_DEBUG_DATA, val);
104104
}
105105

106+
static int at803x_enable_rx_delay(struct phy_device *phydev)
107+
{
108+
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
109+
AT803X_DEBUG_RX_CLK_DLY_EN);
110+
}
111+
112+
static int at803x_enable_tx_delay(struct phy_device *phydev)
113+
{
114+
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
115+
AT803X_DEBUG_TX_CLK_DLY_EN);
116+
}
117+
106118
static int at803x_disable_rx_delay(struct phy_device *phydev)
107119
{
108120
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
@@ -241,23 +253,42 @@ static int at803x_config_init(struct phy_device *phydev)
241253
if (ret < 0)
242254
return ret;
243255

244-
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
245-
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
246-
phydev->interface == PHY_INTERFACE_MODE_RGMII) {
247-
ret = at803x_disable_rx_delay(phydev);
256+
/* The RX and TX delay default is:
257+
* after HW reset: RX delay enabled and TX delay disabled
258+
* after SW reset: RX delay enabled, while TX delay retains the
259+
* value before reset.
260+
*
261+
* So let's first disable the RX and TX delays in PHY and enable
262+
* them based on the mode selected (this also takes care of RGMII
263+
* mode where we expect delays to be disabled)
264+
*/
265+
266+
ret = at803x_disable_rx_delay(phydev);
267+
if (ret < 0)
268+
return ret;
269+
ret = at803x_disable_tx_delay(phydev);
270+
if (ret < 0)
271+
return ret;
272+
273+
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
274+
phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
275+
/* If RGMII_ID or RGMII_RXID are specified enable RX delay,
276+
* otherwise keep it disabled
277+
*/
278+
ret = at803x_enable_rx_delay(phydev);
248279
if (ret < 0)
249280
return ret;
250281
}
251282

252-
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
253-
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
254-
phydev->interface == PHY_INTERFACE_MODE_RGMII) {
255-
ret = at803x_disable_tx_delay(phydev);
256-
if (ret < 0)
257-
return ret;
283+
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
284+
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
285+
/* If RGMII_ID or RGMII_TXID are specified enable TX delay,
286+
* otherwise keep it disabled
287+
*/
288+
ret = at803x_enable_tx_delay(phydev);
258289
}
259290

260-
return 0;
291+
return ret;
261292
}
262293

263294
static int at803x_ack_interrupt(struct phy_device *phydev)

0 commit comments

Comments
 (0)