net: phy: adin: configure RGMII/RMII/MII modes on config
The ADIN1300 chip supports RGMII, RMII & MII modes. Default (if unconfigured) is RGMII. This change adds support for configuring these modes via the device registers. For RGMII with internal delays (modes RGMII_ID,RGMII_TXID, RGMII_RXID), the default delay is 2 ns. This can be configurable and will be done in a subsequent change. Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
3e32d020d8
Коммит
d6200c8fd5
|
@ -31,9 +31,86 @@
|
|||
(ADIN1300_INT_LINK_STAT_CHNG_EN | ADIN1300_INT_HW_IRQ_EN)
|
||||
#define ADIN1300_INT_STATUS_REG 0x0019
|
||||
|
||||
#define ADIN1300_GE_RGMII_CFG_REG 0xff23
|
||||
#define ADIN1300_GE_RGMII_RXID_EN BIT(2)
|
||||
#define ADIN1300_GE_RGMII_TXID_EN BIT(1)
|
||||
#define ADIN1300_GE_RGMII_EN BIT(0)
|
||||
|
||||
#define ADIN1300_GE_RMII_CFG_REG 0xff24
|
||||
#define ADIN1300_GE_RMII_EN BIT(0)
|
||||
|
||||
static int adin_config_rgmii_mode(struct phy_device *phydev)
|
||||
{
|
||||
int reg;
|
||||
|
||||
if (!phy_interface_is_rgmii(phydev))
|
||||
return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
|
||||
ADIN1300_GE_RGMII_CFG_REG,
|
||||
ADIN1300_GE_RGMII_EN);
|
||||
|
||||
reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_RGMII_CFG_REG);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
reg |= ADIN1300_GE_RGMII_EN;
|
||||
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
||||
phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
|
||||
reg |= ADIN1300_GE_RGMII_RXID_EN;
|
||||
} else {
|
||||
reg &= ~ADIN1300_GE_RGMII_RXID_EN;
|
||||
}
|
||||
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
||||
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
|
||||
reg |= ADIN1300_GE_RGMII_TXID_EN;
|
||||
} else {
|
||||
reg &= ~ADIN1300_GE_RGMII_TXID_EN;
|
||||
}
|
||||
|
||||
return phy_write_mmd(phydev, MDIO_MMD_VEND1,
|
||||
ADIN1300_GE_RGMII_CFG_REG, reg);
|
||||
}
|
||||
|
||||
static int adin_config_rmii_mode(struct phy_device *phydev)
|
||||
{
|
||||
int reg;
|
||||
|
||||
if (phydev->interface != PHY_INTERFACE_MODE_RMII)
|
||||
return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
|
||||
ADIN1300_GE_RMII_CFG_REG,
|
||||
ADIN1300_GE_RMII_EN);
|
||||
|
||||
reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_RMII_CFG_REG);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
reg |= ADIN1300_GE_RMII_EN;
|
||||
|
||||
return phy_write_mmd(phydev, MDIO_MMD_VEND1,
|
||||
ADIN1300_GE_RMII_CFG_REG, reg);
|
||||
}
|
||||
|
||||
static int adin_config_init(struct phy_device *phydev)
|
||||
{
|
||||
return genphy_config_init(phydev);
|
||||
int rc;
|
||||
|
||||
rc = genphy_config_init(phydev);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = adin_config_rgmii_mode(phydev);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = adin_config_rmii_mode(phydev);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
phydev_dbg(phydev, "PHY is using mode '%s'\n",
|
||||
phy_modes(phydev->interface));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adin_phy_ack_intr(struct phy_device *phydev)
|
||||
|
|
Загрузка…
Ссылка в новой задаче