net: phy: Add SGMII support for TI phy

Add support of SGMII to TI phy dp838367
Enable the SGMII and PCS settings in phy
control, CFG2 and BIST registers

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
index c3912d5..937426b 100644
--- a/drivers/net/phy/ti.c
+++ b/drivers/net/phy/ti.c
@@ -12,6 +12,8 @@
 
 #define MII_DP83867_PHYCTRL	0x10
 #define MII_DP83867_MICR	0x12
+#define MII_DP83867_CFG2	0x14
+#define MII_DP83867_BISCR	0x16
 #define DP83867_CTRL		0x1f
 
 /* Extended Registers */
@@ -43,10 +45,22 @@
 #define DP83867_PHYCR_FIFO_DEPTH_SHIFT		14
 #define DP83867_MDI_CROSSOVER		5
 #define DP83867_MDI_CROSSOVER_AUTO	2
+#define DP83867_MDI_CROSSOVER_MDIX	2
+#define DP83867_PHYCTRL_SGMIIEN			0x0800
+#define DP83867_PHYCTRL_RXFIFO_SHIFT	12
+#define DP83867_PHYCTRL_TXFIFO_SHIFT	14
 
 /* RGMIIDCTL bits */
 #define DP83867_RGMII_TX_CLK_DELAY_SHIFT	4
 
+/* CFG2 bits */
+#define MII_DP83867_CFG2_SPEEDOPT_10EN		0x0040
+#define MII_DP83867_CFG2_SGMII_AUTONEGEN	0x0080
+#define MII_DP83867_CFG2_SPEEDOPT_ENH		0x0100
+#define MII_DP83867_CFG2_SPEEDOPT_CNT		0x0800
+#define MII_DP83867_CFG2_SPEEDOPT_INTLOW	0x2000
+#define MII_DP83867_CFG2_MASK			0x003F
+
 #define MII_MMD_CTRL	0x0d /* MMD Access Control Register */
 #define MII_MMD_DATA	0x0e /* MMD Access Data Register */
 
@@ -141,7 +155,7 @@
 
 static int dp83867_config(struct phy_device *phydev)
 {
-	unsigned int val, delay;
+	unsigned int val, delay, cfg2;
 	int ret;
 
 	/* Restart the PHY.  */
@@ -155,6 +169,29 @@
 			(FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
 		if (ret)
 			return ret;
+	} else {
+		phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
+			  (BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));
+
+		cfg2 = phy_read(phydev, phydev->addr, MII_DP83867_CFG2);
+		cfg2 &= MII_DP83867_CFG2_MASK;
+		cfg2 |= (MII_DP83867_CFG2_SPEEDOPT_10EN |
+			 MII_DP83867_CFG2_SGMII_AUTONEGEN |
+			 MII_DP83867_CFG2_SPEEDOPT_ENH |
+			 MII_DP83867_CFG2_SPEEDOPT_CNT |
+			 MII_DP83867_CFG2_SPEEDOPT_INTLOW);
+		phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG2, cfg2);
+
+		phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
+				       DP83867_DEVADDR, phydev->addr, 0x0);
+
+		phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
+			  DP83867_PHYCTRL_SGMIIEN |
+			  (DP83867_MDI_CROSSOVER_MDIX <<
+			  DP83867_MDI_CROSSOVER) |
+			  (FIFO_DEPTH << DP83867_PHYCTRL_RXFIFO_SHIFT) |
+			  (FIFO_DEPTH  << DP83867_PHYCTRL_TXFIFO_SHIFT));
+		phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_BISCR, 0x0);
 	}
 
 	if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) &&