/* Extended Page 2 Registers */
 #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 RGMII_RX_CLK_DELAY_MASK                  0x0070
 #define RGMII_RX_CLK_DELAY_POS           4
 
        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)
 {
        struct vsc8531_private *vsc8531 = phydev->priv;
        if (ret)
                return ret;
 
+       if (phy_interface_is_rgmii(phydev))
+               vsc8584_rgmii_set_skews(phydev);
+
        ret = genphy_soft_reset(phydev);
        if (ret)
                return ret;