net: phy: dp83867: Add SGMII mode type switching
[oweals/u-boot.git] / drivers / net / phy / dp83867.c
index a43793cd4274040fc75014c861a5614d6632ad1e..50804c130efd1d87d4b326260a16c5106cccc8b8 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <common.h>
 #include <phy.h>
+#include <dm/devres.h>
 #include <linux/compat.h>
 #include <malloc.h>
 
@@ -28,6 +29,7 @@
 #define DP83867_STRAP_STS2     0x006f
 #define DP83867_RGMIIDCTL      0x0086
 #define DP83867_IO_MUX_CFG     0x0170
+#define DP83867_SGMIICTL       0x00D3
 
 #define DP83867_SW_RESET       BIT(15)
 #define DP83867_SW_RESTART     BIT(14)
@@ -64,6 +66,7 @@
 #define DP83867_PHYCR_FIFO_DEPTH_SHIFT         14
 #define DP83867_PHYCR_FIFO_DEPTH_MASK          GENMASK(15, 14)
 #define DP83867_PHYCR_RESERVED_MASK    BIT(11)
+#define DP83867_PHYCR_FORCE_LINK_GOOD  BIT(10)
 #define DP83867_MDI_CROSSOVER          5
 #define DP83867_MDI_CROSSOVER_MDIX     2
 #define DP83867_PHYCTRL_SGMIIEN                        0x0800
 /* CFG4 bits */
 #define DP83867_CFG4_PORT_MIRROR_EN            BIT(0)
 
+/* SGMIICTL bits */
+#define DP83867_SGMII_TYPE                     BIT(14)
+
 enum {
        DP83867_PORT_MIRRORING_KEEP,
        DP83867_PORT_MIRRORING_EN,
@@ -114,6 +120,7 @@ struct dp83867_private {
        int port_mirroring;
        bool set_clk_output;
        unsigned int clk_output_sel;
+       bool sgmii_ref_clk_en;
 };
 
 static int dp83867_config_port_mirroring(struct phy_device *phydev)
@@ -234,6 +241,9 @@ static int dp83867_of_init(struct phy_device *phydev)
        if (ofnode_read_bool(node, "enet-phy-lane-no-swap"))
                dp83867->port_mirroring = DP83867_PORT_MIRRORING_DIS;
 
+       if (ofnode_read_bool(node, "ti,sgmii-ref-clock-output-enable"))
+               dp83867->sgmii_ref_clk_en = true;
+
        return 0;
 }
 #else
@@ -283,6 +293,9 @@ static int dp83867_config(struct phy_device *phydev)
                val &= ~DP83867_PHYCR_FIFO_DEPTH_MASK;
                val |= (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT);
 
+               /* Do not force link good */
+               val &= ~DP83867_PHYCR_FORCE_LINK_GOOD;
+
                /* The code below checks if "port mirroring" N/A MODE4 has been
                 * enabled during power on bootstrap.
                 *
@@ -326,6 +339,10 @@ static int dp83867_config(struct phy_device *phydev)
        }
 
        if (phy_interface_is_sgmii(phydev)) {
+               if (dp83867->sgmii_ref_clk_en)
+                       phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL,
+                                     DP83867_SGMII_TYPE);
+
                phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
                          (BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));