From: Alice Guo <[email protected]>

Add support for initializing the i.MX95 XPCS in SGMII 1G mode, including
including required configuration settings.

Signed-off-by: Alice Guo <[email protected]>
---
 drivers/net/fsl_enetc_xpcs_phy.c | 550 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 550 insertions(+)

diff --git a/drivers/net/fsl_enetc_xpcs_phy.c b/drivers/net/fsl_enetc_xpcs_phy.c
index 9c1ee752a66..d8393dea151 100644
--- a/drivers/net/fsl_enetc_xpcs_phy.c
+++ b/drivers/net/fsl_enetc_xpcs_phy.c
@@ -57,6 +57,8 @@
 #define PMA_MP_16G_25G_TX_MISC_CTRL0                   0x1007C
 #define PMA_TX_MISC_CTRL0_TX0_MISC_MASK                GENMASK(7, 0)
 #define PMA_TX_MISC_CTRL0_TX0_MISC(x)          ((x) & GENMASK(7, 0))
+#define PMA_MP_12G_16G_25G_TX_STS              0x10080
+#define PMA_TX_STS_TX_ACK_0                    BIT(0)
 #define PMA_MP_12G_16G_25G_RX_GENCTRL0                 0x100A0
 #define PMA_RX_GENCTRL0_RX_DT_EN_0             BIT(8)
 #define PMA_MP_12G_16G_25G_RX_GENCTRL1                 0x100A2
@@ -102,6 +104,8 @@
 #define PMA_MP_12G_16G_25G_DFE_TAP_CTRL0               0x100BC
 #define PMA_DFE_TAP_CTRL0_DFE_TAP1_0_MASK      GENMASK(7, 0)
 #define PMA_DFE_TAP_CTRL0_DFE_TAP1_0(x)                ((x) & GENMASK(7, 0))
+#define PMA_MP_12G_16G_25G_RX_STS              0x100C0
+#define PMA_RX_STS_RX_ACK_0                    BIT(0)
 #define PMA_MP_16G_RX_CDR_CTRL1                                0x100C8
 #define PMA_RX_CDR_CTRL1_VCO_TEMP_COMP_EN_0    BIT(0)
 #define PMA_RX_CDR_CTRL1_VCO_STEP_CTRL_0       BIT(4)
@@ -198,6 +202,7 @@
 #define MII_CTRL_AN_ENABLE                     BIT(12)
 #define MII_CTRL_SS13                          BIT(13)
 #define MII_DIG_CTRL1                                  0x10000
+#define MII_DIG_CTRL1_EN_2_5G_MODE             BIT(2)
 #define MII_DIG_CTRL1_CL37_TMR_OVR_RIDE                BIT(3)
 #define MII_AN_CTRL                                    0x10002
 #define MII_AN_CTRL_MII_AN_INTR_EN             BIT(0)
@@ -349,6 +354,39 @@ static int xpcs_phy_common_init_seq_1_pma(struct udevice 
*dev)
                mdelay(10);
        } while (val & PMA_RX_GENCTRL2_RX_REQ_0);
 
+       mdelay(1);
+
+       /* Deassert TX_REQ and RX_REQ */
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+       val &= ~PMA_TX_GENCTRL2_TX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+       val &= ~PMA_RX_GENCTRL2_RX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+       /* Poll TX_ACK == 0 */
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_STS);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_TX_STS_TX_ACK_0);
+
+       /* Poll RX_ACK == 0 */
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_STS);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_RX_STS_RX_ACK_0);
+
        return 0;
 
 timeout:
@@ -484,6 +522,190 @@ timeout:
        return -ETIMEDOUT;
 }
 
+static int xpcs_phy_common_init_seq_2_pma(struct udevice *dev, bool an)
+{
+       ulong begin;
+       u16 val;
+
+       val = xpcs_read(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL));
+       if (an)
+               val |= MII_CTRL_AN_ENABLE;
+       else
+               val &= ~MII_CTRL_AN_ENABLE;
+       xpcs_write(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL), val);
+
+       val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL));
+       val |= PCS_DEBUG_CTRL_TX_PMBL_CTL;
+       xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL), val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL);
+       val = u16_replace_bits(val, 2, PMA_POWER_STATE_CTRL_TX0_PSTATE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL);
+       val |= PMA_MPLL_CMN_CTRL_MPLL_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL, val);
+
+       mdelay(1);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+       val |= PMA_TX_GENCTRL2_TX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+       val |= PMA_RX_GENCTRL2_RX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_RX_GENCTRL2_RX_REQ_0);
+
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_TX_GENCTRL2_TX_REQ_0);
+
+       mdelay(1);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+       val &= ~PMA_TX_GENCTRL2_TX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+       val &= ~PMA_RX_GENCTRL2_RX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_STS);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_TX_STS_TX_ACK_0);
+
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_STS);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_RX_STS_RX_ACK_0);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL);
+       val = u16_replace_bits(val, 0, PMA_POWER_STATE_CTRL_TX0_PSTATE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0);
+       val &= ~PMA_TX_GENCTRL0_TX_RST_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL);
+       val &= ~PMA_POWER_STATE_CTRL_TX_DISABLE_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL);
+       val |= PMA_MPLL_CMN_CTRL_MPLL_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+       val &= ~PMA_RX_GENCTRL1_RX_RST_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL);
+       val &= ~PMA_RX_POWER_STATE_CTRL_RX_DISABLE_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL);
+       val = u16_replace_bits(val, 0, PMA_RX_POWER_STATE_CTRL_RX0_PSTATE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0);
+       val |= PMA_TX_GENCTRL0_TX_DT_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL0);
+       val |= PMA_RX_GENCTRL0_RX_DT_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+       val |= PMA_TX_GENCTRL2_TX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+       val |= PMA_RX_GENCTRL2_RX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_RX_GENCTRL2_RX_REQ_0);
+
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_TX_GENCTRL2_TX_REQ_0);
+
+       mdelay(1);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+       val &= ~PMA_TX_GENCTRL2_TX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+       val &= ~PMA_RX_GENCTRL2_RX_REQ_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_STS);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_TX_STS_TX_ACK_0);
+
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_STS);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PMA_RX_STS_RX_ACK_0);
+
+       return 0;
+
+timeout:
+       return -ETIMEDOUT;
+}
+
 void xpcs_phy_reg_lock(struct udevice *dev)
 {
        u16 val;
@@ -961,6 +1183,334 @@ timeout:
        return -ETIMEDOUT;
 }
 
+static int imx95_xpcs_phy_mplla_configuration_sgmii(struct udevice *dev)
+{
+       ulong begin;
+       u16 val;
+
+       /* 2 Config MPLL for SGMII */
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL);
+       val = u16_replace_bits(val, 0x6, PMA_REF_CLK_CTRL_REF_RANGE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL);
+       val &= ~PMA_REF_CLK_CTRL_REF_CLK_DIV2;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL);
+       val |= PMA_REF_CLK_CTRL_REF_MPLLA_DIV2;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+       val &= ~PMA_MPLLA_CTRL2_MPLLA_DIV8_CLK_EN;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+       val |= PMA_MPLLA_CTRL2_MPLLA_DIV10_CLK_EN;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+       val &= ~PMA_MPLLA_CTRL2_MPLLA_DIV16P5_CLK_EN;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+       val = u16_replace_bits(val, 0, PMA_MPLLA_CTRL2_MPLLA_TX_CLK_DIV_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+       val |= PMA_MPLLA_CTRL2_MPLLA_DIV_CLK_EN;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+       val = u16_replace_bits(val, 0x14, PMA_MPLLA_CTRL2_MPLLA_DIV_MULT_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL1);
+       val &= ~PMA_MPLLA_CTRL1_MPLLA_SSC_EN;
+       xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL1);
+       val &= ~PMA_MPLLA_CTRL1_MPLLA_SSC_CLK_SEL;
+       xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL5);
+       val = u16_replace_bits(val, 0, 
PMA_MPLLA_CTRL5_MPLLA_SSC_FRQ_CNT_PK_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL5, val);
+
+       xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL4, 0);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL5);
+       val &= ~PMA_MPLLA_CTRL5_MPLLA_SSC_SPD_EN;
+       xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL5, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL1);
+       val &= ~PMA_MPLLA_CTRL1_MPLLA_FRACN_CTRL_MASK;
+       xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL0);
+       val = u16_replace_bits(val, 0x20, 
PMA_MPLLA_CTRL0_MPLLA_MULTIPLIER_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+       val = u16_replace_bits(val, 0x5, PMA_TX_GENCTRL1_VBOOST_LVL_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+       val = PMA_MPLLA_CTRL3_MPLLA_BANDWIDTH(0xA035);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL3, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MISC_CTRL0);
+       val = u16_replace_bits(val, 0x11, PMA_MISC_CTRL0_RX_VREF_CTRL_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MISC_CTRL0, val);
+
+       val = PMA_MISC_CTRL2_SUP_MISC(1);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_MISC_CTRL2, val);
+
+       val = PMA_VCO_CAL_REF0_VCO_REF_LD_0(0x2a);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_VCO_CAL_REF0, val);
+
+       val = PMA_VCO_CAL_LD0_VCO_LD_VAL_0(0x540);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_VCO_CAL_LD0, val);
+
+       val = PMA_RX_PPM_CTRL0_RX0_CDR_PPM_MAX(0x12);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_PPM_CTRL0, val);
+
+       /* 3 Configure LANE0 for 1G SGMII */
+       val = PMA_TX_MISC_CTRL0_TX0_MISC(0x0);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_TX_MISC_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_RATE_CTRL);
+       val = u16_replace_bits(val, 0x3, PMA_TX_RATE_CTRL_TX0_RATE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_RATE_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL);
+       val &= ~PMA_MPLL_CMN_CTRL_MPLLB_SEL_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+       val = u16_replace_bits(val, 0x1, PMA_TX_GENCTRL2_TX0_WIDTH_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+       val |= PMA_TX_GENCTRL1_VBOOST_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+       val = PMA_TX_BOOST_CTRL_TX0_IBOOST(0xf);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_BOOST_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0x0, PMA_TX_EQ_CTRL0_TX_EQ_PRE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL1);
+       val = u16_replace_bits(val, 0x0, PMA_TX_EQ_CTRL1_TX_EQ_POST_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0x28, PMA_TX_EQ_CTRL0_TX_EQ_MAIN_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_RATE_CTRL);
+       val = u16_replace_bits(val, 0x3, PMA_RX_RATE_CTRL_RX0_RATE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_RATE_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0, PMA_RX_EQ_CTRL0_CTLE_POLE_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0x12, PMA_RX_EQ_CTRL0_CTLE_BOOST_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL3);
+       val = u16_replace_bits(val, 0x1, PMA_RX_GENCTRL3_LOS_TRSHLD_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL3, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+       val |= PMA_RX_CDR_CTRL1_VCO_STEP_CTRL_0;
+       xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+       val |= PMA_RX_CDR_CTRL1_VCO_TEMP_COMP_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+       val = PMA_RX_MISC_CTRL0_RX0_MISC(0x16);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_MISC_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+       val = u16_replace_bits(val, 0x1, PMA_RX_GENCTRL2_RX0_WIDTH_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+       val &= ~PMA_RX_GENCTRL1_RX_DIV16P5_CLK_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_CDR_CTRL);
+       val &= ~PMA_RX_CDR_CTRL_CDR_SSC_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_CDR_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL3);
+       val &= ~PMA_RX_GENCTRL3_LOS_LFPS_EN_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL3, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_GENCTRL4);
+       val |= PMA_RX_GENCTRL4_RX_DFE_BYP_0;
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_GENCTRL4, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_ATTN_CTRL);
+       val = u16_replace_bits(val, 0x0, PMA_RX_ATTN_CTRL_RX0_EQ_ATT_LVL_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_ATTN_CTRL, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0x4, PMA_RX_EQ_CTRL0_VGA1_GAIN_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0x4, PMA_RX_EQ_CTRL0_VGA2_GAIN_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_DFE_TAP_CTRL0);
+       val = u16_replace_bits(val, 0x0, PMA_DFE_TAP_CTRL0_DFE_TAP1_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_DFE_TAP_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+       val = u16_replace_bits(val, 0x1, PMA_RX_CDR_CTRL1_VCO_FRQBAND_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+       val |= PMA_RX_GENCTRL1_RX_TERM_ACDC_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_IQ_CTRL0);
+       val = u16_replace_bits(val, 0x0, PMA_RX_IQ_CTRL0_RX0_DELTA_IQ_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_IQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5);
+       val &= ~PMA_RX_EQ_CTRL5_RX_ADPT_SEL_0;
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5);
+       val = u16_replace_bits(val, 0x0, PMA_RX_EQ_CTRL5_RX0_ADPT_MODE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5, val);
+
+       /* 4 Configure XPCS for 1G SGMII */
+       xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_CTRL2),
+                  PCS_CTRL2_PCS_TYPE_SEL(0x1));
+
+       val = xpcs_read(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_DIG_CTRL1));
+       val &= ~MII_DIG_CTRL1_EN_2_5G_MODE;
+       xpcs_write(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_DIG_CTRL1), val);
+
+       val = xpcs_read(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL));
+       val &= ~MII_CTRL_SS13;
+       xpcs_write(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL), val);
+
+       val = xpcs_read(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL));
+       val |= MII_CTRL_SS6;
+       xpcs_write(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL), val);
+
+       /* Section 4 register re-configuration (align with Linux kernel) */
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_EQ_CTRL4);
+       val &= ~PMA_RX_EQ_CTRL4_CONT_ADAPT_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_EQ_CTRL4, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0x6, PMA_RX_EQ_CTRL0_CTLE_BOOST_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+       val = u16_replace_bits(val, 0x1, PMA_RX_CDR_CTRL1_VCO_FRQBAND_0_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+       val = PMA_RX_MISC_CTRL0_RX0_MISC(0x6);
+       xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_MISC_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+       val &= ~PMA_TX_GENCTRL1_TX_CLK_RDY_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+       /* 4.1 Assert soft reset */
+       val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DIG_CTRL1));
+       val |= PCS_DIG_CTRL1_VR_RST;
+       xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DIG_CTRL1), val);
+
+       /* 4.2 Poll for SRAM initialization done */
+       begin = get_timer(0);
+       do {
+               val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_SRAM);
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (!(val & PMA_SRAM_INIT_DN));
+
+       /* 4.3 Assert SRAM external loading done */
+       xpcs_phy_write(dev, XPCS_PHY_GLOBAL, XPCS_PHY_REG(GLOBAL_CTRL_EX_0),
+                      GLOBAL_CTRL_EX_0_PHY_SRAM_BYPASS);
+
+       /* 4.4 Poll for vendor-specific soft reset */
+       begin = get_timer(0);
+       do {
+               val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DIG_CTRL1));
+               if (get_timer(begin) > 500) {
+                       dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+                       goto timeout;
+               }
+               mdelay(10);
+       } while (val & PCS_DIG_CTRL1_VR_RST);
+
+       /* 4.5 Assert TX0 clock active and stable */
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+       val |= PMA_TX_GENCTRL1_TX_CLK_RDY_0;
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0, PMA_TX_EQ_CTRL0_TX_EQ_PRE_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0);
+       val = u16_replace_bits(val, 0x28, PMA_TX_EQ_CTRL0_TX_EQ_MAIN_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0, val);
+
+       val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL1);
+       val = u16_replace_bits(val, 0x0, PMA_TX_EQ_CTRL1_TX_EQ_POST_MASK);
+       xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL1, val);
+
+       val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL));
+       val &= ~PCS_DEBUG_CTRL_SUPRESS_LOS_DET;
+       xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL), val);
+
+       val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL));
+       val &= ~PCS_DEBUG_CTRL_RX_DT_EN_CTL;
+       xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL), val);
+
+       return 0;
+
+timeout:
+       return -ETIMEDOUT;
+}
+
+int imx95_xpcs_phy_sgmii_1g_config(struct udevice *dev)
+{
+       int ret;
+
+       xpcs_phy_reg_lock(dev);
+
+       ret = xpcs_phy_common_init_seq_1_pma(dev);
+       if (ret)
+               return ret;
+
+       ret = imx95_xpcs_phy_mplla_configuration_sgmii(dev);
+       if (ret)
+               return ret;
+
+       ret = xpcs_phy_common_init_seq_2_pma(dev, true);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 u32 xpcs_phy_get_id(struct udevice *dev)
 {
        int ret;

-- 
2.34.1

Reply via email to