diff options
Diffstat (limited to 'drivers/net/phy/ti_phy_init.c')
| -rw-r--r-- | drivers/net/phy/ti_phy_init.c | 48 | 
1 files changed, 47 insertions, 1 deletions
| diff --git a/drivers/net/phy/ti_phy_init.c b/drivers/net/phy/ti_phy_init.c index a0878193ac0..850c0cbec96 100644 --- a/drivers/net/phy/ti_phy_init.c +++ b/drivers/net/phy/ti_phy_init.c @@ -10,12 +10,58 @@  #include <phy.h>  #include "ti_phy_init.h" +#define DP83822_DEVADDR		0x1f + +#define MII_DP83822_RCSR	0x17 + +/* RCSR bits */ +#define DP83822_RX_CLK_SHIFT	BIT(12) +#define DP83822_TX_CLK_SHIFT	BIT(11) + +/* DP83822 specific RGMII RX/TX delay configuration. */ +static int dp83822_config(struct phy_device *phydev) +{ +	ofnode node = phy_get_ofnode(phydev); +	u32 rgmii_delay = 0; +	u32 rx_delay = 0; +	u32 tx_delay = 0; +	int ret; + +	ret = ofnode_read_u32(node, "rx-internal-delay-ps", &rx_delay); +	if (ret) { +		rx_delay = phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || +			   phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID; +	} + +	ret = ofnode_read_u32(node, "tx-internal-delay-ps", &tx_delay); +	if (ret) { +		tx_delay = phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || +			   phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID; +	} + +	/* Bit set means Receive path internal clock shift is ENABLED */ +	if (rx_delay) +		rgmii_delay |= DP83822_RX_CLK_SHIFT; + +	/* Bit set means Transmit path internal clock shift is DISABLED */ +	if (!tx_delay) +		rgmii_delay |= DP83822_TX_CLK_SHIFT; + +	ret = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, +			     DP83822_RX_CLK_SHIFT | DP83822_TX_CLK_SHIFT, +			     rgmii_delay); +	if (ret) +		return ret; + +	return genphy_config_aneg(phydev); +} +  U_BOOT_PHY_DRIVER(dp83822) = {  	.name = "TI DP83822",  	.uid = 0x2000a240,  	.mask = 0xfffffff0,  	.features = PHY_BASIC_FEATURES, -	.config = &genphy_config_aneg, +	.config = &dp83822_config,  	.startup = &genphy_startup,  	.shutdown = &genphy_shutdown,  }; | 
