Commit 5c9a9fce authored by David S. Miller's avatar David S. Miller

Merge branch 'mscc-RGMII'

Antoine Tenart says:

====================
net: phy: mscc: add support for RGMII MAC mode

This series adds support for the RGMII MAC mode for the VSC8584 PHY
family and for RGMII_ID modes (Tx and/or Rx).

I decided to drop the custom delay for now. I made some tests and it
seemed to be working quite well. If we find out we really need to lower
the delay, which I doubt, I'll send support for it.

Since v2:
  - Dropped support for custom dt bindings.
  - Add the 2ns delay based on the interface mode.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9096a03f dee48f78
...@@ -161,6 +161,20 @@ enum rgmii_rx_clock_delay { ...@@ -161,6 +161,20 @@ enum rgmii_rx_clock_delay {
/* Extended Page 2 Registers */ /* Extended Page 2 Registers */
#define MSCC_PHY_CU_PMD_TX_CNTL 16 #define MSCC_PHY_CU_PMD_TX_CNTL 16
#define MSCC_PHY_RGMII_SETTINGS 18
#define RGMII_SKEW_RX_POS 1
#define RGMII_SKEW_TX_POS 4
/* RGMII skew values, in ns */
#define VSC8584_RGMII_SKEW_0_2 0
#define VSC8584_RGMII_SKEW_0_8 1
#define VSC8584_RGMII_SKEW_1_1 2
#define VSC8584_RGMII_SKEW_1_7 3
#define VSC8584_RGMII_SKEW_2_0 4
#define VSC8584_RGMII_SKEW_2_3 5
#define VSC8584_RGMII_SKEW_2_6 6
#define VSC8584_RGMII_SKEW_3_4 7
#define MSCC_PHY_RGMII_CNTL 20 #define MSCC_PHY_RGMII_CNTL 20
#define RGMII_RX_CLK_DELAY_MASK 0x0070 #define RGMII_RX_CLK_DELAY_MASK 0x0070
#define RGMII_RX_CLK_DELAY_POS 4 #define RGMII_RX_CLK_DELAY_POS 4
...@@ -241,6 +255,7 @@ enum rgmii_rx_clock_delay { ...@@ -241,6 +255,7 @@ enum rgmii_rx_clock_delay {
#define MAC_CFG_MASK 0xc000 #define MAC_CFG_MASK 0xc000
#define MAC_CFG_SGMII 0x0000 #define MAC_CFG_SGMII 0x0000
#define MAC_CFG_QSGMII 0x4000 #define MAC_CFG_QSGMII 0x4000
#define MAC_CFG_RGMII 0x8000
/* Test page Registers */ /* Test page Registers */
#define MSCC_PHY_TEST_PAGE_5 5 #define MSCC_PHY_TEST_PAGE_5 5
......
...@@ -1288,6 +1288,32 @@ static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed) ...@@ -1288,6 +1288,32 @@ static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed)
return false; return false;
} }
static void vsc8584_rgmii_set_skews(struct phy_device *phydev)
{
u32 skew_rx, skew_tx;
/* We first set the Rx and Tx skews to their default value in h/w
* (0.2 ns).
*/
skew_rx = VSC8584_RGMII_SKEW_0_2;
skew_tx = VSC8584_RGMII_SKEW_0_2;
/* We then set the skews based on the interface mode. */
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
skew_rx = VSC8584_RGMII_SKEW_2_0;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
skew_tx = VSC8584_RGMII_SKEW_2_0;
/* Finally we apply the skews configuration. */
phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
MSCC_PHY_RGMII_SETTINGS,
(0x7 << RGMII_SKEW_RX_POS) | (0x7 << RGMII_SKEW_TX_POS),
(skew_rx << RGMII_SKEW_RX_POS) |
(skew_tx << RGMII_SKEW_TX_POS));
}
static int vsc8584_config_init(struct phy_device *phydev) static int vsc8584_config_init(struct phy_device *phydev)
{ {
struct vsc8531_private *vsc8531 = phydev->priv; struct vsc8531_private *vsc8531 = phydev->priv;
...@@ -1360,27 +1386,35 @@ static int vsc8584_config_init(struct phy_device *phydev) ...@@ -1360,27 +1386,35 @@ static int vsc8584_config_init(struct phy_device *phydev)
val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK); val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
val &= ~MAC_CFG_MASK; val &= ~MAC_CFG_MASK;
if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
val |= MAC_CFG_QSGMII; val |= MAC_CFG_QSGMII;
else } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
val |= MAC_CFG_SGMII; val |= MAC_CFG_SGMII;
} else if (phy_interface_is_rgmii(phydev)) {
val |= MAC_CFG_RGMII;
} else {
ret = -EINVAL;
goto err;
}
ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val); ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
if (ret) if (ret)
goto err; goto err;
val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT | if (!phy_interface_is_rgmii(phydev)) {
PROC_CMD_READ_MOD_WRITE_PORT; val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) PROC_CMD_READ_MOD_WRITE_PORT;
val |= PROC_CMD_QSGMII_MAC; if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
else val |= PROC_CMD_QSGMII_MAC;
val |= PROC_CMD_SGMII_MAC; else
val |= PROC_CMD_SGMII_MAC;
ret = vsc8584_cmd(phydev, val); ret = vsc8584_cmd(phydev, val);
if (ret) if (ret)
goto err; goto err;
usleep_range(10000, 20000); usleep_range(10000, 20000);
}
/* Disable SerDes for 100Base-FX */ /* Disable SerDes for 100Base-FX */
ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF | ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
...@@ -1414,6 +1448,9 @@ static int vsc8584_config_init(struct phy_device *phydev) ...@@ -1414,6 +1448,9 @@ static int vsc8584_config_init(struct phy_device *phydev)
if (ret) if (ret)
return ret; return ret;
if (phy_interface_is_rgmii(phydev))
vsc8584_rgmii_set_skews(phydev);
ret = genphy_soft_reset(phydev); ret = genphy_soft_reset(phydev);
if (ret) if (ret)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment