From: Alice Guo <[email protected]>
Add support for initializing the i.MX95 ENET_PHY to 1G SGMII mode. The
initialization sequence is implemented according to i.MX95 Reference
Manual Revision: 5 (2026-03-30).
Signed-off-by: Alice Guo <[email protected]>
---
drivers/net/fsl_enetc_xpcs_phy.c | 521 +++++++++++++++++++++++++++++++++++++++
1 file changed, 521 insertions(+)
diff --git a/drivers/net/fsl_enetc_xpcs_phy.c b/drivers/net/fsl_enetc_xpcs_phy.c
index 006a2bd2238..e7fed59a0cd 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)
@@ -959,6 +964,522 @@ 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 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, 0x3, 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_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);
+
+ 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 = 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_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);
+
+ 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));
+
+ /* 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.3 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.4 Assert TX0 clock is 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;
+}
+
+static int xpcs_phy_common_init_seq_2(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;
+}
+
+int imx95_xpcs_phy_sgmii_1g_config(struct udevice *dev)
+{
+ int ret;
+
+ xpcs_phy_reg_lock(dev);
+
+ ret = xpcs_phy_common_init_seq_1(dev);
+ if (ret)
+ return ret;
+
+ ret = imx95_xpcs_phy_mplla_configuration_sgmii(dev);
+ if (ret)
+ return ret;
+
+ ret = xpcs_phy_common_init_seq_2(dev, true);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int xpcs_phy_sgmii_1g_config(struct udevice *dev)
+{
+ if (is_imx95())
+ return imx95_xpcs_phy_sgmii_1g_config(dev);
+
+ dev_dbg(dev, "SGMII 1G config skipped\n");
+ return -ENODEV;
+}
+
u32 xpcs_phy_get_id(struct udevice *dev)
{
int ret;
--
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.