Subject: [PATCH v3 00/15] PHY: Add support for multilink configurations in Cadence Sierra PHY driver

Cadence Sierra PHY is a multiprotocol PHY supporting different multilink
PHY configurations. This patch series extends functionality of Sierra PHY
driver by adding features like support for multilink multiprotocol
configurations, derived reference clock etc.

The changes have been validated on TI J721E platform.

Version History:

v3:
- Rebased on latest PHY next
- Added Reviewed-by and Acked-by tags

v2:
- Added a new patch 3/15 to rename the SSC macros for dt-bindings
to use generic names. These macros are not yet used in any DTS file.

Swapnil Jakhade (15):
phy: cadence: Sierra: Use of_device_get_match_data() to get driver
data
phy: cadence: Sierra: Prepare driver to add support for multilink
configurations
dt-bindings: phy: cadence-torrent: Rename SSC macros to use generic
names
dt-bindings: phy: cadence-sierra: Add binding to specify SSC mode
phy: cadence: Sierra: Add support to get SSC type from device tree
phy: cadence: Sierra: Rename some regmap variables to be in sync with
Sierra documentation
phy: cadence: Sierra: Add PHY PCS common register configurations
phy: cadence: Sierra: Check cmn_ready assertion during PHY power on
phy: cadence: Sierra: Check PIPE mode PHY status to be ready for
operation
phy: cadence: Sierra: Update single link PCIe register configuration
phy: cadence: Sierra: Fix to get correct parent for mux clocks
phy: cadence: Sierra: Add support for PHY multilink configurations
phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration
dt-bindings: phy: cadence-sierra: Add clock ID for derived reference
clock
phy: cadence: Sierra: Add support for derived reference clock output

.../bindings/phy/phy-cadence-sierra.yaml | 9 +
.../bindings/phy/phy-cadence-torrent.yaml | 4 +-
drivers/phy/cadence/phy-cadence-sierra.c | 1299 +++++++++++++++--
include/dt-bindings/phy/phy-cadence.h | 9 +-
4 files changed, 1226 insertions(+), 95 deletions(-)

--
2.26.1


Subject: [PATCH v3 03/15] dt-bindings: phy: cadence-torrent: Rename SSC macros to use generic names

Rename SSC macros to use generic names instead of PHY specific names,
so that they can be used to specify SSC modes for both Torrent and
Sierra. Renaming the macros should not affect the things as these are
not being used in any DTS file yet.

Signed-off-by: Swapnil Jakhade <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
.../devicetree/bindings/phy/phy-cadence-torrent.yaml | 4 ++--
include/dt-bindings/phy/phy-cadence.h | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
index bd9ae11c9994..2fec9e54ad0e 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
@@ -202,7 +202,7 @@ examples:
#phy-cells = <0>;
cdns,phy-type = <PHY_TYPE_PCIE>;
cdns,num-lanes = <2>;
- cdns,ssc-mode = <TORRENT_SERDES_NO_SSC>;
+ cdns,ssc-mode = <CDNS_SERDES_NO_SSC>;
};

phy@2 {
@@ -211,7 +211,7 @@ examples:
#phy-cells = <0>;
cdns,phy-type = <PHY_TYPE_SGMII>;
cdns,num-lanes = <1>;
- cdns,ssc-mode = <TORRENT_SERDES_NO_SSC>;
+ cdns,ssc-mode = <CDNS_SERDES_NO_SSC>;
};
};
};
diff --git a/include/dt-bindings/phy/phy-cadence.h b/include/dt-bindings/phy/phy-cadence.h
index 24fdc9e11bd6..d55fe6e6b936 100644
--- a/include/dt-bindings/phy/phy-cadence.h
+++ b/include/dt-bindings/phy/phy-cadence.h
@@ -6,11 +6,11 @@
#ifndef _DT_BINDINGS_CADENCE_SERDES_H
#define _DT_BINDINGS_CADENCE_SERDES_H

-/* Torrent */
-#define TORRENT_SERDES_NO_SSC 0
-#define TORRENT_SERDES_EXTERNAL_SSC 1
-#define TORRENT_SERDES_INTERNAL_SSC 2
+#define CDNS_SERDES_NO_SSC 0
+#define CDNS_SERDES_EXTERNAL_SSC 1
+#define CDNS_SERDES_INTERNAL_SSC 2

+/* Torrent */
#define CDNS_TORRENT_REFCLK_DRIVER 0
#define CDNS_TORRENT_DERIVED_REFCLK 1
#define CDNS_TORRENT_RECEIVED_REFCLK 2
--
2.26.1

Subject: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

Add register sequences for PCIe + QSGMII PHY multilink configuration.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 377 ++++++++++++++++++++++-
1 file changed, 376 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index a39be67424a1..0deb627845b1 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -45,6 +45,9 @@
#define SIERRA_CMN_REFRCV_PREG 0x98
#define SIERRA_CMN_REFRCV1_PREG 0xB8
#define SIERRA_CMN_PLLLC1_GEN_PREG 0xC2
+#define SIERRA_CMN_PLLLC1_LF_COEFF_MODE0_PREG 0xCA
+#define SIERRA_CMN_PLLLC1_BWCAL_MODE0_PREG 0xD0
+#define SIERRA_CMN_PLLLC1_SS_TIME_STEPSIZE_MODE_PREG 0xE2

#define SIERRA_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \
((0x4000 << (block_offset)) + \
@@ -59,6 +62,9 @@
#define SIERRA_PSM_A0IN_TMR_PREG 0x009
#define SIERRA_PSM_A3IN_TMR_PREG 0x00C
#define SIERRA_PSM_DIAG_PREG 0x015
+#define SIERRA_PSC_LN_A3_PREG 0x023
+#define SIERRA_PSC_LN_A4_PREG 0x024
+#define SIERRA_PSC_LN_IDLE_PREG 0x026
#define SIERRA_PSC_TX_A0_PREG 0x028
#define SIERRA_PSC_TX_A1_PREG 0x029
#define SIERRA_PSC_TX_A2_PREG 0x02A
@@ -68,6 +74,7 @@
#define SIERRA_PSC_RX_A2_PREG 0x032
#define SIERRA_PSC_RX_A3_PREG 0x033
#define SIERRA_PLLCTRL_SUBRATE_PREG 0x03A
+#define SIERRA_PLLCTRL_GEN_A_PREG 0x03B
#define SIERRA_PLLCTRL_GEN_D_PREG 0x03E
#define SIERRA_PLLCTRL_CPGAIN_MODE_PREG 0x03F
#define SIERRA_PLLCTRL_STATUS_PREG 0x044
@@ -150,6 +157,7 @@
#define SIERRA_CPICAL_TMRVAL_MODE0_PREG 0x171
#define SIERRA_CPICAL_PICNT_MODE1_PREG 0x174
#define SIERRA_CPI_OUTBUF_RATESEL_PREG 0x17C
+#define SIERRA_CPI_RESBIAS_BIN_PREG 0x17E
#define SIERRA_CPI_TRIM_PREG 0x17F
#define SIERRA_CPICAL_RES_STARTCODE_MODE23_PREG 0x183
#define SIERRA_EPI_CTRL_PREG 0x187
@@ -272,7 +280,8 @@ static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
enum cdns_sierra_phy_type {
TYPE_NONE,
TYPE_PCIE,
- TYPE_USB
+ TYPE_USB,
+ TYPE_QSGMII
};

enum cdns_sierra_ssc_mode {
@@ -807,6 +816,9 @@ static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
case PHY_TYPE_USB3:
inst->phy_type = TYPE_USB;
break;
+ case PHY_TYPE_QSGMII:
+ inst->phy_type = TYPE_QSGMII;
+ break;
default:
return -EINVAL;
}
@@ -1186,6 +1198,9 @@ static int cdns_sierra_phy_configure_multilink(struct cdns_sierra_phy *sp)
regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val);
}
}
+
+ if (phy_t1 == TYPE_QSGMII)
+ reset_control_deassert(sp->phys[node].lnk_rst);
}

/* Take the PHY out of reset */
@@ -1363,6 +1378,72 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev)
return 0;
}

+/* QSGMII PHY PMA lane configuration */
+static struct cdns_reg_pairs qsgmii_phy_pma_ln_regs[] = {
+ {0x9010, SIERRA_PHY_PMA_XCVR_CTRL}
+};
+
+static struct cdns_sierra_vals qsgmii_phy_pma_ln_vals = {
+ .reg_pairs = qsgmii_phy_pma_ln_regs,
+ .num_regs = ARRAY_SIZE(qsgmii_phy_pma_ln_regs),
+};
+
+/* QSGMII refclk 100MHz, 20b, opt1, No BW cal, no ssc, PLL LC1 */
+static const struct cdns_reg_pairs qsgmii_100_no_ssc_plllc1_cmn_regs[] = {
+ {0x2085, SIERRA_CMN_PLLLC1_LF_COEFF_MODE0_PREG},
+ {0x0000, SIERRA_CMN_PLLLC1_BWCAL_MODE0_PREG},
+ {0x0000, SIERRA_CMN_PLLLC1_SS_TIME_STEPSIZE_MODE_PREG}
+};
+
+static const struct cdns_reg_pairs qsgmii_100_no_ssc_plllc1_ln_regs[] = {
+ {0xFC08, SIERRA_DET_STANDEC_A_PREG},
+ {0x0252, SIERRA_DET_STANDEC_E_PREG},
+ {0x0004, SIERRA_PSC_LN_IDLE_PREG},
+ {0x0FFE, SIERRA_PSC_RX_A0_PREG},
+ {0x0011, SIERRA_PLLCTRL_SUBRATE_PREG},
+ {0x0001, SIERRA_PLLCTRL_GEN_A_PREG},
+ {0x5233, SIERRA_PLLCTRL_CPGAIN_MODE_PREG},
+ {0x0000, SIERRA_DRVCTRL_ATTEN_PREG},
+ {0x0089, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
+ {0x3C3C, SIERRA_CREQ_CCLKDET_MODE01_PREG},
+ {0x3222, SIERRA_CREQ_FSMCLK_SEL_PREG},
+ {0x0000, SIERRA_CREQ_EQ_CTRL_PREG},
+ {0x8422, SIERRA_CTLELUT_CTRL_PREG},
+ {0x4111, SIERRA_DFE_ECMP_RATESEL_PREG},
+ {0x4111, SIERRA_DFE_SMP_RATESEL_PREG},
+ {0x0002, SIERRA_DEQ_PHALIGN_CTRL},
+ {0x9595, SIERRA_DEQ_VGATUNE_CTRL_PREG},
+ {0x0186, SIERRA_DEQ_GLUT0},
+ {0x0186, SIERRA_DEQ_GLUT1},
+ {0x0186, SIERRA_DEQ_GLUT2},
+ {0x0186, SIERRA_DEQ_GLUT3},
+ {0x0186, SIERRA_DEQ_GLUT4},
+ {0x0861, SIERRA_DEQ_ALUT0},
+ {0x07E0, SIERRA_DEQ_ALUT1},
+ {0x079E, SIERRA_DEQ_ALUT2},
+ {0x071D, SIERRA_DEQ_ALUT3},
+ {0x03F5, SIERRA_DEQ_DFETAP_CTRL_PREG},
+ {0x0C01, SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG},
+ {0x3C40, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
+ {0x1C04, SIERRA_DEQ_TAU_CTRL2_PREG},
+ {0x0033, SIERRA_DEQ_PICTRL_PREG},
+ {0x0660, SIERRA_CPICAL_TMRVAL_MODE0_PREG},
+ {0x00D5, SIERRA_CPI_OUTBUF_RATESEL_PREG},
+ {0x0B6D, SIERRA_CPI_RESBIAS_BIN_PREG},
+ {0x0102, SIERRA_RXBUFFER_CTLECTRL_PREG},
+ {0x0002, SIERRA_RXBUFFER_RCDFECTRL_PREG}
+};
+
+static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_cmn_vals = {
+ .reg_pairs = qsgmii_100_no_ssc_plllc1_cmn_regs,
+ .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_cmn_regs),
+};
+
+static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_ln_vals = {
+ .reg_pairs = qsgmii_100_no_ssc_plllc1_ln_regs,
+ .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_ln_regs),
+};
+
/* PCIE PHY PCS common configuration */
static struct cdns_reg_pairs pcie_phy_pcs_cmn_regs[] = {
{0x0430, SIERRA_PHY_PIPE_CMN_CTRL1}
@@ -1373,6 +1454,233 @@ static struct cdns_sierra_vals pcie_phy_pcs_cmn_vals = {
.num_regs = ARRAY_SIZE(pcie_phy_pcs_cmn_regs),
};

+/* refclk100MHz_32b_PCIe_cmn_pll_no_ssc, pcie_links_using_plllc, pipe_bw_3 */
+static const struct cdns_reg_pairs pcie_100_no_ssc_plllc_cmn_regs[] = {
+ {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
+ {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
+ {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
+ {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG}
+};
+
+/*
+ * refclk100MHz_32b_PCIe_ln_no_ssc, multilink, using_plllc,
+ * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz
+ */
+static const struct cdns_reg_pairs ml_pcie_100_no_ssc_ln_regs[] = {
+ {0xFC08, SIERRA_DET_STANDEC_A_PREG},
+ {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
+ {0x0004, SIERRA_PSC_LN_A3_PREG},
+ {0x0004, SIERRA_PSC_LN_A4_PREG},
+ {0x0004, SIERRA_PSC_LN_IDLE_PREG},
+ {0x1555, SIERRA_DFE_BIASTRIM_PREG},
+ {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
+ {0x8055, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
+ {0x80BB, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
+ {0x8351, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
+ {0x8349, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
+ {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
+ {0x9800, SIERRA_RX_CTLE_CAL_PREG},
+ {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
+ {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
+ {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
+ {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
+ {0x0041, SIERRA_DEQ_GLUT0},
+ {0x0082, SIERRA_DEQ_GLUT1},
+ {0x00C3, SIERRA_DEQ_GLUT2},
+ {0x0145, SIERRA_DEQ_GLUT3},
+ {0x0186, SIERRA_DEQ_GLUT4},
+ {0x09E7, SIERRA_DEQ_ALUT0},
+ {0x09A6, SIERRA_DEQ_ALUT1},
+ {0x0965, SIERRA_DEQ_ALUT2},
+ {0x08E3, SIERRA_DEQ_ALUT3},
+ {0x00FA, SIERRA_DEQ_DFETAP0},
+ {0x00FA, SIERRA_DEQ_DFETAP1},
+ {0x00FA, SIERRA_DEQ_DFETAP2},
+ {0x00FA, SIERRA_DEQ_DFETAP3},
+ {0x00FA, SIERRA_DEQ_DFETAP4},
+ {0x000F, SIERRA_DEQ_PRECUR_PREG},
+ {0x0280, SIERRA_DEQ_POSTCUR_PREG},
+ {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
+ {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
+ {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
+ {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
+ {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
+ {0x002B, SIERRA_CPI_TRIM_PREG},
+ {0x0003, SIERRA_EPI_CTRL_PREG},
+ {0x803F, SIERRA_SDFILT_H2L_A_PREG},
+ {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
+ {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
+ {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
+};
+
+static struct cdns_sierra_vals pcie_100_no_ssc_plllc_cmn_vals = {
+ .reg_pairs = pcie_100_no_ssc_plllc_cmn_regs,
+ .num_regs = ARRAY_SIZE(pcie_100_no_ssc_plllc_cmn_regs),
+};
+
+static struct cdns_sierra_vals ml_pcie_100_no_ssc_ln_vals = {
+ .reg_pairs = ml_pcie_100_no_ssc_ln_regs,
+ .num_regs = ARRAY_SIZE(ml_pcie_100_no_ssc_ln_regs),
+};
+
+/* refclk100MHz_32b_PCIe_cmn_pll_int_ssc, pcie_links_using_plllc, pipe_bw_3 */
+static const struct cdns_reg_pairs pcie_100_int_ssc_plllc_cmn_regs[] = {
+ {0x000E, SIERRA_CMN_PLLLC_MODE_PREG},
+ {0x4006, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
+ {0x4006, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
+ {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
+ {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
+ {0x0581, SIERRA_CMN_PLLLC_DSMCORR_PREG},
+ {0x7F80, SIERRA_CMN_PLLLC_SS_PREG},
+ {0x0041, SIERRA_CMN_PLLLC_SS_AMP_STEP_SIZE_PREG},
+ {0x0464, SIERRA_CMN_PLLLC_SSTWOPT_PREG},
+ {0x0D0D, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG},
+ {0x0060, SIERRA_CMN_PLLLC_LOCK_DELAY_CTRL_PREG}
+};
+
+/*
+ * refclk100MHz_32b_PCIe_ln_int_ssc, multilink, using_plllc,
+ * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz
+ */
+static const struct cdns_reg_pairs ml_pcie_100_int_ssc_ln_regs[] = {
+ {0xFC08, SIERRA_DET_STANDEC_A_PREG},
+ {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
+ {0x0004, SIERRA_PSC_LN_A3_PREG},
+ {0x0004, SIERRA_PSC_LN_A4_PREG},
+ {0x0004, SIERRA_PSC_LN_IDLE_PREG},
+ {0x1555, SIERRA_DFE_BIASTRIM_PREG},
+ {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
+ {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
+ {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
+ {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
+ {0x9800, SIERRA_RX_CTLE_CAL_PREG},
+ {0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
+ {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
+ {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
+ {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
+ {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
+ {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
+ {0x0041, SIERRA_DEQ_GLUT0},
+ {0x0082, SIERRA_DEQ_GLUT1},
+ {0x00C3, SIERRA_DEQ_GLUT2},
+ {0x0145, SIERRA_DEQ_GLUT3},
+ {0x0186, SIERRA_DEQ_GLUT4},
+ {0x09E7, SIERRA_DEQ_ALUT0},
+ {0x09A6, SIERRA_DEQ_ALUT1},
+ {0x0965, SIERRA_DEQ_ALUT2},
+ {0x08E3, SIERRA_DEQ_ALUT3},
+ {0x00FA, SIERRA_DEQ_DFETAP0},
+ {0x00FA, SIERRA_DEQ_DFETAP1},
+ {0x00FA, SIERRA_DEQ_DFETAP2},
+ {0x00FA, SIERRA_DEQ_DFETAP3},
+ {0x00FA, SIERRA_DEQ_DFETAP4},
+ {0x000F, SIERRA_DEQ_PRECUR_PREG},
+ {0x0280, SIERRA_DEQ_POSTCUR_PREG},
+ {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
+ {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
+ {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
+ {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
+ {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
+ {0x002B, SIERRA_CPI_TRIM_PREG},
+ {0x0003, SIERRA_EPI_CTRL_PREG},
+ {0x803F, SIERRA_SDFILT_H2L_A_PREG},
+ {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
+ {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
+ {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
+};
+
+static struct cdns_sierra_vals pcie_100_int_ssc_plllc_cmn_vals = {
+ .reg_pairs = pcie_100_int_ssc_plllc_cmn_regs,
+ .num_regs = ARRAY_SIZE(pcie_100_int_ssc_plllc_cmn_regs),
+};
+
+static struct cdns_sierra_vals ml_pcie_100_int_ssc_ln_vals = {
+ .reg_pairs = ml_pcie_100_int_ssc_ln_regs,
+ .num_regs = ARRAY_SIZE(ml_pcie_100_int_ssc_ln_regs),
+};
+
+/* refclk100MHz_32b_PCIe_cmn_pll_ext_ssc, pcie_links_using_plllc, pipe_bw_3 */
+static const struct cdns_reg_pairs pcie_100_ext_ssc_plllc_cmn_regs[] = {
+ {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
+ {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
+ {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
+ {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
+ {0x1B1B, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG}
+};
+
+/*
+ * refclk100MHz_32b_PCIe_ln_ext_ssc, multilink, using_plllc,
+ * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz
+ */
+static const struct cdns_reg_pairs ml_pcie_100_ext_ssc_ln_regs[] = {
+ {0xFC08, SIERRA_DET_STANDEC_A_PREG},
+ {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
+ {0x0004, SIERRA_PSC_LN_A3_PREG},
+ {0x0004, SIERRA_PSC_LN_A4_PREG},
+ {0x0004, SIERRA_PSC_LN_IDLE_PREG},
+ {0x1555, SIERRA_DFE_BIASTRIM_PREG},
+ {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
+ {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
+ {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
+ {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
+ {0x9800, SIERRA_RX_CTLE_CAL_PREG},
+ {0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
+ {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
+ {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
+ {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
+ {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
+ {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
+ {0x0041, SIERRA_DEQ_GLUT0},
+ {0x0082, SIERRA_DEQ_GLUT1},
+ {0x00C3, SIERRA_DEQ_GLUT2},
+ {0x0145, SIERRA_DEQ_GLUT3},
+ {0x0186, SIERRA_DEQ_GLUT4},
+ {0x09E7, SIERRA_DEQ_ALUT0},
+ {0x09A6, SIERRA_DEQ_ALUT1},
+ {0x0965, SIERRA_DEQ_ALUT2},
+ {0x08E3, SIERRA_DEQ_ALUT3},
+ {0x00FA, SIERRA_DEQ_DFETAP0},
+ {0x00FA, SIERRA_DEQ_DFETAP1},
+ {0x00FA, SIERRA_DEQ_DFETAP2},
+ {0x00FA, SIERRA_DEQ_DFETAP3},
+ {0x00FA, SIERRA_DEQ_DFETAP4},
+ {0x000F, SIERRA_DEQ_PRECUR_PREG},
+ {0x0280, SIERRA_DEQ_POSTCUR_PREG},
+ {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
+ {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
+ {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
+ {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
+ {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
+ {0x002B, SIERRA_CPI_TRIM_PREG},
+ {0x0003, SIERRA_EPI_CTRL_PREG},
+ {0x803F, SIERRA_SDFILT_H2L_A_PREG},
+ {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
+ {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
+ {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
+};
+
+static struct cdns_sierra_vals pcie_100_ext_ssc_plllc_cmn_vals = {
+ .reg_pairs = pcie_100_ext_ssc_plllc_cmn_regs,
+ .num_regs = ARRAY_SIZE(pcie_100_ext_ssc_plllc_cmn_regs),
+};
+
+static struct cdns_sierra_vals ml_pcie_100_ext_ssc_ln_vals = {
+ .reg_pairs = ml_pcie_100_ext_ssc_ln_regs,
+ .num_regs = ARRAY_SIZE(ml_pcie_100_ext_ssc_ln_regs),
+};
+
/* refclk100MHz_32b_PCIe_cmn_pll_no_ssc */
static const struct cdns_reg_pairs cdns_pcie_cmn_regs_no_ssc[] = {
{0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
@@ -1710,6 +2018,11 @@ static const struct cdns_sierra_data cdns_map_sierra = {
[EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
[INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
},
+ [TYPE_QSGMII] = {
+ [NO_SSC] = &pcie_phy_pcs_cmn_vals,
+ [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
+ [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
+ },
},
},
.pma_cmn_vals = {
@@ -1719,12 +2032,24 @@ static const struct cdns_sierra_data cdns_map_sierra = {
[EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
[INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
},
+ [TYPE_QSGMII] = {
+ [NO_SSC] = &pcie_100_no_ssc_plllc_cmn_vals,
+ [EXTERNAL_SSC] = &pcie_100_ext_ssc_plllc_cmn_vals,
+ [INTERNAL_SSC] = &pcie_100_int_ssc_plllc_cmn_vals,
+ },
},
[TYPE_USB] = {
[TYPE_NONE] = {
[EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals,
},
},
+ [TYPE_QSGMII] = {
+ [TYPE_PCIE] = {
+ [NO_SSC] = &qsgmii_100_no_ssc_plllc1_cmn_vals,
+ [EXTERNAL_SSC] = &qsgmii_100_no_ssc_plllc1_cmn_vals,
+ [INTERNAL_SSC] = &qsgmii_100_no_ssc_plllc1_cmn_vals,
+ },
+ },
},
.pma_ln_vals = {
[TYPE_PCIE] = {
@@ -1733,12 +2058,24 @@ static const struct cdns_sierra_data cdns_map_sierra = {
[EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
[INTERNAL_SSC] = &pcie_100_int_ssc_ln_vals,
},
+ [TYPE_QSGMII] = {
+ [NO_SSC] = &ml_pcie_100_no_ssc_ln_vals,
+ [EXTERNAL_SSC] = &ml_pcie_100_ext_ssc_ln_vals,
+ [INTERNAL_SSC] = &ml_pcie_100_int_ssc_ln_vals,
+ },
},
[TYPE_USB] = {
[TYPE_NONE] = {
[EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals,
},
},
+ [TYPE_QSGMII] = {
+ [TYPE_PCIE] = {
+ [NO_SSC] = &qsgmii_100_no_ssc_plllc1_ln_vals,
+ [EXTERNAL_SSC] = &qsgmii_100_no_ssc_plllc1_ln_vals,
+ [INTERNAL_SSC] = &qsgmii_100_no_ssc_plllc1_ln_vals,
+ },
+ },
},
};

@@ -1753,6 +2090,20 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = {
[EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
[INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
},
+ [TYPE_QSGMII] = {
+ [NO_SSC] = &pcie_phy_pcs_cmn_vals,
+ [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
+ [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
+ },
+ },
+ },
+ .phy_pma_ln_vals = {
+ [TYPE_QSGMII] = {
+ [TYPE_PCIE] = {
+ [NO_SSC] = &qsgmii_phy_pma_ln_vals,
+ [EXTERNAL_SSC] = &qsgmii_phy_pma_ln_vals,
+ [INTERNAL_SSC] = &qsgmii_phy_pma_ln_vals,
+ },
},
},
.pma_cmn_vals = {
@@ -1762,12 +2113,24 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = {
[EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
[INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
},
+ [TYPE_QSGMII] = {
+ [NO_SSC] = &pcie_100_no_ssc_plllc_cmn_vals,
+ [EXTERNAL_SSC] = &pcie_100_ext_ssc_plllc_cmn_vals,
+ [INTERNAL_SSC] = &pcie_100_int_ssc_plllc_cmn_vals,
+ },
},
[TYPE_USB] = {
[TYPE_NONE] = {
[EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals,
},
},
+ [TYPE_QSGMII] = {
+ [TYPE_PCIE] = {
+ [NO_SSC] = &qsgmii_100_no_ssc_plllc1_cmn_vals,
+ [EXTERNAL_SSC] = &qsgmii_100_no_ssc_plllc1_cmn_vals,
+ [INTERNAL_SSC] = &qsgmii_100_no_ssc_plllc1_cmn_vals,
+ },
+ },
},
.pma_ln_vals = {
[TYPE_PCIE] = {
@@ -1776,12 +2139,24 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = {
[EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
[INTERNAL_SSC] = &pcie_100_int_ssc_ln_vals,
},
+ [TYPE_QSGMII] = {
+ [NO_SSC] = &ml_pcie_100_no_ssc_ln_vals,
+ [EXTERNAL_SSC] = &ml_pcie_100_ext_ssc_ln_vals,
+ [INTERNAL_SSC] = &ml_pcie_100_int_ssc_ln_vals,
+ },
},
[TYPE_USB] = {
[TYPE_NONE] = {
[EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals,
},
},
+ [TYPE_QSGMII] = {
+ [TYPE_PCIE] = {
+ [NO_SSC] = &qsgmii_100_no_ssc_plllc1_ln_vals,
+ [EXTERNAL_SSC] = &qsgmii_100_no_ssc_plllc1_ln_vals,
+ [INTERNAL_SSC] = &qsgmii_100_no_ssc_plllc1_ln_vals,
+ },
+ },
},
};

--
2.26.1

Subject: [PATCH v3 09/15] phy: cadence: Sierra: Check PIPE mode PHY status to be ready for operation

PIPE phy status is used to communicate the completion of several PHY
functions. Check if PHY is ready for operation while configured for
PIPE mode during startup.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 73 +++++++++++++++++++++++-
1 file changed, 72 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 13176208e6d7..59458388a855 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -151,6 +151,13 @@
#define SIERRA_PHY_PIPE_CMN_CTRL1 0x0
#define SIERRA_PHY_PLL_CFG 0xe

+/* PHY PCS lane registers */
+#define SIERRA_PHY_PCS_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \
+ ((0xD000 << (block_offset)) + \
+ (((ln) << 8) << (reg_offset)))
+
+#define SIERRA_PHY_ISO_LINK_CTRL 0xB
+
/* PHY PMA common registers */
#define SIERRA_PHY_PMA_COMMON_OFFSET(block_offset) \
(0xE000 << (block_offset))
@@ -181,6 +188,8 @@ static const struct reg_field pma_cmn_ready =
REG_FIELD(SIERRA_PHY_PMA_CMN_CTRL, 0, 0);
static const struct reg_field pllctrl_lock =
REG_FIELD(SIERRA_PLLCTRL_STATUS_PREG, 0, 0);
+static const struct reg_field phy_iso_link_ctrl_1 =
+ REG_FIELD(SIERRA_PHY_ISO_LINK_CTRL, 1, 1);

static const char * const clk_names[] = {
[CDNS_SIERRA_PLL_CMNLC] = "pll_cmnlc",
@@ -287,12 +296,14 @@ struct cdns_sierra_phy {
struct reset_control *apb_rst;
struct regmap *regmap_lane_cdb[SIERRA_MAX_LANES];
struct regmap *regmap_phy_pcs_common_cdb;
+ struct regmap *regmap_phy_pcs_lane_cdb[SIERRA_MAX_LANES];
struct regmap *regmap_phy_pma_common_cdb;
struct regmap *regmap_common_cdb;
struct regmap_field *macro_id_type;
struct regmap_field *phy_pll_cfg_1;
struct regmap_field *pma_cmn_ready;
struct regmap_field *pllctrl_lock[SIERRA_MAX_LANES];
+ struct regmap_field *phy_iso_link_ctrl_1[SIERRA_MAX_LANES];
struct regmap_field *cmn_refrcv_refclk_plllc1en_preg[SIERRA_NUM_CMN_PLLC];
struct regmap_field *cmn_refrcv_refclk_termen_preg[SIERRA_NUM_CMN_PLLC];
struct regmap_field *cmn_plllc_pfdclk1_sel_preg[SIERRA_NUM_CMN_PLLC];
@@ -367,6 +378,34 @@ static const struct regmap_config cdns_sierra_phy_pcs_cmn_cdb_config = {
.reg_read = cdns_regmap_read,
};

+#define SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF(n) \
+{ \
+ .name = "sierra_phy_pcs_lane" n "_cdb", \
+ .reg_stride = 1, \
+ .fast_io = true, \
+ .reg_write = cdns_regmap_write, \
+ .reg_read = cdns_regmap_read, \
+}
+
+static const struct regmap_config cdns_sierra_phy_pcs_lane_cdb_config[] = {
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("0"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("1"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("2"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("3"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("4"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("5"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("6"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("7"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("8"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("9"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("10"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("11"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("12"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("13"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("14"),
+ SIERRA_PHY_PCS_LANE_CDB_REGMAP_CONF("15"),
+};
+
static const struct regmap_config cdns_sierra_phy_pma_cmn_cdb_config = {
.name = "sierra_phy_pma_cmn_cdb",
.reg_stride = 1,
@@ -452,6 +491,15 @@ static int cdns_sierra_phy_on(struct phy *gphy)
return ret;
}

+ if (ins->phy_type == TYPE_PCIE || ins->phy_type == TYPE_USB) {
+ ret = regmap_field_read_poll_timeout(sp->phy_iso_link_ctrl_1[ins->mlane],
+ val, !val, 1000, PLL_LOCK_TIME);
+ if (ret) {
+ dev_err(dev, "Timeout waiting for PHY status ready\n");
+ return ret;
+ }
+ }
+
/*
* Wait for cmn_ready assertion
* PHY_PMA_CMN_CTRL[0] == 1
@@ -755,7 +803,17 @@ static int cdns_regfield_init(struct cdns_sierra_phy *sp)
dev_err(dev, "P%d_ENABLE reg field init failed\n", i);
return PTR_ERR(field);
}
- sp->pllctrl_lock[i] = field;
+ sp->pllctrl_lock[i] = field;
+ }
+
+ for (i = 0; i < SIERRA_MAX_LANES; i++) {
+ regmap = sp->regmap_phy_pcs_lane_cdb[i];
+ field = devm_regmap_field_alloc(dev, regmap, phy_iso_link_ctrl_1);
+ if (IS_ERR(field)) {
+ dev_err(dev, "PHY_ISO_LINK_CTRL reg field init for lane %d failed\n", i);
+ return PTR_ERR(field);
+ }
+ sp->phy_iso_link_ctrl_1[i] = field;
}

return 0;
@@ -801,6 +859,19 @@ static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp,
}
sp->regmap_phy_pcs_common_cdb = regmap;

+ for (i = 0; i < SIERRA_MAX_LANES; i++) {
+ block_offset = SIERRA_PHY_PCS_LANE_CDB_OFFSET(i, block_offset_shift,
+ reg_offset_shift);
+ regmap = cdns_regmap_init(dev, base, block_offset,
+ reg_offset_shift,
+ &cdns_sierra_phy_pcs_lane_cdb_config[i]);
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "Failed to init PHY PCS lane CDB regmap\n");
+ return PTR_ERR(regmap);
+ }
+ sp->regmap_phy_pcs_lane_cdb[i] = regmap;
+ }
+
block_offset = SIERRA_PHY_PMA_COMMON_OFFSET(block_offset_shift);
regmap = cdns_regmap_init(dev, base, block_offset, reg_offset_shift,
&cdns_sierra_phy_pma_cmn_cdb_config);
--
2.26.1

Subject: [PATCH v3 08/15] phy: cadence: Sierra: Check cmn_ready assertion during PHY power on

Check if PMA cmn_ready is set indicating the startup process is complete.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 45 ++++++++++++++++++++++++
1 file changed, 45 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 0bfd13843f2e..13176208e6d7 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -151,6 +151,11 @@
#define SIERRA_PHY_PIPE_CMN_CTRL1 0x0
#define SIERRA_PHY_PLL_CFG 0xe

+/* PHY PMA common registers */
+#define SIERRA_PHY_PMA_COMMON_OFFSET(block_offset) \
+ (0xE000 << (block_offset))
+#define SIERRA_PHY_PMA_CMN_CTRL 0x000
+
#define SIERRA_MACRO_ID 0x00007364
#define SIERRA_MAX_LANES 16
#define PLL_LOCK_TIME 100000
@@ -172,6 +177,8 @@ static const struct reg_field macro_id_type =
REG_FIELD(SIERRA_MACRO_ID_REG, 0, 15);
static const struct reg_field phy_pll_cfg_1 =
REG_FIELD(SIERRA_PHY_PLL_CFG, 1, 1);
+static const struct reg_field pma_cmn_ready =
+ REG_FIELD(SIERRA_PHY_PMA_CMN_CTRL, 0, 0);
static const struct reg_field pllctrl_lock =
REG_FIELD(SIERRA_PLLCTRL_STATUS_PREG, 0, 0);

@@ -280,9 +287,11 @@ struct cdns_sierra_phy {
struct reset_control *apb_rst;
struct regmap *regmap_lane_cdb[SIERRA_MAX_LANES];
struct regmap *regmap_phy_pcs_common_cdb;
+ struct regmap *regmap_phy_pma_common_cdb;
struct regmap *regmap_common_cdb;
struct regmap_field *macro_id_type;
struct regmap_field *phy_pll_cfg_1;
+ struct regmap_field *pma_cmn_ready;
struct regmap_field *pllctrl_lock[SIERRA_MAX_LANES];
struct regmap_field *cmn_refrcv_refclk_plllc1en_preg[SIERRA_NUM_CMN_PLLC];
struct regmap_field *cmn_refrcv_refclk_termen_preg[SIERRA_NUM_CMN_PLLC];
@@ -358,6 +367,14 @@ static const struct regmap_config cdns_sierra_phy_pcs_cmn_cdb_config = {
.reg_read = cdns_regmap_read,
};

+static const struct regmap_config cdns_sierra_phy_pma_cmn_cdb_config = {
+ .name = "sierra_phy_pma_cmn_cdb",
+ .reg_stride = 1,
+ .fast_io = true,
+ .reg_write = cdns_regmap_write,
+ .reg_read = cdns_regmap_read,
+};
+
static int cdns_sierra_phy_init(struct phy *gphy)
{
struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
@@ -435,6 +452,17 @@ static int cdns_sierra_phy_on(struct phy *gphy)
return ret;
}

+ /*
+ * Wait for cmn_ready assertion
+ * PHY_PMA_CMN_CTRL[0] == 1
+ */
+ ret = regmap_field_read_poll_timeout(sp->pma_cmn_ready, val, val,
+ 1000, PLL_LOCK_TIME);
+ if (ret) {
+ dev_err(dev, "Timeout waiting for CMN ready\n");
+ return ret;
+ }
+
ret = regmap_field_read_poll_timeout(sp->pllctrl_lock[ins->mlane],
val, val, 1000, PLL_LOCK_TIME);
if (ret < 0)
@@ -712,6 +740,14 @@ static int cdns_regfield_init(struct cdns_sierra_phy *sp)
}
sp->phy_pll_cfg_1 = field;

+ regmap = sp->regmap_phy_pma_common_cdb;
+ field = devm_regmap_field_alloc(dev, regmap, pma_cmn_ready);
+ if (IS_ERR(field)) {
+ dev_err(dev, "PHY_PMA_CMN_CTRL reg field init failed\n");
+ return PTR_ERR(field);
+ }
+ sp->pma_cmn_ready = field;
+
for (i = 0; i < SIERRA_MAX_LANES; i++) {
regmap = sp->regmap_lane_cdb[i];
field = devm_regmap_field_alloc(dev, regmap, pllctrl_lock);
@@ -765,6 +801,15 @@ static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp,
}
sp->regmap_phy_pcs_common_cdb = regmap;

+ block_offset = SIERRA_PHY_PMA_COMMON_OFFSET(block_offset_shift);
+ regmap = cdns_regmap_init(dev, base, block_offset, reg_offset_shift,
+ &cdns_sierra_phy_pma_cmn_cdb_config);
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "Failed to init PHY PMA common CDB regmap\n");
+ return PTR_ERR(regmap);
+ }
+ sp->regmap_phy_pma_common_cdb = regmap;
+
return 0;
}

--
2.26.1

Subject: [PATCH v3 15/15] phy: cadence: Sierra: Add support for derived reference clock output

Sierra has derived differential reference clock output which is sourced
after the spread spectrum generation has been added. Add support to drive
derived reference clock out of serdes. Model this derived clock as a
"clock" so that platforms using this can enable it.

Sierra Main LC VCO PLL divider 1 clock is programmed to output 100MHz
clock output.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 109 ++++++++++++++++++++++-
1 file changed, 108 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 0deb627845b1..626d2d702f6c 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -34,6 +34,7 @@
#define SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG 0x49
#define SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG 0x4A
#define SIERRA_CMN_PLLLC_LOCK_CNTSTART_PREG 0x4B
+#define SIERRA_CMN_PLLLC_CLK1_PREG 0x4D
#define SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG 0x4F
#define SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG 0x50
#define SIERRA_CMN_PLLLC_DSMCORR_PREG 0x51
@@ -203,7 +204,7 @@
#define SIERRA_MAX_LANES 16
#define PLL_LOCK_TIME 100000

-#define CDNS_SIERRA_OUTPUT_CLOCKS 2
+#define CDNS_SIERRA_OUTPUT_CLOCKS 3
#define CDNS_SIERRA_INPUT_CLOCKS 5
enum cdns_sierra_clock_input {
PHY_CLK,
@@ -226,10 +227,15 @@ static const struct reg_field pllctrl_lock =
REG_FIELD(SIERRA_PLLCTRL_STATUS_PREG, 0, 0);
static const struct reg_field phy_iso_link_ctrl_1 =
REG_FIELD(SIERRA_PHY_ISO_LINK_CTRL, 1, 1);
+static const struct reg_field cmn_plllc_clk1outdiv_preg =
+ REG_FIELD(SIERRA_CMN_PLLLC_CLK1_PREG, 0, 6);
+static const struct reg_field cmn_plllc_clk1_en_preg =
+ REG_FIELD(SIERRA_CMN_PLLLC_CLK1_PREG, 12, 12);

static const char * const clk_names[] = {
[CDNS_SIERRA_PLL_CMNLC] = "pll_cmnlc",
[CDNS_SIERRA_PLL_CMNLC1] = "pll_cmnlc1",
+ [CDNS_SIERRA_DERIVED_REFCLK] = "refclk_der",
};

enum cdns_sierra_cmn_plllc {
@@ -277,6 +283,16 @@ static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
[CMN_PLLLC1] = { 1, 0 },
};

+struct cdns_sierra_derived_refclk {
+ struct clk_hw hw;
+ struct regmap_field *cmn_plllc_clk1outdiv_preg;
+ struct regmap_field *cmn_plllc_clk1_en_preg;
+ struct clk_init_data clk_data;
+};
+
+#define to_cdns_sierra_derived_refclk(_hw) \
+ container_of(_hw, struct cdns_sierra_derived_refclk, hw)
+
enum cdns_sierra_phy_type {
TYPE_NONE,
TYPE_PCIE,
@@ -766,6 +782,91 @@ static int cdns_sierra_phy_register_pll_mux(struct cdns_sierra_phy *sp)
return 0;
}

+static int cdns_sierra_derived_refclk_enable(struct clk_hw *hw)
+{
+ struct cdns_sierra_derived_refclk *derived_refclk = to_cdns_sierra_derived_refclk(hw);
+
+ regmap_field_write(derived_refclk->cmn_plllc_clk1_en_preg, 0x1);
+
+ /* Programming to get 100Mhz clock output in ref_der_clk_out 5GHz VCO/50 = 100MHz */
+ regmap_field_write(derived_refclk->cmn_plllc_clk1outdiv_preg, 0x2E);
+
+ return 0;
+}
+
+static void cdns_sierra_derived_refclk_disable(struct clk_hw *hw)
+{
+ struct cdns_sierra_derived_refclk *derived_refclk = to_cdns_sierra_derived_refclk(hw);
+
+ regmap_field_write(derived_refclk->cmn_plllc_clk1_en_preg, 0);
+}
+
+static int cdns_sierra_derived_refclk_is_enabled(struct clk_hw *hw)
+{
+ struct cdns_sierra_derived_refclk *derived_refclk = to_cdns_sierra_derived_refclk(hw);
+ int val;
+
+ regmap_field_read(derived_refclk->cmn_plllc_clk1_en_preg, &val);
+
+ return !!val;
+}
+
+static const struct clk_ops cdns_sierra_derived_refclk_ops = {
+ .enable = cdns_sierra_derived_refclk_enable,
+ .disable = cdns_sierra_derived_refclk_disable,
+ .is_enabled = cdns_sierra_derived_refclk_is_enabled,
+};
+
+static int cdns_sierra_derived_refclk_register(struct cdns_sierra_phy *sp)
+{
+ struct cdns_sierra_derived_refclk *derived_refclk;
+ struct device *dev = sp->dev;
+ struct regmap_field *field;
+ struct clk_init_data *init;
+ struct regmap *regmap;
+ char clk_name[100];
+ struct clk *clk;
+
+ derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL);
+ if (!derived_refclk)
+ return -ENOMEM;
+
+ snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev),
+ clk_names[CDNS_SIERRA_DERIVED_REFCLK]);
+
+ init = &derived_refclk->clk_data;
+
+ init->ops = &cdns_sierra_derived_refclk_ops;
+ init->flags = 0;
+ init->name = clk_name;
+
+ regmap = sp->regmap_common_cdb;
+
+ field = devm_regmap_field_alloc(dev, regmap, cmn_plllc_clk1outdiv_preg);
+ if (IS_ERR(field)) {
+ dev_err(dev, "cmn_plllc_clk1outdiv_preg reg field init failed\n");
+ return PTR_ERR(field);
+ }
+ derived_refclk->cmn_plllc_clk1outdiv_preg = field;
+
+ field = devm_regmap_field_alloc(dev, regmap, cmn_plllc_clk1_en_preg);
+ if (IS_ERR(field)) {
+ dev_err(dev, "cmn_plllc_clk1_en_preg reg field init failed\n");
+ return PTR_ERR(field);
+ }
+ derived_refclk->cmn_plllc_clk1_en_preg = field;
+
+ derived_refclk->hw.init = init;
+
+ clk = devm_clk_register(dev, &derived_refclk->hw);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ sp->output_clks[CDNS_SIERRA_DERIVED_REFCLK] = clk;
+
+ return 0;
+}
+
static void cdns_sierra_clk_unregister(struct cdns_sierra_phy *sp)
{
struct device *dev = sp->dev;
@@ -786,6 +887,12 @@ static int cdns_sierra_clk_register(struct cdns_sierra_phy *sp)
return ret;
}

+ ret = cdns_sierra_derived_refclk_register(sp);
+ if (ret) {
+ dev_err(dev, "Failed to register derived refclk\n");
+ return ret;
+ }
+
sp->clk_data.clks = sp->output_clks;
sp->clk_data.clk_num = CDNS_SIERRA_OUTPUT_CLOCKS;
ret = of_clk_add_provider(node, of_clk_src_onecell_get, &sp->clk_data);
--
2.26.1

Subject: [PATCH v3 07/15] phy: cadence: Sierra: Add PHY PCS common register configurations

Add PHY PCS common register configuration sequences for single link.
Update single link PCIe register sequence accordingly.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 38 ++++++++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 9f2b8aefee9c..0bfd13843f2e 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -148,6 +148,7 @@
/* PHY PCS common registers */
#define SIERRA_PHY_PCS_COMMON_OFFSET(block_offset) \
(0xc000 << (block_offset))
+#define SIERRA_PHY_PIPE_CMN_CTRL1 0x0
#define SIERRA_PHY_PLL_CFG 0xe

#define SIERRA_MACRO_ID 0x00007364
@@ -256,6 +257,8 @@ struct cdns_sierra_data {
u32 id_value;
u8 block_offset_shift;
u8 reg_offset_shift;
+ struct cdns_sierra_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
[NUM_SSC_MODE];
struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
@@ -364,6 +367,7 @@ static int cdns_sierra_phy_init(struct phy *gphy)
enum cdns_sierra_phy_type phy_type = ins->phy_type;
enum cdns_sierra_ssc_mode ssc = ins->ssc_mode;
const struct cdns_reg_pairs *reg_pairs;
+ struct cdns_sierra_vals *pcs_cmn_vals;
struct regmap *regmap;
u32 num_regs;
int i, j;
@@ -375,6 +379,16 @@ static int cdns_sierra_phy_init(struct phy *gphy)
clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
clk_set_rate(phy->input_clks[CMN_REFCLK1_DIG_DIV], 25000000);

+ /* PHY PCS common registers configurations */
+ pcs_cmn_vals = init_data->pcs_cmn_vals[phy_type][TYPE_NONE][ssc];
+ if (pcs_cmn_vals) {
+ reg_pairs = pcs_cmn_vals->reg_pairs;
+ num_regs = pcs_cmn_vals->num_regs;
+ regmap = phy->regmap_phy_pcs_common_cdb;
+ for (i = 0; i < num_regs; i++)
+ regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val);
+ }
+
/* PMA common registers configurations */
pma_cmn_vals = init_data->pma_cmn_vals[phy_type][TYPE_NONE][ssc];
if (pma_cmn_vals) {
@@ -1022,6 +1036,16 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev)
return 0;
}

+/* PCIE PHY PCS common configuration */
+static struct cdns_reg_pairs pcie_phy_pcs_cmn_regs[] = {
+ {0x0430, SIERRA_PHY_PIPE_CMN_CTRL1}
+};
+
+static struct cdns_sierra_vals pcie_phy_pcs_cmn_vals = {
+ .reg_pairs = pcie_phy_pcs_cmn_regs,
+ .num_regs = ARRAY_SIZE(pcie_phy_pcs_cmn_regs),
+};
+
/* refclk100MHz_32b_PCIe_cmn_pll_ext_ssc */
static const struct cdns_reg_pairs cdns_pcie_cmn_regs_ext_ssc[] = {
{0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
@@ -1173,6 +1197,13 @@ static const struct cdns_sierra_data cdns_map_sierra = {
.id_value = SIERRA_MACRO_ID,
.block_offset_shift = 0x2,
.reg_offset_shift = 0x2,
+ .pcs_cmn_vals = {
+ [TYPE_PCIE] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
+ },
+ },
+ },
.pma_cmn_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
@@ -1203,6 +1234,13 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = {
.id_value = SIERRA_MACRO_ID,
.block_offset_shift = 0x0,
.reg_offset_shift = 0x1,
+ .pcs_cmn_vals = {
+ [TYPE_PCIE] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
+ },
+ },
+ },
.pma_cmn_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
--
2.26.1

Subject: [PATCH v3 12/15] phy: cadence: Sierra: Add support for PHY multilink configurations

Add support for multilink configuration of Sierra PHY. Currently,
maximum two links are supported.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 185 ++++++++++++++++++++++-
1 file changed, 177 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index abdbc6ebd5a8..a39be67424a1 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -24,7 +24,7 @@
#include <dt-bindings/phy/phy-cadence.h>

#define NUM_SSC_MODE 3
-#define NUM_PHY_TYPE 3
+#define NUM_PHY_TYPE 4

/* PHY register offsets */
#define SIERRA_COMMON_CDB_OFFSET 0x0
@@ -184,6 +184,13 @@
(0xE000 << (block_offset))
#define SIERRA_PHY_PMA_CMN_CTRL 0x000

+/* PHY PMA lane registers */
+#define SIERRA_PHY_PMA_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \
+ ((0xF000 << (block_offset)) + \
+ (((ln) << 8) << (reg_offset)))
+
+#define SIERRA_PHY_PMA_XCVR_CTRL 0x000
+
#define SIERRA_MACRO_ID 0x00007364
#define SIERRA_MAX_LANES 16
#define PLL_LOCK_TIME 100000
@@ -299,6 +306,8 @@ struct cdns_sierra_data {
u8 reg_offset_shift;
struct cdns_sierra_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
[NUM_SSC_MODE];
+ struct cdns_sierra_vals *phy_pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
[NUM_SSC_MODE];
struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
@@ -322,6 +331,7 @@ struct cdns_sierra_phy {
struct regmap *regmap_phy_pcs_common_cdb;
struct regmap *regmap_phy_pcs_lane_cdb[SIERRA_MAX_LANES];
struct regmap *regmap_phy_pma_common_cdb;
+ struct regmap *regmap_phy_pma_lane_cdb[SIERRA_MAX_LANES];
struct regmap *regmap_common_cdb;
struct regmap_field *macro_id_type;
struct regmap_field *phy_pll_cfg_1;
@@ -438,6 +448,34 @@ static const struct regmap_config cdns_sierra_phy_pma_cmn_cdb_config = {
.reg_read = cdns_regmap_read,
};

+#define SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF(n) \
+{ \
+ .name = "sierra_phy_pma_lane" n "_cdb", \
+ .reg_stride = 1, \
+ .fast_io = true, \
+ .reg_write = cdns_regmap_write, \
+ .reg_read = cdns_regmap_read, \
+}
+
+static const struct regmap_config cdns_sierra_phy_pma_lane_cdb_config[] = {
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("0"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("1"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("2"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("3"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("4"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("5"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("6"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("7"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("8"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("9"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("10"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("11"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("12"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("13"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("14"),
+ SIERRA_PHY_PMA_LANE_CDB_REGMAP_CONF("15"),
+};
+
static int cdns_sierra_phy_init(struct phy *gphy)
{
struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
@@ -446,6 +484,7 @@ static int cdns_sierra_phy_init(struct phy *gphy)
struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
enum cdns_sierra_phy_type phy_type = ins->phy_type;
enum cdns_sierra_ssc_mode ssc = ins->ssc_mode;
+ struct cdns_sierra_vals *phy_pma_ln_vals;
const struct cdns_reg_pairs *reg_pairs;
struct cdns_sierra_vals *pcs_cmn_vals;
struct regmap *regmap;
@@ -453,7 +492,7 @@ static int cdns_sierra_phy_init(struct phy *gphy)
int i, j;

/* Initialise the PHY registers, unless auto configured */
- if (phy->autoconf)
+ if (phy->autoconf || phy->nsubnodes > 1)
return 0;

clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
@@ -469,6 +508,18 @@ static int cdns_sierra_phy_init(struct phy *gphy)
regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val);
}

+ /* PHY PMA lane registers configurations */
+ phy_pma_ln_vals = init_data->phy_pma_ln_vals[phy_type][TYPE_NONE][ssc];
+ if (phy_pma_ln_vals) {
+ reg_pairs = phy_pma_ln_vals->reg_pairs;
+ num_regs = phy_pma_ln_vals->num_regs;
+ for (i = 0; i < ins->num_lanes; i++) {
+ regmap = phy->regmap_phy_pma_lane_cdb[i + ins->mlane];
+ for (j = 0; j < num_regs; j++)
+ regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val);
+ }
+ }
+
/* PMA common registers configurations */
pma_cmn_vals = init_data->pma_cmn_vals[phy_type][TYPE_NONE][ssc];
if (pma_cmn_vals) {
@@ -502,10 +553,13 @@ static int cdns_sierra_phy_on(struct phy *gphy)
u32 val;
int ret;

- ret = reset_control_deassert(sp->phy_rst);
- if (ret) {
- dev_err(dev, "Failed to take the PHY out of reset\n");
- return ret;
+ if (sp->nsubnodes == 1) {
+ /* Take the PHY out of reset */
+ ret = reset_control_deassert(sp->phy_rst);
+ if (ret) {
+ dev_err(dev, "Failed to take the PHY out of reset\n");
+ return ret;
+ }
}

/* Take the PHY lane group out of reset */
@@ -923,6 +977,19 @@ static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp,
}
sp->regmap_phy_pma_common_cdb = regmap;

+ for (i = 0; i < SIERRA_MAX_LANES; i++) {
+ block_offset = SIERRA_PHY_PMA_LANE_CDB_OFFSET(i, block_offset_shift,
+ reg_offset_shift);
+ regmap = cdns_regmap_init(dev, base, block_offset,
+ reg_offset_shift,
+ &cdns_sierra_phy_pma_lane_cdb_config[i]);
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "Failed to init PHY PMA lane CDB regmap\n");
+ return PTR_ERR(regmap);
+ }
+ sp->regmap_phy_pma_lane_cdb[i] = regmap;
+ }
+
return 0;
}

@@ -1030,6 +1097,105 @@ static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp,
return 0;
}

+static int cdns_sierra_phy_configure_multilink(struct cdns_sierra_phy *sp)
+{
+ const struct cdns_sierra_data *init_data = sp->init_data;
+ enum cdns_sierra_phy_type phy_t1, phy_t2, tmp_phy_type;
+ struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
+ struct cdns_sierra_vals *phy_pma_ln_vals;
+ const struct cdns_reg_pairs *reg_pairs;
+ struct cdns_sierra_vals *pcs_cmn_vals;
+ int i, j, node, mlane, num_lanes, ret;
+ enum cdns_sierra_ssc_mode ssc;
+ struct regmap *regmap;
+ u32 num_regs;
+
+ /* Maximum 2 links (subnodes) are supported */
+ if (sp->nsubnodes != 2)
+ return -EINVAL;
+
+ clk_set_rate(sp->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
+ clk_set_rate(sp->input_clks[CMN_REFCLK1_DIG_DIV], 25000000);
+
+ /* PHY configured to use both PLL LC and LC1 */
+ regmap_field_write(sp->phy_pll_cfg_1, 0x1);
+
+ phy_t1 = sp->phys[0].phy_type;
+ phy_t2 = sp->phys[1].phy_type;
+
+ /*
+ * First configure the PHY for first link with phy_t1. Get the array
+ * values as [phy_t1][phy_t2][ssc].
+ */
+ for (node = 0; node < sp->nsubnodes; node++) {
+ if (node == 1) {
+ /*
+ * If first link with phy_t1 is configured, then
+ * configure the PHY for second link with phy_t2.
+ * Get the array values as [phy_t2][phy_t1][ssc].
+ */
+ tmp_phy_type = phy_t1;
+ phy_t1 = phy_t2;
+ phy_t2 = tmp_phy_type;
+ }
+
+ mlane = sp->phys[node].mlane;
+ ssc = sp->phys[node].ssc_mode;
+ num_lanes = sp->phys[node].num_lanes;
+
+ /* PHY PCS common registers configurations */
+ pcs_cmn_vals = init_data->pcs_cmn_vals[phy_t1][phy_t2][ssc];
+ if (pcs_cmn_vals) {
+ reg_pairs = pcs_cmn_vals->reg_pairs;
+ num_regs = pcs_cmn_vals->num_regs;
+ regmap = sp->regmap_phy_pcs_common_cdb;
+ for (i = 0; i < num_regs; i++)
+ regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val);
+ }
+
+ /* PHY PMA lane registers configurations */
+ phy_pma_ln_vals = init_data->phy_pma_ln_vals[phy_t1][phy_t2][ssc];
+ if (phy_pma_ln_vals) {
+ reg_pairs = phy_pma_ln_vals->reg_pairs;
+ num_regs = phy_pma_ln_vals->num_regs;
+ for (i = 0; i < num_lanes; i++) {
+ regmap = sp->regmap_phy_pma_lane_cdb[i + mlane];
+ for (j = 0; j < num_regs; j++)
+ regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val);
+ }
+ }
+
+ /* PMA common registers configurations */
+ pma_cmn_vals = init_data->pma_cmn_vals[phy_t1][phy_t2][ssc];
+ if (pma_cmn_vals) {
+ reg_pairs = pma_cmn_vals->reg_pairs;
+ num_regs = pma_cmn_vals->num_regs;
+ regmap = sp->regmap_common_cdb;
+ for (i = 0; i < num_regs; i++)
+ regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val);
+ }
+
+ /* PMA lane registers configurations */
+ pma_ln_vals = init_data->pma_ln_vals[phy_t1][phy_t2][ssc];
+ if (pma_ln_vals) {
+ reg_pairs = pma_ln_vals->reg_pairs;
+ num_regs = pma_ln_vals->num_regs;
+ for (i = 0; i < num_lanes; i++) {
+ regmap = sp->regmap_lane_cdb[i + mlane];
+ for (j = 0; j < num_regs; j++)
+ regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val);
+ }
+ }
+ }
+
+ /* Take the PHY out of reset */
+ ret = reset_control_deassert(sp->phy_rst);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int cdns_sierra_phy_probe(struct platform_device *pdev)
{
struct cdns_sierra_phy *sp;
@@ -1149,8 +1315,11 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
}

/* If more than one subnode, configure the PHY as multilink */
- if (!sp->autoconf && sp->nsubnodes > 1)
- regmap_field_write(sp->phy_pll_cfg_1, 0x1);
+ if (!sp->autoconf && sp->nsubnodes > 1) {
+ ret = cdns_sierra_phy_configure_multilink(sp);
+ if (ret)
+ goto put_child2;
+ }

pm_runtime_enable(dev);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
--
2.26.1

Subject: [PATCH v3 14/15] dt-bindings: phy: cadence-sierra: Add clock ID for derived reference clock

Add clock ID for Sierra derived reference clock.

Signed-off-by: Swapnil Jakhade <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
include/dt-bindings/phy/phy-cadence.h | 1 +
1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/phy/phy-cadence.h b/include/dt-bindings/phy/phy-cadence.h
index d55fe6e6b936..0671991208fc 100644
--- a/include/dt-bindings/phy/phy-cadence.h
+++ b/include/dt-bindings/phy/phy-cadence.h
@@ -18,5 +18,6 @@
/* Sierra */
#define CDNS_SIERRA_PLL_CMNLC 0
#define CDNS_SIERRA_PLL_CMNLC1 1
+#define CDNS_SIERRA_DERIVED_REFCLK 2

#endif /* _DT_BINDINGS_CADENCE_SERDES_H */
--
2.26.1

Subject: [PATCH v3 01/15] phy: cadence: Sierra: Use of_device_get_match_data() to get driver data

Use of_device_get_match_data() to get driver data instead of boilerplate
code.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index e93818e3991f..54d1c63932ac 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -253,7 +253,7 @@ struct cdns_regmap_cdb_context {
struct cdns_sierra_phy {
struct device *dev;
struct regmap *regmap;
- struct cdns_sierra_data *init_data;
+ const struct cdns_sierra_data *init_data;
struct cdns_sierra_inst phys[SIERRA_MAX_LANES];
struct reset_control *phy_rst;
struct reset_control *apb_rst;
@@ -595,8 +595,6 @@ static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
return 0;
}

-static const struct of_device_id cdns_sierra_id_table[];
-
static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base,
u32 block_offset, u8 reg_offset_shift,
const struct regmap_config *config)
@@ -829,8 +827,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
struct cdns_sierra_phy *sp;
struct phy_provider *phy_provider;
struct device *dev = &pdev->dev;
- const struct of_device_id *match;
- struct cdns_sierra_data *data;
+ const struct cdns_sierra_data *data;
unsigned int id_value;
int i, ret, node = 0;
void __iomem *base;
@@ -840,12 +837,10 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
return -ENODEV;

/* Get init data for this PHY */
- match = of_match_device(cdns_sierra_id_table, dev);
- if (!match)
+ data = of_device_get_match_data(dev);
+ if (!data)
return -EINVAL;

- data = (struct cdns_sierra_data *)match->data;
-
sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL);
if (!sp)
return -ENOMEM;
--
2.26.1

Subject: [PATCH v3 11/15] phy: cadence: Sierra: Fix to get correct parent for mux clocks

Fix get_parent() callback to return the correct index of the parent for
PLL_CMNLC1 clock. Add a separate table of register values corresponding
to the parent index for PLL_CMNLC1. Update set_parent() callback
accordingly.

Fixes: 28081b72859f ("phy: cadence: Sierra: Model PLL_CMNLC and PLL_CMNLC1 as clocks (mux clocks)")
Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 31 ++++++++++++++++++++----
1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 728abd14aa79..abdbc6ebd5a8 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -257,7 +257,10 @@ static const int pll_mux_parent_index[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
[CMN_PLLLC1] = { PLL1_REFCLK, PLL0_REFCLK },
};

-static u32 cdns_sierra_pll_mux_table[] = { 0, 1 };
+static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
+ [CMN_PLLLC] = { 0, 1 },
+ [CMN_PLLLC1] = { 1, 0 },
+};

enum cdns_sierra_phy_type {
TYPE_NONE,
@@ -567,11 +570,25 @@ static const struct phy_ops ops = {
static u8 cdns_sierra_pll_mux_get_parent(struct clk_hw *hw)
{
struct cdns_sierra_pll_mux *mux = to_cdns_sierra_pll_mux(hw);
+ struct regmap_field *plllc1en_field = mux->plllc1en_field;
+ struct regmap_field *termen_field = mux->termen_field;
struct regmap_field *field = mux->pfdclk_sel_preg;
unsigned int val;
+ int index;

regmap_field_read(field, &val);
- return clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table, 0, val);
+
+ if (strstr(clk_hw_get_name(hw), clk_names[CDNS_SIERRA_PLL_CMNLC1])) {
+ index = clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table[CMN_PLLLC1], 0, val);
+ if (index == 1) {
+ regmap_field_write(plllc1en_field, 1);
+ regmap_field_write(termen_field, 1);
+ }
+ } else {
+ index = clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table[CMN_PLLLC], 0, val);
+ }
+
+ return index;
}

static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index)
@@ -589,7 +606,11 @@ static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index)
ret |= regmap_field_write(termen_field, 1);
}

- val = cdns_sierra_pll_mux_table[index];
+ if (strstr(clk_hw_get_name(hw), clk_names[CDNS_SIERRA_PLL_CMNLC1]))
+ val = cdns_sierra_pll_mux_table[CMN_PLLLC1][index];
+ else
+ val = cdns_sierra_pll_mux_table[CMN_PLLLC][index];
+
ret |= regmap_field_write(field, val);

return ret;
@@ -627,8 +648,8 @@ static int cdns_sierra_pll_mux_register(struct cdns_sierra_phy *sp,
for (i = 0; i < num_parents; i++) {
clk = sp->input_clks[pll_mux_parent_index[clk_index][i]];
if (IS_ERR_OR_NULL(clk)) {
- dev_err(dev, "No parent clock for derived_refclk\n");
- return PTR_ERR(clk);
+ dev_err(dev, "No parent clock for PLL mux clocks\n");
+ return IS_ERR(clk) ? PTR_ERR(clk) : -ENOENT;
}
parent_names[i] = __clk_get_name(clk);
}
--
2.26.1

Subject: [PATCH v3 02/15] phy: cadence: Sierra: Prepare driver to add support for multilink configurations

Sierra driver currently supports single link configurations only. Prepare
driver to support multilink multiprotocol configurations along with
different SSC modes.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 195 ++++++++++++++++-------
1 file changed, 139 insertions(+), 56 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 54d1c63932ac..c82ac6716f5e 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -23,6 +23,9 @@
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/phy/phy-cadence.h>

+#define NUM_SSC_MODE 3
+#define NUM_PHY_TYPE 3
+
/* PHY register offsets */
#define SIERRA_COMMON_CDB_OFFSET 0x0
#define SIERRA_MACRO_ID_REG 0x0
@@ -217,9 +220,21 @@ static const int pll_mux_parent_index[][SIERRA_NUM_CMN_PLLC_PARENTS] = {

static u32 cdns_sierra_pll_mux_table[] = { 0, 1 };

+enum cdns_sierra_phy_type {
+ TYPE_NONE,
+ TYPE_PCIE,
+ TYPE_USB
+};
+
+enum cdns_sierra_ssc_mode {
+ NO_SSC,
+ EXTERNAL_SSC,
+ INTERNAL_SSC
+};
+
struct cdns_sierra_inst {
struct phy *phy;
- u32 phy_type;
+ enum cdns_sierra_phy_type phy_type;
u32 num_lanes;
u32 mlane;
struct reset_control *lnk_rst;
@@ -230,18 +245,19 @@ struct cdns_reg_pairs {
u32 off;
};

+struct cdns_sierra_vals {
+ const struct cdns_reg_pairs *reg_pairs;
+ u32 num_regs;
+};
+
struct cdns_sierra_data {
- u32 id_value;
- u8 block_offset_shift;
- u8 reg_offset_shift;
- u32 pcie_cmn_regs;
- u32 pcie_ln_regs;
- u32 usb_cmn_regs;
- u32 usb_ln_regs;
- const struct cdns_reg_pairs *pcie_cmn_vals;
- const struct cdns_reg_pairs *pcie_ln_vals;
- const struct cdns_reg_pairs *usb_cmn_vals;
- const struct cdns_reg_pairs *usb_ln_vals;
+ u32 id_value;
+ u8 block_offset_shift;
+ u8 reg_offset_shift;
+ struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
+ struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
};

struct cdns_regmap_cdb_context {
@@ -341,10 +357,14 @@ static int cdns_sierra_phy_init(struct phy *gphy)
{
struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
struct cdns_sierra_phy *phy = dev_get_drvdata(gphy->dev.parent);
+ const struct cdns_sierra_data *init_data = phy->init_data;
+ struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
+ enum cdns_sierra_phy_type phy_type = ins->phy_type;
+ enum cdns_sierra_ssc_mode ssc = EXTERNAL_SSC;
+ const struct cdns_reg_pairs *reg_pairs;
struct regmap *regmap;
+ u32 num_regs;
int i, j;
- const struct cdns_reg_pairs *cmn_vals, *ln_vals;
- u32 num_cmn_regs, num_ln_regs;

/* Initialise the PHY registers, unless auto configured */
if (phy->autoconf)
@@ -352,28 +372,26 @@ static int cdns_sierra_phy_init(struct phy *gphy)

clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
clk_set_rate(phy->input_clks[CMN_REFCLK1_DIG_DIV], 25000000);
- if (ins->phy_type == PHY_TYPE_PCIE) {
- num_cmn_regs = phy->init_data->pcie_cmn_regs;
- num_ln_regs = phy->init_data->pcie_ln_regs;
- cmn_vals = phy->init_data->pcie_cmn_vals;
- ln_vals = phy->init_data->pcie_ln_vals;
- } else if (ins->phy_type == PHY_TYPE_USB3) {
- num_cmn_regs = phy->init_data->usb_cmn_regs;
- num_ln_regs = phy->init_data->usb_ln_regs;
- cmn_vals = phy->init_data->usb_cmn_vals;
- ln_vals = phy->init_data->usb_ln_vals;
- } else {
- return -EINVAL;
- }

- regmap = phy->regmap_common_cdb;
- for (j = 0; j < num_cmn_regs ; j++)
- regmap_write(regmap, cmn_vals[j].off, cmn_vals[j].val);
+ /* PMA common registers configurations */
+ pma_cmn_vals = init_data->pma_cmn_vals[phy_type][TYPE_NONE][ssc];
+ if (pma_cmn_vals) {
+ reg_pairs = pma_cmn_vals->reg_pairs;
+ num_regs = pma_cmn_vals->num_regs;
+ regmap = phy->regmap_common_cdb;
+ for (i = 0; i < num_regs; i++)
+ regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val);
+ }

- for (i = 0; i < ins->num_lanes; i++) {
- for (j = 0; j < num_ln_regs ; j++) {
+ /* PMA lane registers configurations */
+ pma_ln_vals = init_data->pma_ln_vals[phy_type][TYPE_NONE][ssc];
+ if (pma_ln_vals) {
+ reg_pairs = pma_ln_vals->reg_pairs;
+ num_regs = pma_ln_vals->num_regs;
+ for (i = 0; i < ins->num_lanes; i++) {
regmap = phy->regmap_lane_cdb[i + ins->mlane];
- regmap_write(regmap, ln_vals[j].off, ln_vals[j].val);
+ for (j = 0; j < num_regs; j++)
+ regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val);
}
}

@@ -583,15 +601,28 @@ static int cdns_sierra_clk_register(struct cdns_sierra_phy *sp)
static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
struct device_node *child)
{
+ u32 phy_type;
+
if (of_property_read_u32(child, "reg", &inst->mlane))
return -EINVAL;

if (of_property_read_u32(child, "cdns,num-lanes", &inst->num_lanes))
return -EINVAL;

- if (of_property_read_u32(child, "cdns,phy-type", &inst->phy_type))
+ if (of_property_read_u32(child, "cdns,phy-type", &phy_type))
return -EINVAL;

+ switch (phy_type) {
+ case PHY_TYPE_PCIE:
+ inst->phy_type = TYPE_PCIE;
+ break;
+ case PHY_TYPE_USB3:
+ inst->phy_type = TYPE_USB;
+ break;
+ default:
+ return -EINVAL;
+ }
+
return 0;
}

@@ -1006,6 +1037,16 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = {
{0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG}
};

+static struct cdns_sierra_vals pcie_100_ext_ssc_cmn_vals = {
+ .reg_pairs = cdns_pcie_cmn_regs_ext_ssc,
+ .num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
+};
+
+static struct cdns_sierra_vals pcie_100_ext_ssc_ln_vals = {
+ .reg_pairs = cdns_pcie_ln_regs_ext_ssc,
+ .num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
+};
+
/* refclk100MHz_20b_USB_cmn_pll_ext_ssc */
static const struct cdns_reg_pairs cdns_usb_cmn_regs_ext_ssc[] = {
{0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
@@ -1113,32 +1154,74 @@ static const struct cdns_reg_pairs cdns_usb_ln_regs_ext_ssc[] = {
{0x4243, SIERRA_RXBUFFER_DFECTRL_PREG}
};

+static struct cdns_sierra_vals usb_100_ext_ssc_cmn_vals = {
+ .reg_pairs = cdns_usb_cmn_regs_ext_ssc,
+ .num_regs = ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
+};
+
+static struct cdns_sierra_vals usb_100_ext_ssc_ln_vals = {
+ .reg_pairs = cdns_usb_ln_regs_ext_ssc,
+ .num_regs = ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
+};
+
static const struct cdns_sierra_data cdns_map_sierra = {
- SIERRA_MACRO_ID,
- 0x2,
- 0x2,
- ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
- ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
- ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
- ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
- cdns_pcie_cmn_regs_ext_ssc,
- cdns_pcie_ln_regs_ext_ssc,
- cdns_usb_cmn_regs_ext_ssc,
- cdns_usb_ln_regs_ext_ssc,
+ .id_value = SIERRA_MACRO_ID,
+ .block_offset_shift = 0x2,
+ .reg_offset_shift = 0x2,
+ .pma_cmn_vals = {
+ [TYPE_PCIE] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
+ },
+ },
+ [TYPE_USB] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals,
+ },
+ },
+ },
+ .pma_ln_vals = {
+ [TYPE_PCIE] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
+ },
+ },
+ [TYPE_USB] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals,
+ },
+ },
+ },
};

static const struct cdns_sierra_data cdns_ti_map_sierra = {
- SIERRA_MACRO_ID,
- 0x0,
- 0x1,
- ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
- ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
- ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
- ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
- cdns_pcie_cmn_regs_ext_ssc,
- cdns_pcie_ln_regs_ext_ssc,
- cdns_usb_cmn_regs_ext_ssc,
- cdns_usb_ln_regs_ext_ssc,
+ .id_value = SIERRA_MACRO_ID,
+ .block_offset_shift = 0x0,
+ .reg_offset_shift = 0x1,
+ .pma_cmn_vals = {
+ [TYPE_PCIE] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
+ },
+ },
+ [TYPE_USB] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals,
+ },
+ },
+ },
+ .pma_ln_vals = {
+ [TYPE_PCIE] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
+ },
+ },
+ [TYPE_USB] = {
+ [TYPE_NONE] = {
+ [EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals,
+ },
+ },
+ },
};

static const struct of_device_id cdns_sierra_id_table[] = {
--
2.26.1

Subject: [PATCH v3 06/15] phy: cadence: Sierra: Rename some regmap variables to be in sync with Sierra documentation

No functional change. Rename some regmap variables as mentioned in Sierra
register description documentation.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 4674328574f5..9f2b8aefee9c 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -145,8 +145,9 @@
#define SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG 0x14F
#define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG 0x150

-#define SIERRA_PHY_CONFIG_CTRL_OFFSET(block_offset) \
- (0xc000 << (block_offset))
+/* PHY PCS common registers */
+#define SIERRA_PHY_PCS_COMMON_OFFSET(block_offset) \
+ (0xc000 << (block_offset))
#define SIERRA_PHY_PLL_CFG 0xe

#define SIERRA_MACRO_ID 0x00007364
@@ -275,7 +276,7 @@ struct cdns_sierra_phy {
struct reset_control *phy_rst;
struct reset_control *apb_rst;
struct regmap *regmap_lane_cdb[SIERRA_MAX_LANES];
- struct regmap *regmap_phy_config_ctrl;
+ struct regmap *regmap_phy_pcs_common_cdb;
struct regmap *regmap_common_cdb;
struct regmap_field *macro_id_type;
struct regmap_field *phy_pll_cfg_1;
@@ -346,8 +347,8 @@ static const struct regmap_config cdns_sierra_common_cdb_config = {
.reg_read = cdns_regmap_read,
};

-static const struct regmap_config cdns_sierra_phy_config_ctrl_config = {
- .name = "sierra_phy_config_ctrl",
+static const struct regmap_config cdns_sierra_phy_pcs_cmn_cdb_config = {
+ .name = "sierra_phy_pcs_cmn_cdb",
.reg_stride = 1,
.fast_io = true,
.reg_write = cdns_regmap_write,
@@ -689,7 +690,7 @@ static int cdns_regfield_init(struct cdns_sierra_phy *sp)
sp->cmn_refrcv_refclk_termen_preg[i] = field;
}

- regmap = sp->regmap_phy_config_ctrl;
+ regmap = sp->regmap_phy_pcs_common_cdb;
field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg_1);
if (IS_ERR(field)) {
dev_err(dev, "PHY_PLL_CFG_1 reg field init failed\n");
@@ -741,14 +742,14 @@ static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp,
}
sp->regmap_common_cdb = regmap;

- block_offset = SIERRA_PHY_CONFIG_CTRL_OFFSET(block_offset_shift);
+ block_offset = SIERRA_PHY_PCS_COMMON_OFFSET(block_offset_shift);
regmap = cdns_regmap_init(dev, base, block_offset, reg_offset_shift,
- &cdns_sierra_phy_config_ctrl_config);
+ &cdns_sierra_phy_pcs_cmn_cdb_config);
if (IS_ERR(regmap)) {
- dev_err(dev, "Failed to init PHY config and control regmap\n");
+ dev_err(dev, "Failed to init PHY PCS common CDB regmap\n");
return PTR_ERR(regmap);
}
- sp->regmap_phy_config_ctrl = regmap;
+ sp->regmap_phy_pcs_common_cdb = regmap;

return 0;
}
--
2.26.1

Subject: [PATCH v3 10/15] phy: cadence: Sierra: Update single link PCIe register configuration

Add single link PCIe register configurations for no SSC and internal
SSC. Also, add missing PMA lane registers for external SSC.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 214 ++++++++++++++++++++++-
1 file changed, 213 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 59458388a855..728abd14aa79 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -36,7 +36,12 @@
#define SIERRA_CMN_PLLLC_LOCK_CNTSTART_PREG 0x4B
#define SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG 0x4F
#define SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG 0x50
+#define SIERRA_CMN_PLLLC_DSMCORR_PREG 0x51
+#define SIERRA_CMN_PLLLC_SS_PREG 0x52
+#define SIERRA_CMN_PLLLC_SS_AMP_STEP_SIZE_PREG 0x53
+#define SIERRA_CMN_PLLLC_SSTWOPT_PREG 0x54
#define SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG 0x62
+#define SIERRA_CMN_PLLLC_LOCK_DELAY_CTRL_PREG 0x63
#define SIERRA_CMN_REFRCV_PREG 0x98
#define SIERRA_CMN_REFRCV1_PREG 0xB8
#define SIERRA_CMN_PLLLC1_GEN_PREG 0xC2
@@ -52,6 +57,7 @@
#define SIERRA_DET_STANDEC_E_PREG 0x004
#define SIERRA_PSM_LANECAL_DLY_A1_RESETS_PREG 0x008
#define SIERRA_PSM_A0IN_TMR_PREG 0x009
+#define SIERRA_PSM_A3IN_TMR_PREG 0x00C
#define SIERRA_PSM_DIAG_PREG 0x015
#define SIERRA_PSC_TX_A0_PREG 0x028
#define SIERRA_PSC_TX_A1_PREG 0x029
@@ -68,12 +74,15 @@
#define SIERRA_CLKPATH_BIASTRIM_PREG 0x04B
#define SIERRA_DFE_BIASTRIM_PREG 0x04C
#define SIERRA_DRVCTRL_ATTEN_PREG 0x06A
+#define SIERRA_DRVCTRL_BOOST_PREG 0x06F
#define SIERRA_CLKPATHCTRL_TMR_PREG 0x081
#define SIERRA_RX_CREQ_FLTR_A_MODE3_PREG 0x085
#define SIERRA_RX_CREQ_FLTR_A_MODE2_PREG 0x086
#define SIERRA_RX_CREQ_FLTR_A_MODE1_PREG 0x087
#define SIERRA_RX_CREQ_FLTR_A_MODE0_PREG 0x088
+#define SIERRA_CREQ_DCBIASATTEN_OVR_PREG 0x08C
#define SIERRA_CREQ_CCLKDET_MODE01_PREG 0x08E
+#define SIERRA_RX_CTLE_CAL_PREG 0x08F
#define SIERRA_RX_CTLE_MAINTENANCE_PREG 0x091
#define SIERRA_CREQ_FSMCLK_SEL_PREG 0x092
#define SIERRA_CREQ_EQ_CTRL_PREG 0x093
@@ -123,15 +132,27 @@
#define SIERRA_DEQ_ALUT12 0x114
#define SIERRA_DEQ_ALUT13 0x115
#define SIERRA_DEQ_DFETAP_CTRL_PREG 0x128
+#define SIERRA_DEQ_DFETAP0 0x129
+#define SIERRA_DEQ_DFETAP1 0x12B
+#define SIERRA_DEQ_DFETAP2 0x12D
+#define SIERRA_DEQ_DFETAP3 0x12F
+#define SIERRA_DEQ_DFETAP4 0x131
#define SIERRA_DFE_EN_1010_IGNORE_PREG 0x134
+#define SIERRA_DEQ_PRECUR_PREG 0x138
+#define SIERRA_DEQ_POSTCUR_PREG 0x140
+#define SIERRA_DEQ_POSTCUR_DECR_PREG 0x142
#define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG 0x150
#define SIERRA_DEQ_TAU_CTRL2_PREG 0x151
+#define SIERRA_DEQ_TAU_CTRL3_PREG 0x152
+#define SIERRA_DEQ_OPENEYE_CTRL_PREG 0x158
#define SIERRA_DEQ_PICTRL_PREG 0x161
#define SIERRA_CPICAL_TMRVAL_MODE1_PREG 0x170
#define SIERRA_CPICAL_TMRVAL_MODE0_PREG 0x171
#define SIERRA_CPICAL_PICNT_MODE1_PREG 0x174
#define SIERRA_CPI_OUTBUF_RATESEL_PREG 0x17C
+#define SIERRA_CPI_TRIM_PREG 0x17F
#define SIERRA_CPICAL_RES_STARTCODE_MODE23_PREG 0x183
+#define SIERRA_EPI_CTRL_PREG 0x187
#define SIERRA_LFPSDET_SUPPORT_PREG 0x188
#define SIERRA_LFPSFILT_NS_PREG 0x18A
#define SIERRA_LFPSFILT_RD_PREG 0x18B
@@ -1162,6 +1183,146 @@ static struct cdns_sierra_vals pcie_phy_pcs_cmn_vals = {
.num_regs = ARRAY_SIZE(pcie_phy_pcs_cmn_regs),
};

+/* refclk100MHz_32b_PCIe_cmn_pll_no_ssc */
+static const struct cdns_reg_pairs cdns_pcie_cmn_regs_no_ssc[] = {
+ {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
+ {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
+ {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
+ {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG}
+};
+
+/* refclk100MHz_32b_PCIe_ln_no_ssc */
+static const struct cdns_reg_pairs cdns_pcie_ln_regs_no_ssc[] = {
+ {0xFC08, SIERRA_DET_STANDEC_A_PREG},
+ {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
+ {0x1555, SIERRA_DFE_BIASTRIM_PREG},
+ {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
+ {0x8055, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
+ {0x80BB, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
+ {0x8351, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
+ {0x8349, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
+ {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
+ {0x9800, SIERRA_RX_CTLE_CAL_PREG},
+ {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
+ {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
+ {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
+ {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
+ {0x0041, SIERRA_DEQ_GLUT0},
+ {0x0082, SIERRA_DEQ_GLUT1},
+ {0x00C3, SIERRA_DEQ_GLUT2},
+ {0x0145, SIERRA_DEQ_GLUT3},
+ {0x0186, SIERRA_DEQ_GLUT4},
+ {0x09E7, SIERRA_DEQ_ALUT0},
+ {0x09A6, SIERRA_DEQ_ALUT1},
+ {0x0965, SIERRA_DEQ_ALUT2},
+ {0x08E3, SIERRA_DEQ_ALUT3},
+ {0x00FA, SIERRA_DEQ_DFETAP0},
+ {0x00FA, SIERRA_DEQ_DFETAP1},
+ {0x00FA, SIERRA_DEQ_DFETAP2},
+ {0x00FA, SIERRA_DEQ_DFETAP3},
+ {0x00FA, SIERRA_DEQ_DFETAP4},
+ {0x000F, SIERRA_DEQ_PRECUR_PREG},
+ {0x0280, SIERRA_DEQ_POSTCUR_PREG},
+ {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
+ {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
+ {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
+ {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
+ {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
+ {0x002B, SIERRA_CPI_TRIM_PREG},
+ {0x0003, SIERRA_EPI_CTRL_PREG},
+ {0x803F, SIERRA_SDFILT_H2L_A_PREG},
+ {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
+ {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
+ {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
+};
+
+static struct cdns_sierra_vals pcie_100_no_ssc_cmn_vals = {
+ .reg_pairs = cdns_pcie_cmn_regs_no_ssc,
+ .num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_no_ssc),
+};
+
+static struct cdns_sierra_vals pcie_100_no_ssc_ln_vals = {
+ .reg_pairs = cdns_pcie_ln_regs_no_ssc,
+ .num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_no_ssc),
+};
+
+/* refclk100MHz_32b_PCIe_cmn_pll_int_ssc */
+static const struct cdns_reg_pairs cdns_pcie_cmn_regs_int_ssc[] = {
+ {0x000E, SIERRA_CMN_PLLLC_MODE_PREG},
+ {0x4006, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
+ {0x4006, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
+ {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
+ {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
+ {0x0581, SIERRA_CMN_PLLLC_DSMCORR_PREG},
+ {0x7F80, SIERRA_CMN_PLLLC_SS_PREG},
+ {0x0041, SIERRA_CMN_PLLLC_SS_AMP_STEP_SIZE_PREG},
+ {0x0464, SIERRA_CMN_PLLLC_SSTWOPT_PREG},
+ {0x0D0D, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG},
+ {0x0060, SIERRA_CMN_PLLLC_LOCK_DELAY_CTRL_PREG}
+};
+
+/* refclk100MHz_32b_PCIe_ln_int_ssc */
+static const struct cdns_reg_pairs cdns_pcie_ln_regs_int_ssc[] = {
+ {0xFC08, SIERRA_DET_STANDEC_A_PREG},
+ {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
+ {0x1555, SIERRA_DFE_BIASTRIM_PREG},
+ {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
+ {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
+ {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
+ {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
+ {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
+ {0x9800, SIERRA_RX_CTLE_CAL_PREG},
+ {0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
+ {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
+ {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
+ {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
+ {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
+ {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
+ {0x0041, SIERRA_DEQ_GLUT0},
+ {0x0082, SIERRA_DEQ_GLUT1},
+ {0x00C3, SIERRA_DEQ_GLUT2},
+ {0x0145, SIERRA_DEQ_GLUT3},
+ {0x0186, SIERRA_DEQ_GLUT4},
+ {0x09E7, SIERRA_DEQ_ALUT0},
+ {0x09A6, SIERRA_DEQ_ALUT1},
+ {0x0965, SIERRA_DEQ_ALUT2},
+ {0x08E3, SIERRA_DEQ_ALUT3},
+ {0x00FA, SIERRA_DEQ_DFETAP0},
+ {0x00FA, SIERRA_DEQ_DFETAP1},
+ {0x00FA, SIERRA_DEQ_DFETAP2},
+ {0x00FA, SIERRA_DEQ_DFETAP3},
+ {0x00FA, SIERRA_DEQ_DFETAP4},
+ {0x000F, SIERRA_DEQ_PRECUR_PREG},
+ {0x0280, SIERRA_DEQ_POSTCUR_PREG},
+ {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
+ {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
+ {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
+ {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
+ {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
+ {0x002B, SIERRA_CPI_TRIM_PREG},
+ {0x0003, SIERRA_EPI_CTRL_PREG},
+ {0x803F, SIERRA_SDFILT_H2L_A_PREG},
+ {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
+ {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
+ {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
+};
+
+static struct cdns_sierra_vals pcie_100_int_ssc_cmn_vals = {
+ .reg_pairs = cdns_pcie_cmn_regs_int_ssc,
+ .num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_int_ssc),
+};
+
+static struct cdns_sierra_vals pcie_100_int_ssc_ln_vals = {
+ .reg_pairs = cdns_pcie_ln_regs_int_ssc,
+ .num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_int_ssc),
+};
+
/* refclk100MHz_32b_PCIe_cmn_pll_ext_ssc */
static const struct cdns_reg_pairs cdns_pcie_cmn_regs_ext_ssc[] = {
{0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
@@ -1173,13 +1334,52 @@ static const struct cdns_reg_pairs cdns_pcie_cmn_regs_ext_ssc[] = {

/* refclk100MHz_32b_PCIe_ln_ext_ssc */
static const struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = {
+ {0xFC08, SIERRA_DET_STANDEC_A_PREG},
+ {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
+ {0x1555, SIERRA_DFE_BIASTRIM_PREG},
+ {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
{0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
{0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
{0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
{0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
{0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
+ {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
+ {0x9800, SIERRA_RX_CTLE_CAL_PREG},
{0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
- {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG}
+ {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
+ {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
+ {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
+ {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
+ {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
+ {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
+ {0x0041, SIERRA_DEQ_GLUT0},
+ {0x0082, SIERRA_DEQ_GLUT1},
+ {0x00C3, SIERRA_DEQ_GLUT2},
+ {0x0145, SIERRA_DEQ_GLUT3},
+ {0x0186, SIERRA_DEQ_GLUT4},
+ {0x09E7, SIERRA_DEQ_ALUT0},
+ {0x09A6, SIERRA_DEQ_ALUT1},
+ {0x0965, SIERRA_DEQ_ALUT2},
+ {0x08E3, SIERRA_DEQ_ALUT3},
+ {0x00FA, SIERRA_DEQ_DFETAP0},
+ {0x00FA, SIERRA_DEQ_DFETAP1},
+ {0x00FA, SIERRA_DEQ_DFETAP2},
+ {0x00FA, SIERRA_DEQ_DFETAP3},
+ {0x00FA, SIERRA_DEQ_DFETAP4},
+ {0x000F, SIERRA_DEQ_PRECUR_PREG},
+ {0x0280, SIERRA_DEQ_POSTCUR_PREG},
+ {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
+ {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
+ {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
+ {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
+ {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
+ {0x002B, SIERRA_CPI_TRIM_PREG},
+ {0x0003, SIERRA_EPI_CTRL_PREG},
+ {0x803F, SIERRA_SDFILT_H2L_A_PREG},
+ {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
+ {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
+ {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
};

static struct cdns_sierra_vals pcie_100_ext_ssc_cmn_vals = {
@@ -1316,14 +1516,18 @@ static const struct cdns_sierra_data cdns_map_sierra = {
.pcs_cmn_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
+ [NO_SSC] = &pcie_phy_pcs_cmn_vals,
[EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
+ [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
},
},
},
.pma_cmn_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
+ [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
[EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
+ [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
},
},
[TYPE_USB] = {
@@ -1335,7 +1539,9 @@ static const struct cdns_sierra_data cdns_map_sierra = {
.pma_ln_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
+ [NO_SSC] = &pcie_100_no_ssc_ln_vals,
[EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
+ [INTERNAL_SSC] = &pcie_100_int_ssc_ln_vals,
},
},
[TYPE_USB] = {
@@ -1353,14 +1559,18 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = {
.pcs_cmn_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
+ [NO_SSC] = &pcie_phy_pcs_cmn_vals,
[EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
+ [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
},
},
},
.pma_cmn_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
+ [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
[EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
+ [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
},
},
[TYPE_USB] = {
@@ -1372,7 +1582,9 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = {
.pma_ln_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
+ [NO_SSC] = &pcie_100_no_ssc_ln_vals,
[EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
+ [INTERNAL_SSC] = &pcie_100_int_ssc_ln_vals,
},
},
[TYPE_USB] = {
--
2.26.1

Subject: [PATCH v3 05/15] phy: cadence: Sierra: Add support to get SSC type from device tree

Add support to get SSC type from DT.

Signed-off-by: Swapnil Jakhade <[email protected]>
Reviewed-by: Aswath Govindraju <[email protected]>
---
drivers/phy/cadence/phy-cadence-sierra.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index c82ac6716f5e..4674328574f5 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -238,6 +238,7 @@ struct cdns_sierra_inst {
u32 num_lanes;
u32 mlane;
struct reset_control *lnk_rst;
+ enum cdns_sierra_ssc_mode ssc_mode;
};

struct cdns_reg_pairs {
@@ -360,7 +361,7 @@ static int cdns_sierra_phy_init(struct phy *gphy)
const struct cdns_sierra_data *init_data = phy->init_data;
struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
enum cdns_sierra_phy_type phy_type = ins->phy_type;
- enum cdns_sierra_ssc_mode ssc = EXTERNAL_SSC;
+ enum cdns_sierra_ssc_mode ssc = ins->ssc_mode;
const struct cdns_reg_pairs *reg_pairs;
struct regmap *regmap;
u32 num_regs;
@@ -623,6 +624,9 @@ static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
return -EINVAL;
}

+ inst->ssc_mode = EXTERNAL_SSC;
+ of_property_read_u32(child, "cdns,ssc-mode", &inst->ssc_mode);
+
return 0;
}

--
2.26.1

2021-11-23 04:33:09

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH v3 02/15] phy: cadence: Sierra: Prepare driver to add support for multilink configurations

On 22-10-21, 19:02, Swapnil Jakhade wrote:
> Sierra driver currently supports single link configurations only. Prepare
> driver to support multilink multiprotocol configurations along with
> different SSC modes.
>
> Signed-off-by: Swapnil Jakhade <[email protected]>
> Reviewed-by: Aswath Govindraju <[email protected]>
> ---
> drivers/phy/cadence/phy-cadence-sierra.c | 195 ++++++++++++++++-------
> 1 file changed, 139 insertions(+), 56 deletions(-)
>
> diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
> index 54d1c63932ac..c82ac6716f5e 100644
> --- a/drivers/phy/cadence/phy-cadence-sierra.c
> +++ b/drivers/phy/cadence/phy-cadence-sierra.c
> @@ -23,6 +23,9 @@
> #include <dt-bindings/phy/phy.h>
> #include <dt-bindings/phy/phy-cadence.h>
>
> +#define NUM_SSC_MODE 3
> +#define NUM_PHY_TYPE 3
> +
> /* PHY register offsets */
> #define SIERRA_COMMON_CDB_OFFSET 0x0
> #define SIERRA_MACRO_ID_REG 0x0
> @@ -217,9 +220,21 @@ static const int pll_mux_parent_index[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
>
> static u32 cdns_sierra_pll_mux_table[] = { 0, 1 };
>
> +enum cdns_sierra_phy_type {
> + TYPE_NONE,

What does NONE type mean?

> + TYPE_PCIE,
> + TYPE_USB
> +};
> +
> +enum cdns_sierra_ssc_mode {
> + NO_SSC,
> + EXTERNAL_SSC,
> + INTERNAL_SSC
> +};
> +
> struct cdns_sierra_inst {
> struct phy *phy;
> - u32 phy_type;
> + enum cdns_sierra_phy_type phy_type;
> u32 num_lanes;
> u32 mlane;
> struct reset_control *lnk_rst;
> @@ -230,18 +245,19 @@ struct cdns_reg_pairs {
> u32 off;
> };
>
> +struct cdns_sierra_vals {
> + const struct cdns_reg_pairs *reg_pairs;
> + u32 num_regs;
> +};
> +
> struct cdns_sierra_data {
> - u32 id_value;
> - u8 block_offset_shift;
> - u8 reg_offset_shift;
> - u32 pcie_cmn_regs;
> - u32 pcie_ln_regs;
> - u32 usb_cmn_regs;
> - u32 usb_ln_regs;
> - const struct cdns_reg_pairs *pcie_cmn_vals;
> - const struct cdns_reg_pairs *pcie_ln_vals;
> - const struct cdns_reg_pairs *usb_cmn_vals;
> - const struct cdns_reg_pairs *usb_ln_vals;
> + u32 id_value;
> + u8 block_offset_shift;
> + u8 reg_offset_shift;
> + struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
> + [NUM_SSC_MODE];
> + struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
> + [NUM_SSC_MODE];

You have defined phy type and ssc, that sounds fine, I am not sure why
you need a third dimension here? What purpose does it solve?

> };
>
> struct cdns_regmap_cdb_context {
> @@ -341,10 +357,14 @@ static int cdns_sierra_phy_init(struct phy *gphy)
> {
> struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
> struct cdns_sierra_phy *phy = dev_get_drvdata(gphy->dev.parent);
> + const struct cdns_sierra_data *init_data = phy->init_data;
> + struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
> + enum cdns_sierra_phy_type phy_type = ins->phy_type;
> + enum cdns_sierra_ssc_mode ssc = EXTERNAL_SSC;
> + const struct cdns_reg_pairs *reg_pairs;
> struct regmap *regmap;
> + u32 num_regs;
> int i, j;
> - const struct cdns_reg_pairs *cmn_vals, *ln_vals;
> - u32 num_cmn_regs, num_ln_regs;
>
> /* Initialise the PHY registers, unless auto configured */
> if (phy->autoconf)
> @@ -352,28 +372,26 @@ static int cdns_sierra_phy_init(struct phy *gphy)
>
> clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
> clk_set_rate(phy->input_clks[CMN_REFCLK1_DIG_DIV], 25000000);
> - if (ins->phy_type == PHY_TYPE_PCIE) {
> - num_cmn_regs = phy->init_data->pcie_cmn_regs;
> - num_ln_regs = phy->init_data->pcie_ln_regs;
> - cmn_vals = phy->init_data->pcie_cmn_vals;
> - ln_vals = phy->init_data->pcie_ln_vals;
> - } else if (ins->phy_type == PHY_TYPE_USB3) {
> - num_cmn_regs = phy->init_data->usb_cmn_regs;
> - num_ln_regs = phy->init_data->usb_ln_regs;
> - cmn_vals = phy->init_data->usb_cmn_vals;
> - ln_vals = phy->init_data->usb_ln_vals;
> - } else {
> - return -EINVAL;
> - }
>
> - regmap = phy->regmap_common_cdb;
> - for (j = 0; j < num_cmn_regs ; j++)
> - regmap_write(regmap, cmn_vals[j].off, cmn_vals[j].val);
> + /* PMA common registers configurations */
> + pma_cmn_vals = init_data->pma_cmn_vals[phy_type][TYPE_NONE][ssc];
> + if (pma_cmn_vals) {
> + reg_pairs = pma_cmn_vals->reg_pairs;
> + num_regs = pma_cmn_vals->num_regs;
> + regmap = phy->regmap_common_cdb;
> + for (i = 0; i < num_regs; i++)
> + regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val);
> + }
>
> - for (i = 0; i < ins->num_lanes; i++) {
> - for (j = 0; j < num_ln_regs ; j++) {
> + /* PMA lane registers configurations */
> + pma_ln_vals = init_data->pma_ln_vals[phy_type][TYPE_NONE][ssc];
> + if (pma_ln_vals) {
> + reg_pairs = pma_ln_vals->reg_pairs;
> + num_regs = pma_ln_vals->num_regs;
> + for (i = 0; i < ins->num_lanes; i++) {
> regmap = phy->regmap_lane_cdb[i + ins->mlane];
> - regmap_write(regmap, ln_vals[j].off, ln_vals[j].val);
> + for (j = 0; j < num_regs; j++)
> + regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val);
> }
> }
>
> @@ -583,15 +601,28 @@ static int cdns_sierra_clk_register(struct cdns_sierra_phy *sp)
> static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
> struct device_node *child)
> {
> + u32 phy_type;
> +
> if (of_property_read_u32(child, "reg", &inst->mlane))
> return -EINVAL;
>
> if (of_property_read_u32(child, "cdns,num-lanes", &inst->num_lanes))
> return -EINVAL;
>
> - if (of_property_read_u32(child, "cdns,phy-type", &inst->phy_type))
> + if (of_property_read_u32(child, "cdns,phy-type", &phy_type))
> return -EINVAL;
>
> + switch (phy_type) {
> + case PHY_TYPE_PCIE:
> + inst->phy_type = TYPE_PCIE;
> + break;
> + case PHY_TYPE_USB3:
> + inst->phy_type = TYPE_USB;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> return 0;
> }
>
> @@ -1006,6 +1037,16 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = {
> {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG}
> };
>
> +static struct cdns_sierra_vals pcie_100_ext_ssc_cmn_vals = {
> + .reg_pairs = cdns_pcie_cmn_regs_ext_ssc,
> + .num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
> +};
> +
> +static struct cdns_sierra_vals pcie_100_ext_ssc_ln_vals = {
> + .reg_pairs = cdns_pcie_ln_regs_ext_ssc,
> + .num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
> +};
> +
> /* refclk100MHz_20b_USB_cmn_pll_ext_ssc */
> static const struct cdns_reg_pairs cdns_usb_cmn_regs_ext_ssc[] = {
> {0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> @@ -1113,32 +1154,74 @@ static const struct cdns_reg_pairs cdns_usb_ln_regs_ext_ssc[] = {
> {0x4243, SIERRA_RXBUFFER_DFECTRL_PREG}
> };
>
> +static struct cdns_sierra_vals usb_100_ext_ssc_cmn_vals = {
> + .reg_pairs = cdns_usb_cmn_regs_ext_ssc,
> + .num_regs = ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
> +};
> +
> +static struct cdns_sierra_vals usb_100_ext_ssc_ln_vals = {
> + .reg_pairs = cdns_usb_ln_regs_ext_ssc,
> + .num_regs = ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
> +};
> +
> static const struct cdns_sierra_data cdns_map_sierra = {
> - SIERRA_MACRO_ID,
> - 0x2,
> - 0x2,
> - ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
> - ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
> - ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
> - ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
> - cdns_pcie_cmn_regs_ext_ssc,
> - cdns_pcie_ln_regs_ext_ssc,
> - cdns_usb_cmn_regs_ext_ssc,
> - cdns_usb_ln_regs_ext_ssc,
> + .id_value = SIERRA_MACRO_ID,
> + .block_offset_shift = 0x2,
> + .reg_offset_shift = 0x2,
> + .pma_cmn_vals = {
> + [TYPE_PCIE] = {
> + [TYPE_NONE] = {
> + [EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
> + },
> + },
> + [TYPE_USB] = {
> + [TYPE_NONE] = {
> + [EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals,
> + },
> + },
> + },
> + .pma_ln_vals = {
> + [TYPE_PCIE] = {
> + [TYPE_NONE] = {
> + [EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
> + },
> + },
> + [TYPE_USB] = {
> + [TYPE_NONE] = {
> + [EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals,
> + },
> + },
> + },
> };
>
> static const struct cdns_sierra_data cdns_ti_map_sierra = {
> - SIERRA_MACRO_ID,
> - 0x0,
> - 0x1,
> - ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
> - ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
> - ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
> - ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
> - cdns_pcie_cmn_regs_ext_ssc,
> - cdns_pcie_ln_regs_ext_ssc,
> - cdns_usb_cmn_regs_ext_ssc,
> - cdns_usb_ln_regs_ext_ssc,
> + .id_value = SIERRA_MACRO_ID,
> + .block_offset_shift = 0x0,
> + .reg_offset_shift = 0x1,
> + .pma_cmn_vals = {
> + [TYPE_PCIE] = {
> + [TYPE_NONE] = {
> + [EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
> + },
> + },
> + [TYPE_USB] = {
> + [TYPE_NONE] = {
> + [EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals,
> + },
> + },
> + },
> + .pma_ln_vals = {
> + [TYPE_PCIE] = {
> + [TYPE_NONE] = {
> + [EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
> + },
> + },
> + [TYPE_USB] = {
> + [TYPE_NONE] = {
> + [EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals,
> + },
> + },
> + },
> };
>
> static const struct of_device_id cdns_sierra_id_table[] = {
> --
> 2.26.1

--
~Vinod

2021-11-23 04:48:21

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

On 22-10-21, 19:02, Swapnil Jakhade wrote:
> Add register sequences for PCIe + QSGMII PHY multilink configuration.
>
> Signed-off-by: Swapnil Jakhade <[email protected]>
> Reviewed-by: Aswath Govindraju <[email protected]>
> ---
> drivers/phy/cadence/phy-cadence-sierra.c | 377 ++++++++++++++++++++++-
> 1 file changed, 376 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
> index a39be67424a1..0deb627845b1 100644
> --- a/drivers/phy/cadence/phy-cadence-sierra.c
> +++ b/drivers/phy/cadence/phy-cadence-sierra.c
> @@ -45,6 +45,9 @@
> #define SIERRA_CMN_REFRCV_PREG 0x98
> #define SIERRA_CMN_REFRCV1_PREG 0xB8
> #define SIERRA_CMN_PLLLC1_GEN_PREG 0xC2
> +#define SIERRA_CMN_PLLLC1_LF_COEFF_MODE0_PREG 0xCA
> +#define SIERRA_CMN_PLLLC1_BWCAL_MODE0_PREG 0xD0
> +#define SIERRA_CMN_PLLLC1_SS_TIME_STEPSIZE_MODE_PREG 0xE2
>
> #define SIERRA_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \
> ((0x4000 << (block_offset)) + \
> @@ -59,6 +62,9 @@
> #define SIERRA_PSM_A0IN_TMR_PREG 0x009
> #define SIERRA_PSM_A3IN_TMR_PREG 0x00C
> #define SIERRA_PSM_DIAG_PREG 0x015
> +#define SIERRA_PSC_LN_A3_PREG 0x023
> +#define SIERRA_PSC_LN_A4_PREG 0x024
> +#define SIERRA_PSC_LN_IDLE_PREG 0x026
> #define SIERRA_PSC_TX_A0_PREG 0x028
> #define SIERRA_PSC_TX_A1_PREG 0x029
> #define SIERRA_PSC_TX_A2_PREG 0x02A
> @@ -68,6 +74,7 @@
> #define SIERRA_PSC_RX_A2_PREG 0x032
> #define SIERRA_PSC_RX_A3_PREG 0x033
> #define SIERRA_PLLCTRL_SUBRATE_PREG 0x03A
> +#define SIERRA_PLLCTRL_GEN_A_PREG 0x03B
> #define SIERRA_PLLCTRL_GEN_D_PREG 0x03E
> #define SIERRA_PLLCTRL_CPGAIN_MODE_PREG 0x03F
> #define SIERRA_PLLCTRL_STATUS_PREG 0x044
> @@ -150,6 +157,7 @@
> #define SIERRA_CPICAL_TMRVAL_MODE0_PREG 0x171
> #define SIERRA_CPICAL_PICNT_MODE1_PREG 0x174
> #define SIERRA_CPI_OUTBUF_RATESEL_PREG 0x17C
> +#define SIERRA_CPI_RESBIAS_BIN_PREG 0x17E
> #define SIERRA_CPI_TRIM_PREG 0x17F
> #define SIERRA_CPICAL_RES_STARTCODE_MODE23_PREG 0x183
> #define SIERRA_EPI_CTRL_PREG 0x187
> @@ -272,7 +280,8 @@ static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
> enum cdns_sierra_phy_type {
> TYPE_NONE,
> TYPE_PCIE,
> - TYPE_USB
> + TYPE_USB,
> + TYPE_QSGMII
> };
>
> enum cdns_sierra_ssc_mode {
> @@ -807,6 +816,9 @@ static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
> case PHY_TYPE_USB3:
> inst->phy_type = TYPE_USB;
> break;
> + case PHY_TYPE_QSGMII:
> + inst->phy_type = TYPE_QSGMII;
> + break;
> default:
> return -EINVAL;
> }
> @@ -1186,6 +1198,9 @@ static int cdns_sierra_phy_configure_multilink(struct cdns_sierra_phy *sp)
> regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val);
> }
> }
> +
> + if (phy_t1 == TYPE_QSGMII)
> + reset_control_deassert(sp->phys[node].lnk_rst);
> }
>
> /* Take the PHY out of reset */
> @@ -1363,6 +1378,72 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev)
> return 0;
> }
>
> +/* QSGMII PHY PMA lane configuration */
> +static struct cdns_reg_pairs qsgmii_phy_pma_ln_regs[] = {
> + {0x9010, SIERRA_PHY_PMA_XCVR_CTRL}
> +};
> +
> +static struct cdns_sierra_vals qsgmii_phy_pma_ln_vals = {
> + .reg_pairs = qsgmii_phy_pma_ln_regs,
> + .num_regs = ARRAY_SIZE(qsgmii_phy_pma_ln_regs),
> +};
> +
> +/* QSGMII refclk 100MHz, 20b, opt1, No BW cal, no ssc, PLL LC1 */
> +static const struct cdns_reg_pairs qsgmii_100_no_ssc_plllc1_cmn_regs[] = {
> + {0x2085, SIERRA_CMN_PLLLC1_LF_COEFF_MODE0_PREG},
> + {0x0000, SIERRA_CMN_PLLLC1_BWCAL_MODE0_PREG},
> + {0x0000, SIERRA_CMN_PLLLC1_SS_TIME_STEPSIZE_MODE_PREG}
> +};
> +
> +static const struct cdns_reg_pairs qsgmii_100_no_ssc_plllc1_ln_regs[] = {
> + {0xFC08, SIERRA_DET_STANDEC_A_PREG},
> + {0x0252, SIERRA_DET_STANDEC_E_PREG},
> + {0x0004, SIERRA_PSC_LN_IDLE_PREG},
> + {0x0FFE, SIERRA_PSC_RX_A0_PREG},
> + {0x0011, SIERRA_PLLCTRL_SUBRATE_PREG},
> + {0x0001, SIERRA_PLLCTRL_GEN_A_PREG},
> + {0x5233, SIERRA_PLLCTRL_CPGAIN_MODE_PREG},
> + {0x0000, SIERRA_DRVCTRL_ATTEN_PREG},
> + {0x0089, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
> + {0x3C3C, SIERRA_CREQ_CCLKDET_MODE01_PREG},
> + {0x3222, SIERRA_CREQ_FSMCLK_SEL_PREG},
> + {0x0000, SIERRA_CREQ_EQ_CTRL_PREG},
> + {0x8422, SIERRA_CTLELUT_CTRL_PREG},
> + {0x4111, SIERRA_DFE_ECMP_RATESEL_PREG},
> + {0x4111, SIERRA_DFE_SMP_RATESEL_PREG},
> + {0x0002, SIERRA_DEQ_PHALIGN_CTRL},
> + {0x9595, SIERRA_DEQ_VGATUNE_CTRL_PREG},
> + {0x0186, SIERRA_DEQ_GLUT0},
> + {0x0186, SIERRA_DEQ_GLUT1},
> + {0x0186, SIERRA_DEQ_GLUT2},
> + {0x0186, SIERRA_DEQ_GLUT3},
> + {0x0186, SIERRA_DEQ_GLUT4},
> + {0x0861, SIERRA_DEQ_ALUT0},
> + {0x07E0, SIERRA_DEQ_ALUT1},
> + {0x079E, SIERRA_DEQ_ALUT2},
> + {0x071D, SIERRA_DEQ_ALUT3},
> + {0x03F5, SIERRA_DEQ_DFETAP_CTRL_PREG},
> + {0x0C01, SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG},
> + {0x3C40, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
> + {0x1C04, SIERRA_DEQ_TAU_CTRL2_PREG},
> + {0x0033, SIERRA_DEQ_PICTRL_PREG},
> + {0x0660, SIERRA_CPICAL_TMRVAL_MODE0_PREG},
> + {0x00D5, SIERRA_CPI_OUTBUF_RATESEL_PREG},
> + {0x0B6D, SIERRA_CPI_RESBIAS_BIN_PREG},
> + {0x0102, SIERRA_RXBUFFER_CTLECTRL_PREG},
> + {0x0002, SIERRA_RXBUFFER_RCDFECTRL_PREG}
> +};
> +
> +static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_cmn_vals = {
> + .reg_pairs = qsgmii_100_no_ssc_plllc1_cmn_regs,
> + .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_cmn_regs),
> +};
> +
> +static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_ln_vals = {
> + .reg_pairs = qsgmii_100_no_ssc_plllc1_ln_regs,
> + .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_ln_regs),
> +};
> +
> /* PCIE PHY PCS common configuration */
> static struct cdns_reg_pairs pcie_phy_pcs_cmn_regs[] = {
> {0x0430, SIERRA_PHY_PIPE_CMN_CTRL1}
> @@ -1373,6 +1454,233 @@ static struct cdns_sierra_vals pcie_phy_pcs_cmn_vals = {
> .num_regs = ARRAY_SIZE(pcie_phy_pcs_cmn_regs),
> };
>
> +/* refclk100MHz_32b_PCIe_cmn_pll_no_ssc, pcie_links_using_plllc, pipe_bw_3 */
> +static const struct cdns_reg_pairs pcie_100_no_ssc_plllc_cmn_regs[] = {
> + {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> + {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
> + {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
> + {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG}
> +};
> +
> +/*
> + * refclk100MHz_32b_PCIe_ln_no_ssc, multilink, using_plllc,
> + * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz
> + */
> +static const struct cdns_reg_pairs ml_pcie_100_no_ssc_ln_regs[] = {
> + {0xFC08, SIERRA_DET_STANDEC_A_PREG},
> + {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
> + {0x0004, SIERRA_PSC_LN_A3_PREG},
> + {0x0004, SIERRA_PSC_LN_A4_PREG},
> + {0x0004, SIERRA_PSC_LN_IDLE_PREG},
> + {0x1555, SIERRA_DFE_BIASTRIM_PREG},
> + {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
> + {0x8055, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
> + {0x80BB, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
> + {0x8351, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
> + {0x8349, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
> + {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
> + {0x9800, SIERRA_RX_CTLE_CAL_PREG},
> + {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
> + {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
> + {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
> + {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
> + {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
> + {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
> + {0x0041, SIERRA_DEQ_GLUT0},
> + {0x0082, SIERRA_DEQ_GLUT1},
> + {0x00C3, SIERRA_DEQ_GLUT2},
> + {0x0145, SIERRA_DEQ_GLUT3},
> + {0x0186, SIERRA_DEQ_GLUT4},
> + {0x09E7, SIERRA_DEQ_ALUT0},
> + {0x09A6, SIERRA_DEQ_ALUT1},
> + {0x0965, SIERRA_DEQ_ALUT2},
> + {0x08E3, SIERRA_DEQ_ALUT3},
> + {0x00FA, SIERRA_DEQ_DFETAP0},
> + {0x00FA, SIERRA_DEQ_DFETAP1},
> + {0x00FA, SIERRA_DEQ_DFETAP2},
> + {0x00FA, SIERRA_DEQ_DFETAP3},
> + {0x00FA, SIERRA_DEQ_DFETAP4},
> + {0x000F, SIERRA_DEQ_PRECUR_PREG},
> + {0x0280, SIERRA_DEQ_POSTCUR_PREG},
> + {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
> + {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
> + {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
> + {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
> + {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
> + {0x002B, SIERRA_CPI_TRIM_PREG},
> + {0x0003, SIERRA_EPI_CTRL_PREG},
> + {0x803F, SIERRA_SDFILT_H2L_A_PREG},
> + {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
> + {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
> + {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
> +};
> +
> +static struct cdns_sierra_vals pcie_100_no_ssc_plllc_cmn_vals = {
> + .reg_pairs = pcie_100_no_ssc_plllc_cmn_regs,
> + .num_regs = ARRAY_SIZE(pcie_100_no_ssc_plllc_cmn_regs),
> +};
> +
> +static struct cdns_sierra_vals ml_pcie_100_no_ssc_ln_vals = {
> + .reg_pairs = ml_pcie_100_no_ssc_ln_regs,
> + .num_regs = ARRAY_SIZE(ml_pcie_100_no_ssc_ln_regs),
> +};
> +
> +/* refclk100MHz_32b_PCIe_cmn_pll_int_ssc, pcie_links_using_plllc, pipe_bw_3 */
> +static const struct cdns_reg_pairs pcie_100_int_ssc_plllc_cmn_regs[] = {
> + {0x000E, SIERRA_CMN_PLLLC_MODE_PREG},
> + {0x4006, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> + {0x4006, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
> + {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
> + {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
> + {0x0581, SIERRA_CMN_PLLLC_DSMCORR_PREG},
> + {0x7F80, SIERRA_CMN_PLLLC_SS_PREG},
> + {0x0041, SIERRA_CMN_PLLLC_SS_AMP_STEP_SIZE_PREG},
> + {0x0464, SIERRA_CMN_PLLLC_SSTWOPT_PREG},
> + {0x0D0D, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG},
> + {0x0060, SIERRA_CMN_PLLLC_LOCK_DELAY_CTRL_PREG}
> +};
> +
> +/*
> + * refclk100MHz_32b_PCIe_ln_int_ssc, multilink, using_plllc,
> + * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz
> + */
> +static const struct cdns_reg_pairs ml_pcie_100_int_ssc_ln_regs[] = {
> + {0xFC08, SIERRA_DET_STANDEC_A_PREG},
> + {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
> + {0x0004, SIERRA_PSC_LN_A3_PREG},
> + {0x0004, SIERRA_PSC_LN_A4_PREG},
> + {0x0004, SIERRA_PSC_LN_IDLE_PREG},
> + {0x1555, SIERRA_DFE_BIASTRIM_PREG},
> + {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
> + {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
> + {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
> + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
> + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
> + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
> + {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
> + {0x9800, SIERRA_RX_CTLE_CAL_PREG},
> + {0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
> + {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
> + {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
> + {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
> + {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
> + {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
> + {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
> + {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
> + {0x0041, SIERRA_DEQ_GLUT0},
> + {0x0082, SIERRA_DEQ_GLUT1},
> + {0x00C3, SIERRA_DEQ_GLUT2},
> + {0x0145, SIERRA_DEQ_GLUT3},
> + {0x0186, SIERRA_DEQ_GLUT4},
> + {0x09E7, SIERRA_DEQ_ALUT0},
> + {0x09A6, SIERRA_DEQ_ALUT1},
> + {0x0965, SIERRA_DEQ_ALUT2},
> + {0x08E3, SIERRA_DEQ_ALUT3},
> + {0x00FA, SIERRA_DEQ_DFETAP0},
> + {0x00FA, SIERRA_DEQ_DFETAP1},
> + {0x00FA, SIERRA_DEQ_DFETAP2},
> + {0x00FA, SIERRA_DEQ_DFETAP3},
> + {0x00FA, SIERRA_DEQ_DFETAP4},
> + {0x000F, SIERRA_DEQ_PRECUR_PREG},
> + {0x0280, SIERRA_DEQ_POSTCUR_PREG},
> + {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
> + {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
> + {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
> + {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
> + {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
> + {0x002B, SIERRA_CPI_TRIM_PREG},
> + {0x0003, SIERRA_EPI_CTRL_PREG},
> + {0x803F, SIERRA_SDFILT_H2L_A_PREG},
> + {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
> + {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
> + {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
> +};
> +
> +static struct cdns_sierra_vals pcie_100_int_ssc_plllc_cmn_vals = {
> + .reg_pairs = pcie_100_int_ssc_plllc_cmn_regs,
> + .num_regs = ARRAY_SIZE(pcie_100_int_ssc_plllc_cmn_regs),
> +};
> +
> +static struct cdns_sierra_vals ml_pcie_100_int_ssc_ln_vals = {
> + .reg_pairs = ml_pcie_100_int_ssc_ln_regs,
> + .num_regs = ARRAY_SIZE(ml_pcie_100_int_ssc_ln_regs),
> +};
> +
> +/* refclk100MHz_32b_PCIe_cmn_pll_ext_ssc, pcie_links_using_plllc, pipe_bw_3 */
> +static const struct cdns_reg_pairs pcie_100_ext_ssc_plllc_cmn_regs[] = {
> + {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> + {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
> + {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
> + {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
> + {0x1B1B, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG}
> +};
> +
> +/*
> + * refclk100MHz_32b_PCIe_ln_ext_ssc, multilink, using_plllc,
> + * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz
> + */
> +static const struct cdns_reg_pairs ml_pcie_100_ext_ssc_ln_regs[] = {
> + {0xFC08, SIERRA_DET_STANDEC_A_PREG},
> + {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
> + {0x0004, SIERRA_PSC_LN_A3_PREG},
> + {0x0004, SIERRA_PSC_LN_A4_PREG},
> + {0x0004, SIERRA_PSC_LN_IDLE_PREG},
> + {0x1555, SIERRA_DFE_BIASTRIM_PREG},
> + {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
> + {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
> + {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
> + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
> + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
> + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
> + {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
> + {0x9800, SIERRA_RX_CTLE_CAL_PREG},
> + {0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
> + {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
> + {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
> + {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
> + {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
> + {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
> + {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
> + {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
> + {0x0041, SIERRA_DEQ_GLUT0},
> + {0x0082, SIERRA_DEQ_GLUT1},
> + {0x00C3, SIERRA_DEQ_GLUT2},
> + {0x0145, SIERRA_DEQ_GLUT3},
> + {0x0186, SIERRA_DEQ_GLUT4},
> + {0x09E7, SIERRA_DEQ_ALUT0},
> + {0x09A6, SIERRA_DEQ_ALUT1},
> + {0x0965, SIERRA_DEQ_ALUT2},
> + {0x08E3, SIERRA_DEQ_ALUT3},
> + {0x00FA, SIERRA_DEQ_DFETAP0},
> + {0x00FA, SIERRA_DEQ_DFETAP1},
> + {0x00FA, SIERRA_DEQ_DFETAP2},
> + {0x00FA, SIERRA_DEQ_DFETAP3},
> + {0x00FA, SIERRA_DEQ_DFETAP4},
> + {0x000F, SIERRA_DEQ_PRECUR_PREG},
> + {0x0280, SIERRA_DEQ_POSTCUR_PREG},
> + {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
> + {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
> + {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
> + {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
> + {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
> + {0x002B, SIERRA_CPI_TRIM_PREG},
> + {0x0003, SIERRA_EPI_CTRL_PREG},
> + {0x803F, SIERRA_SDFILT_H2L_A_PREG},
> + {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
> + {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
> + {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
> +};
> +
> +static struct cdns_sierra_vals pcie_100_ext_ssc_plllc_cmn_vals = {
> + .reg_pairs = pcie_100_ext_ssc_plllc_cmn_regs,
> + .num_regs = ARRAY_SIZE(pcie_100_ext_ssc_plllc_cmn_regs),
> +};
> +
> +static struct cdns_sierra_vals ml_pcie_100_ext_ssc_ln_vals = {
> + .reg_pairs = ml_pcie_100_ext_ssc_ln_regs,
> + .num_regs = ARRAY_SIZE(ml_pcie_100_ext_ssc_ln_regs),
> +};
> +
> /* refclk100MHz_32b_PCIe_cmn_pll_no_ssc */
> static const struct cdns_reg_pairs cdns_pcie_cmn_regs_no_ssc[] = {
> {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> @@ -1710,6 +2018,11 @@ static const struct cdns_sierra_data cdns_map_sierra = {
> [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
> [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
> },
> + [TYPE_QSGMII] = {
> + [NO_SSC] = &pcie_phy_pcs_cmn_vals,
> + [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
> + [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
> + },
> },
> },
> .pma_cmn_vals = {
> @@ -1719,12 +2032,24 @@ static const struct cdns_sierra_data cdns_map_sierra = {
> [EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals,
> [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals,
> },
> + [TYPE_QSGMII] = {

so this is pcie->qsgmii ->ssc/external/internal ... ok

> + [NO_SSC] = &pcie_100_no_ssc_plllc_cmn_vals,
> + [EXTERNAL_SSC] = &pcie_100_ext_ssc_plllc_cmn_vals,
> + [INTERNAL_SSC] = &pcie_100_int_ssc_plllc_cmn_vals,
> + },
> },
> [TYPE_USB] = {
> [TYPE_NONE] = {
> [EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals,
> },
> },
> + [TYPE_QSGMII] = {
> + [TYPE_PCIE] = {

now it is reverse! qsgmii -> pcie -> ... why?

what is meant by pcie->qsgmii and qsgmii-> pcie?

--
~Vinod

Subject: RE: [PATCH v3 02/15] phy: cadence: Sierra: Prepare driver to add support for multilink configurations

Hi Vinod,

> -----Original Message-----
> From: Vinod Koul <[email protected]>
> Sent: Tuesday, November 23, 2021 10:03 AM
> To: Swapnil Kashinath Jakhade <[email protected]>
> Cc: [email protected]; [email protected]; [email protected]; linux-
> [email protected]; [email protected];
> [email protected]; Milind Parab <[email protected]>; a-
> [email protected]
> Subject: Re: [PATCH v3 02/15] phy: cadence: Sierra: Prepare driver to add
> support for multilink configurations
>
> EXTERNAL MAIL
>
>
> On 22-10-21, 19:02, Swapnil Jakhade wrote:
> > Sierra driver currently supports single link configurations only.
> > Prepare driver to support multilink multiprotocol configurations along
> > with different SSC modes.
> >
> > Signed-off-by: Swapnil Jakhade <[email protected]>
> > Reviewed-by: Aswath Govindraju <[email protected]>
> > ---
> > drivers/phy/cadence/phy-cadence-sierra.c | 195
> > ++++++++++++++++-------
> > 1 file changed, 139 insertions(+), 56 deletions(-)
> >
> > diff --git a/drivers/phy/cadence/phy-cadence-sierra.c
> > b/drivers/phy/cadence/phy-cadence-sierra.c
> > index 54d1c63932ac..c82ac6716f5e 100644
> > --- a/drivers/phy/cadence/phy-cadence-sierra.c
> > +++ b/drivers/phy/cadence/phy-cadence-sierra.c
> > @@ -23,6 +23,9 @@
> > #include <dt-bindings/phy/phy.h>
> > #include <dt-bindings/phy/phy-cadence.h>
> >
> > +#define NUM_SSC_MODE 3
> > +#define NUM_PHY_TYPE 3
> > +
> > /* PHY register offsets */
> > #define SIERRA_COMMON_CDB_OFFSET 0x0
> > #define SIERRA_MACRO_ID_REG 0x0
> > @@ -217,9 +220,21 @@ static const int
> > pll_mux_parent_index[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
> >
> > static u32 cdns_sierra_pll_mux_table[] = { 0, 1 };
> >
> > +enum cdns_sierra_phy_type {
> > + TYPE_NONE,
>
> What does NONE type mean?

TYPE_NONE is used to denote single link configuration.
e.g. [TYPE_PCIE][TYPE_NONE] denotes single link PCIe configuration.

>
> > + TYPE_PCIE,
> > + TYPE_USB
> > +};
> > +
> > +enum cdns_sierra_ssc_mode {
> > + NO_SSC,
> > + EXTERNAL_SSC,
> > + INTERNAL_SSC
> > +};
> > +
> > struct cdns_sierra_inst {
> > struct phy *phy;
> > - u32 phy_type;
> > + enum cdns_sierra_phy_type phy_type;
> > u32 num_lanes;
> > u32 mlane;
> > struct reset_control *lnk_rst;
> > @@ -230,18 +245,19 @@ struct cdns_reg_pairs {
> > u32 off;
> > };
> >
> > +struct cdns_sierra_vals {
> > + const struct cdns_reg_pairs *reg_pairs;
> > + u32 num_regs;
> > +};
> > +
> > struct cdns_sierra_data {
> > - u32 id_value;
> > - u8 block_offset_shift;
> > - u8 reg_offset_shift;
> > - u32 pcie_cmn_regs;
> > - u32 pcie_ln_regs;
> > - u32 usb_cmn_regs;
> > - u32 usb_ln_regs;
> > - const struct cdns_reg_pairs *pcie_cmn_vals;
> > - const struct cdns_reg_pairs *pcie_ln_vals;
> > - const struct cdns_reg_pairs *usb_cmn_vals;
> > - const struct cdns_reg_pairs *usb_ln_vals;
> > + u32 id_value;
> > + u8 block_offset_shift;
> > + u8 reg_offset_shift;
> > + struct cdns_sierra_vals
> *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
> > + [NUM_SSC_MODE];
> > + struct cdns_sierra_vals
> *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
> > + [NUM_SSC_MODE];
>
> You have defined phy type and ssc, that sounds fine, I am not sure why you
> need a third dimension here? What purpose does it solve?

PHY can be configured to support max 2 protocols simultaneously, so there
are two PHY_TYPE dimensions.

Thanks & regards,
Swapnil

>
> > };
> >
> > struct cdns_regmap_cdb_context {
> > @@ -341,10 +357,14 @@ static int cdns_sierra_phy_init(struct phy
> > *gphy) {
> > struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
> > struct cdns_sierra_phy *phy = dev_get_drvdata(gphy->dev.parent);
> > + const struct cdns_sierra_data *init_data = phy->init_data;
> > + struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
> > + enum cdns_sierra_phy_type phy_type = ins->phy_type;
> > + enum cdns_sierra_ssc_mode ssc = EXTERNAL_SSC;
> > + const struct cdns_reg_pairs *reg_pairs;
> > struct regmap *regmap;
> > + u32 num_regs;
> > int i, j;
> > - const struct cdns_reg_pairs *cmn_vals, *ln_vals;
> > - u32 num_cmn_regs, num_ln_regs;
> >
> > /* Initialise the PHY registers, unless auto configured */
> > if (phy->autoconf)
> > @@ -352,28 +372,26 @@ static int cdns_sierra_phy_init(struct phy
> > *gphy)
> >
> > clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
> > clk_set_rate(phy->input_clks[CMN_REFCLK1_DIG_DIV], 25000000);
> > - if (ins->phy_type == PHY_TYPE_PCIE) {
> > - num_cmn_regs = phy->init_data->pcie_cmn_regs;
> > - num_ln_regs = phy->init_data->pcie_ln_regs;
> > - cmn_vals = phy->init_data->pcie_cmn_vals;
> > - ln_vals = phy->init_data->pcie_ln_vals;
> > - } else if (ins->phy_type == PHY_TYPE_USB3) {
> > - num_cmn_regs = phy->init_data->usb_cmn_regs;
> > - num_ln_regs = phy->init_data->usb_ln_regs;
> > - cmn_vals = phy->init_data->usb_cmn_vals;
> > - ln_vals = phy->init_data->usb_ln_vals;
> > - } else {
> > - return -EINVAL;
> > - }
> >
> > - regmap = phy->regmap_common_cdb;
> > - for (j = 0; j < num_cmn_regs ; j++)
> > - regmap_write(regmap, cmn_vals[j].off, cmn_vals[j].val);
> > + /* PMA common registers configurations */
> > + pma_cmn_vals = init_data-
> >pma_cmn_vals[phy_type][TYPE_NONE][ssc];
> > + if (pma_cmn_vals) {
> > + reg_pairs = pma_cmn_vals->reg_pairs;
> > + num_regs = pma_cmn_vals->num_regs;
> > + regmap = phy->regmap_common_cdb;
> > + for (i = 0; i < num_regs; i++)
> > + regmap_write(regmap, reg_pairs[i].off,
> reg_pairs[i].val);
> > + }
> >
> > - for (i = 0; i < ins->num_lanes; i++) {
> > - for (j = 0; j < num_ln_regs ; j++) {
> > + /* PMA lane registers configurations */
> > + pma_ln_vals = init_data->pma_ln_vals[phy_type][TYPE_NONE][ssc];
> > + if (pma_ln_vals) {
> > + reg_pairs = pma_ln_vals->reg_pairs;
> > + num_regs = pma_ln_vals->num_regs;
> > + for (i = 0; i < ins->num_lanes; i++) {
> > regmap = phy->regmap_lane_cdb[i + ins->mlane];
> > - regmap_write(regmap, ln_vals[j].off, ln_vals[j].val);
> > + for (j = 0; j < num_regs; j++)
> > + regmap_write(regmap, reg_pairs[j].off,
> reg_pairs[j].val);
> > }
> > }
> >
> > @@ -583,15 +601,28 @@ static int cdns_sierra_clk_register(struct
> > cdns_sierra_phy *sp) static int cdns_sierra_get_optional(struct
> cdns_sierra_inst *inst,
> > struct device_node *child)
> > {
> > + u32 phy_type;
> > +
> > if (of_property_read_u32(child, "reg", &inst->mlane))
> > return -EINVAL;
> >
> > if (of_property_read_u32(child, "cdns,num-lanes", &inst-
> >num_lanes))
> > return -EINVAL;
> >
> > - if (of_property_read_u32(child, "cdns,phy-type", &inst->phy_type))
> > + if (of_property_read_u32(child, "cdns,phy-type", &phy_type))
> > return -EINVAL;
> >
> > + switch (phy_type) {
> > + case PHY_TYPE_PCIE:
> > + inst->phy_type = TYPE_PCIE;
> > + break;
> > + case PHY_TYPE_USB3:
> > + inst->phy_type = TYPE_USB;
> > + break;
> > + default:
> > + return -EINVAL;
> > + }
> > +
> > return 0;
> > }
> >
> > @@ -1006,6 +1037,16 @@ static const struct cdns_reg_pairs
> cdns_pcie_ln_regs_ext_ssc[] = {
> > {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG}
> > };
> >
> > +static struct cdns_sierra_vals pcie_100_ext_ssc_cmn_vals = {
> > + .reg_pairs = cdns_pcie_cmn_regs_ext_ssc,
> > + .num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
> > +};
> > +
> > +static struct cdns_sierra_vals pcie_100_ext_ssc_ln_vals = {
> > + .reg_pairs = cdns_pcie_ln_regs_ext_ssc,
> > + .num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
> > +};
> > +
> > /* refclk100MHz_20b_USB_cmn_pll_ext_ssc */ static const struct
> > cdns_reg_pairs cdns_usb_cmn_regs_ext_ssc[] = {
> > {0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> > @@ -1113,32 +1154,74 @@ static const struct cdns_reg_pairs
> cdns_usb_ln_regs_ext_ssc[] = {
> > {0x4243, SIERRA_RXBUFFER_DFECTRL_PREG} };
> >
> > +static struct cdns_sierra_vals usb_100_ext_ssc_cmn_vals = {
> > + .reg_pairs = cdns_usb_cmn_regs_ext_ssc,
> > + .num_regs = ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
> > +};
> > +
> > +static struct cdns_sierra_vals usb_100_ext_ssc_ln_vals = {
> > + .reg_pairs = cdns_usb_ln_regs_ext_ssc,
> > + .num_regs = ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
> > +};
> > +
> > static const struct cdns_sierra_data cdns_map_sierra = {
> > - SIERRA_MACRO_ID,
> > - 0x2,
> > - 0x2,
> > - ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
> > - ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
> > - ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
> > - ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
> > - cdns_pcie_cmn_regs_ext_ssc,
> > - cdns_pcie_ln_regs_ext_ssc,
> > - cdns_usb_cmn_regs_ext_ssc,
> > - cdns_usb_ln_regs_ext_ssc,
> > + .id_value = SIERRA_MACRO_ID,
> > + .block_offset_shift = 0x2,
> > + .reg_offset_shift = 0x2,
> > + .pma_cmn_vals = {
> > + [TYPE_PCIE] = {
> > + [TYPE_NONE] = {
> > + [EXTERNAL_SSC] =
> &pcie_100_ext_ssc_cmn_vals,
> > + },
> > + },
> > + [TYPE_USB] = {
> > + [TYPE_NONE] = {
> > + [EXTERNAL_SSC] =
> &usb_100_ext_ssc_cmn_vals,
> > + },
> > + },
> > + },
> > + .pma_ln_vals = {
> > + [TYPE_PCIE] = {
> > + [TYPE_NONE] = {
> > + [EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
> > + },
> > + },
> > + [TYPE_USB] = {
> > + [TYPE_NONE] = {
> > + [EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals,
> > + },
> > + },
> > + },
> > };
> >
> > static const struct cdns_sierra_data cdns_ti_map_sierra = {
> > - SIERRA_MACRO_ID,
> > - 0x0,
> > - 0x1,
> > - ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
> > - ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
> > - ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
> > - ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
> > - cdns_pcie_cmn_regs_ext_ssc,
> > - cdns_pcie_ln_regs_ext_ssc,
> > - cdns_usb_cmn_regs_ext_ssc,
> > - cdns_usb_ln_regs_ext_ssc,
> > + .id_value = SIERRA_MACRO_ID,
> > + .block_offset_shift = 0x0,
> > + .reg_offset_shift = 0x1,
> > + .pma_cmn_vals = {
> > + [TYPE_PCIE] = {
> > + [TYPE_NONE] = {
> > + [EXTERNAL_SSC] =
> &pcie_100_ext_ssc_cmn_vals,
> > + },
> > + },
> > + [TYPE_USB] = {
> > + [TYPE_NONE] = {
> > + [EXTERNAL_SSC] =
> &usb_100_ext_ssc_cmn_vals,
> > + },
> > + },
> > + },
> > + .pma_ln_vals = {
> > + [TYPE_PCIE] = {
> > + [TYPE_NONE] = {
> > + [EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals,
> > + },
> > + },
> > + [TYPE_USB] = {
> > + [TYPE_NONE] = {
> > + [EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals,
> > + },
> > + },
> > + },
> > };
> >
> > static const struct of_device_id cdns_sierra_id_table[] = {
> > --
> > 2.26.1
>
> --
> ~Vinod

Subject: RE: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

Hi Vinod,

> -----Original Message-----
> From: Vinod Koul <[email protected]>
> Sent: Tuesday, November 23, 2021 10:18 AM
> To: Swapnil Kashinath Jakhade <[email protected]>
> Cc: [email protected]; [email protected]; [email protected]; linux-
> [email protected]; [email protected];
> [email protected]; Milind Parab <[email protected]>; a-
> [email protected]
> Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY
> multilink configuration
>
> EXTERNAL MAIL
>
>
> On 22-10-21, 19:02, Swapnil Jakhade wrote:
> > Add register sequences for PCIe + QSGMII PHY multilink configuration.
> >
> > Signed-off-by: Swapnil Jakhade <[email protected]>
> > Reviewed-by: Aswath Govindraju <[email protected]>
> > ---
> > drivers/phy/cadence/phy-cadence-sierra.c | 377
> > ++++++++++++++++++++++-
> > 1 file changed, 376 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/phy/cadence/phy-cadence-sierra.c
> > b/drivers/phy/cadence/phy-cadence-sierra.c
> > index a39be67424a1..0deb627845b1 100644
> > --- a/drivers/phy/cadence/phy-cadence-sierra.c
> > +++ b/drivers/phy/cadence/phy-cadence-sierra.c
> > @@ -45,6 +45,9 @@
> > #define SIERRA_CMN_REFRCV_PREG 0x98
> > #define SIERRA_CMN_REFRCV1_PREG 0xB8
> > #define SIERRA_CMN_PLLLC1_GEN_PREG 0xC2
> > +#define SIERRA_CMN_PLLLC1_LF_COEFF_MODE0_PREG 0xCA
> > +#define SIERRA_CMN_PLLLC1_BWCAL_MODE0_PREG 0xD0
> > +#define SIERRA_CMN_PLLLC1_SS_TIME_STEPSIZE_MODE_PREG 0xE2
> >
> > #define SIERRA_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \
> > ((0x4000 << (block_offset)) + \
> > @@ -59,6 +62,9 @@
> > #define SIERRA_PSM_A0IN_TMR_PREG 0x009
> > #define SIERRA_PSM_A3IN_TMR_PREG 0x00C
> > #define SIERRA_PSM_DIAG_PREG 0x015
> > +#define SIERRA_PSC_LN_A3_PREG 0x023
> > +#define SIERRA_PSC_LN_A4_PREG 0x024
> > +#define SIERRA_PSC_LN_IDLE_PREG 0x026
> > #define SIERRA_PSC_TX_A0_PREG 0x028
> > #define SIERRA_PSC_TX_A1_PREG 0x029
> > #define SIERRA_PSC_TX_A2_PREG 0x02A
> > @@ -68,6 +74,7 @@
> > #define SIERRA_PSC_RX_A2_PREG 0x032
> > #define SIERRA_PSC_RX_A3_PREG 0x033
> > #define SIERRA_PLLCTRL_SUBRATE_PREG 0x03A
> > +#define SIERRA_PLLCTRL_GEN_A_PREG 0x03B
> > #define SIERRA_PLLCTRL_GEN_D_PREG 0x03E
> > #define SIERRA_PLLCTRL_CPGAIN_MODE_PREG 0x03F
> > #define SIERRA_PLLCTRL_STATUS_PREG 0x044
> > @@ -150,6 +157,7 @@
> > #define SIERRA_CPICAL_TMRVAL_MODE0_PREG 0x171
> > #define SIERRA_CPICAL_PICNT_MODE1_PREG 0x174
> > #define SIERRA_CPI_OUTBUF_RATESEL_PREG 0x17C
> > +#define SIERRA_CPI_RESBIAS_BIN_PREG 0x17E
> > #define SIERRA_CPI_TRIM_PREG 0x17F
> > #define SIERRA_CPICAL_RES_STARTCODE_MODE23_PREG 0x183
> > #define SIERRA_EPI_CTRL_PREG 0x187
> > @@ -272,7 +280,8 @@ static u32
> > cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = { enum
> cdns_sierra_phy_type {
> > TYPE_NONE,
> > TYPE_PCIE,
> > - TYPE_USB
> > + TYPE_USB,
> > + TYPE_QSGMII
> > };
> >
> > enum cdns_sierra_ssc_mode {
> > @@ -807,6 +816,9 @@ static int cdns_sierra_get_optional(struct
> cdns_sierra_inst *inst,
> > case PHY_TYPE_USB3:
> > inst->phy_type = TYPE_USB;
> > break;
> > + case PHY_TYPE_QSGMII:
> > + inst->phy_type = TYPE_QSGMII;
> > + break;
> > default:
> > return -EINVAL;
> > }
> > @@ -1186,6 +1198,9 @@ static int
> cdns_sierra_phy_configure_multilink(struct cdns_sierra_phy *sp)
> > regmap_write(regmap,
> reg_pairs[j].off, reg_pairs[j].val);
> > }
> > }
> > +
> > + if (phy_t1 == TYPE_QSGMII)
> > + reset_control_deassert(sp->phys[node].lnk_rst);
> > }
> >
> > /* Take the PHY out of reset */
> > @@ -1363,6 +1378,72 @@ static int cdns_sierra_phy_remove(struct
> platform_device *pdev)
> > return 0;
> > }
> >
> > +/* QSGMII PHY PMA lane configuration */ static struct cdns_reg_pairs
> > +qsgmii_phy_pma_ln_regs[] = {
> > + {0x9010, SIERRA_PHY_PMA_XCVR_CTRL}
> > +};
> > +
> > +static struct cdns_sierra_vals qsgmii_phy_pma_ln_vals = {
> > + .reg_pairs = qsgmii_phy_pma_ln_regs,
> > + .num_regs = ARRAY_SIZE(qsgmii_phy_pma_ln_regs),
> > +};
> > +
> > +/* QSGMII refclk 100MHz, 20b, opt1, No BW cal, no ssc, PLL LC1 */
> > +static const struct cdns_reg_pairs qsgmii_100_no_ssc_plllc1_cmn_regs[] =
> {
> > + {0x2085, SIERRA_CMN_PLLLC1_LF_COEFF_MODE0_PREG},
> > + {0x0000, SIERRA_CMN_PLLLC1_BWCAL_MODE0_PREG},
> > + {0x0000, SIERRA_CMN_PLLLC1_SS_TIME_STEPSIZE_MODE_PREG}
> > +};
> > +
> > +static const struct cdns_reg_pairs qsgmii_100_no_ssc_plllc1_ln_regs[] = {
> > + {0xFC08, SIERRA_DET_STANDEC_A_PREG},
> > + {0x0252, SIERRA_DET_STANDEC_E_PREG},
> > + {0x0004, SIERRA_PSC_LN_IDLE_PREG},
> > + {0x0FFE, SIERRA_PSC_RX_A0_PREG},
> > + {0x0011, SIERRA_PLLCTRL_SUBRATE_PREG},
> > + {0x0001, SIERRA_PLLCTRL_GEN_A_PREG},
> > + {0x5233, SIERRA_PLLCTRL_CPGAIN_MODE_PREG},
> > + {0x0000, SIERRA_DRVCTRL_ATTEN_PREG},
> > + {0x0089, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
> > + {0x3C3C, SIERRA_CREQ_CCLKDET_MODE01_PREG},
> > + {0x3222, SIERRA_CREQ_FSMCLK_SEL_PREG},
> > + {0x0000, SIERRA_CREQ_EQ_CTRL_PREG},
> > + {0x8422, SIERRA_CTLELUT_CTRL_PREG},
> > + {0x4111, SIERRA_DFE_ECMP_RATESEL_PREG},
> > + {0x4111, SIERRA_DFE_SMP_RATESEL_PREG},
> > + {0x0002, SIERRA_DEQ_PHALIGN_CTRL},
> > + {0x9595, SIERRA_DEQ_VGATUNE_CTRL_PREG},
> > + {0x0186, SIERRA_DEQ_GLUT0},
> > + {0x0186, SIERRA_DEQ_GLUT1},
> > + {0x0186, SIERRA_DEQ_GLUT2},
> > + {0x0186, SIERRA_DEQ_GLUT3},
> > + {0x0186, SIERRA_DEQ_GLUT4},
> > + {0x0861, SIERRA_DEQ_ALUT0},
> > + {0x07E0, SIERRA_DEQ_ALUT1},
> > + {0x079E, SIERRA_DEQ_ALUT2},
> > + {0x071D, SIERRA_DEQ_ALUT3},
> > + {0x03F5, SIERRA_DEQ_DFETAP_CTRL_PREG},
> > + {0x0C01, SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG},
> > + {0x3C40, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
> > + {0x1C04, SIERRA_DEQ_TAU_CTRL2_PREG},
> > + {0x0033, SIERRA_DEQ_PICTRL_PREG},
> > + {0x0660, SIERRA_CPICAL_TMRVAL_MODE0_PREG},
> > + {0x00D5, SIERRA_CPI_OUTBUF_RATESEL_PREG},
> > + {0x0B6D, SIERRA_CPI_RESBIAS_BIN_PREG},
> > + {0x0102, SIERRA_RXBUFFER_CTLECTRL_PREG},
> > + {0x0002, SIERRA_RXBUFFER_RCDFECTRL_PREG} };
> > +
> > +static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_cmn_vals = {
> > + .reg_pairs = qsgmii_100_no_ssc_plllc1_cmn_regs,
> > + .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_cmn_regs),
> > +};
> > +
> > +static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_ln_vals = {
> > + .reg_pairs = qsgmii_100_no_ssc_plllc1_ln_regs,
> > + .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_ln_regs),
> > +};
> > +
> > /* PCIE PHY PCS common configuration */ static struct cdns_reg_pairs
> > pcie_phy_pcs_cmn_regs[] = {
> > {0x0430, SIERRA_PHY_PIPE_CMN_CTRL1}
> > @@ -1373,6 +1454,233 @@ static struct cdns_sierra_vals
> pcie_phy_pcs_cmn_vals = {
> > .num_regs = ARRAY_SIZE(pcie_phy_pcs_cmn_regs),
> > };
> >
> > +/* refclk100MHz_32b_PCIe_cmn_pll_no_ssc, pcie_links_using_plllc,
> > +pipe_bw_3 */ static const struct cdns_reg_pairs
> pcie_100_no_ssc_plllc_cmn_regs[] = {
> > + {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> > + {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
> > + {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
> > + {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG}
> > +};
> > +
> > +/*
> > + * refclk100MHz_32b_PCIe_ln_no_ssc, multilink, using_plllc,
> > + * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz */ static const
> > +struct cdns_reg_pairs ml_pcie_100_no_ssc_ln_regs[] = {
> > + {0xFC08, SIERRA_DET_STANDEC_A_PREG},
> > + {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
> > + {0x0004, SIERRA_PSC_LN_A3_PREG},
> > + {0x0004, SIERRA_PSC_LN_A4_PREG},
> > + {0x0004, SIERRA_PSC_LN_IDLE_PREG},
> > + {0x1555, SIERRA_DFE_BIASTRIM_PREG},
> > + {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
> > + {0x8055, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
> > + {0x80BB, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
> > + {0x8351, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
> > + {0x8349, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
> > + {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
> > + {0x9800, SIERRA_RX_CTLE_CAL_PREG},
> > + {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
> > + {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
> > + {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
> > + {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
> > + {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
> > + {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
> > + {0x0041, SIERRA_DEQ_GLUT0},
> > + {0x0082, SIERRA_DEQ_GLUT1},
> > + {0x00C3, SIERRA_DEQ_GLUT2},
> > + {0x0145, SIERRA_DEQ_GLUT3},
> > + {0x0186, SIERRA_DEQ_GLUT4},
> > + {0x09E7, SIERRA_DEQ_ALUT0},
> > + {0x09A6, SIERRA_DEQ_ALUT1},
> > + {0x0965, SIERRA_DEQ_ALUT2},
> > + {0x08E3, SIERRA_DEQ_ALUT3},
> > + {0x00FA, SIERRA_DEQ_DFETAP0},
> > + {0x00FA, SIERRA_DEQ_DFETAP1},
> > + {0x00FA, SIERRA_DEQ_DFETAP2},
> > + {0x00FA, SIERRA_DEQ_DFETAP3},
> > + {0x00FA, SIERRA_DEQ_DFETAP4},
> > + {0x000F, SIERRA_DEQ_PRECUR_PREG},
> > + {0x0280, SIERRA_DEQ_POSTCUR_PREG},
> > + {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
> > + {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
> > + {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
> > + {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
> > + {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
> > + {0x002B, SIERRA_CPI_TRIM_PREG},
> > + {0x0003, SIERRA_EPI_CTRL_PREG},
> > + {0x803F, SIERRA_SDFILT_H2L_A_PREG},
> > + {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
> > + {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
> > + {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} };
> > +
> > +static struct cdns_sierra_vals pcie_100_no_ssc_plllc_cmn_vals = {
> > + .reg_pairs = pcie_100_no_ssc_plllc_cmn_regs,
> > + .num_regs = ARRAY_SIZE(pcie_100_no_ssc_plllc_cmn_regs),
> > +};
> > +
> > +static struct cdns_sierra_vals ml_pcie_100_no_ssc_ln_vals = {
> > + .reg_pairs = ml_pcie_100_no_ssc_ln_regs,
> > + .num_regs = ARRAY_SIZE(ml_pcie_100_no_ssc_ln_regs),
> > +};
> > +
> > +/* refclk100MHz_32b_PCIe_cmn_pll_int_ssc, pcie_links_using_plllc,
> > +pipe_bw_3 */ static const struct cdns_reg_pairs
> pcie_100_int_ssc_plllc_cmn_regs[] = {
> > + {0x000E, SIERRA_CMN_PLLLC_MODE_PREG},
> > + {0x4006, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> > + {0x4006, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
> > + {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
> > + {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
> > + {0x0581, SIERRA_CMN_PLLLC_DSMCORR_PREG},
> > + {0x7F80, SIERRA_CMN_PLLLC_SS_PREG},
> > + {0x0041, SIERRA_CMN_PLLLC_SS_AMP_STEP_SIZE_PREG},
> > + {0x0464, SIERRA_CMN_PLLLC_SSTWOPT_PREG},
> > + {0x0D0D, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG},
> > + {0x0060, SIERRA_CMN_PLLLC_LOCK_DELAY_CTRL_PREG}
> > +};
> > +
> > +/*
> > + * refclk100MHz_32b_PCIe_ln_int_ssc, multilink, using_plllc,
> > + * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz */ static const
> > +struct cdns_reg_pairs ml_pcie_100_int_ssc_ln_regs[] = {
> > + {0xFC08, SIERRA_DET_STANDEC_A_PREG},
> > + {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
> > + {0x0004, SIERRA_PSC_LN_A3_PREG},
> > + {0x0004, SIERRA_PSC_LN_A4_PREG},
> > + {0x0004, SIERRA_PSC_LN_IDLE_PREG},
> > + {0x1555, SIERRA_DFE_BIASTRIM_PREG},
> > + {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
> > + {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
> > + {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
> > + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
> > + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
> > + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
> > + {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
> > + {0x9800, SIERRA_RX_CTLE_CAL_PREG},
> > + {0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
> > + {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
> > + {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
> > + {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
> > + {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
> > + {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
> > + {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
> > + {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
> > + {0x0041, SIERRA_DEQ_GLUT0},
> > + {0x0082, SIERRA_DEQ_GLUT1},
> > + {0x00C3, SIERRA_DEQ_GLUT2},
> > + {0x0145, SIERRA_DEQ_GLUT3},
> > + {0x0186, SIERRA_DEQ_GLUT4},
> > + {0x09E7, SIERRA_DEQ_ALUT0},
> > + {0x09A6, SIERRA_DEQ_ALUT1},
> > + {0x0965, SIERRA_DEQ_ALUT2},
> > + {0x08E3, SIERRA_DEQ_ALUT3},
> > + {0x00FA, SIERRA_DEQ_DFETAP0},
> > + {0x00FA, SIERRA_DEQ_DFETAP1},
> > + {0x00FA, SIERRA_DEQ_DFETAP2},
> > + {0x00FA, SIERRA_DEQ_DFETAP3},
> > + {0x00FA, SIERRA_DEQ_DFETAP4},
> > + {0x000F, SIERRA_DEQ_PRECUR_PREG},
> > + {0x0280, SIERRA_DEQ_POSTCUR_PREG},
> > + {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
> > + {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
> > + {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
> > + {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
> > + {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
> > + {0x002B, SIERRA_CPI_TRIM_PREG},
> > + {0x0003, SIERRA_EPI_CTRL_PREG},
> > + {0x803F, SIERRA_SDFILT_H2L_A_PREG},
> > + {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
> > + {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
> > + {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} };
> > +
> > +static struct cdns_sierra_vals pcie_100_int_ssc_plllc_cmn_vals = {
> > + .reg_pairs = pcie_100_int_ssc_plllc_cmn_regs,
> > + .num_regs = ARRAY_SIZE(pcie_100_int_ssc_plllc_cmn_regs),
> > +};
> > +
> > +static struct cdns_sierra_vals ml_pcie_100_int_ssc_ln_vals = {
> > + .reg_pairs = ml_pcie_100_int_ssc_ln_regs,
> > + .num_regs = ARRAY_SIZE(ml_pcie_100_int_ssc_ln_regs),
> > +};
> > +
> > +/* refclk100MHz_32b_PCIe_cmn_pll_ext_ssc, pcie_links_using_plllc,
> > +pipe_bw_3 */ static const struct cdns_reg_pairs
> pcie_100_ext_ssc_plllc_cmn_regs[] = {
> > + {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> > + {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
> > + {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
> > + {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
> > + {0x1B1B, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG}
> > +};
> > +
> > +/*
> > + * refclk100MHz_32b_PCIe_ln_ext_ssc, multilink, using_plllc,
> > + * cmn_pllcy_anaclk0_1Ghz, xcvr_pllclk_fullrt_500mhz */ static const
> > +struct cdns_reg_pairs ml_pcie_100_ext_ssc_ln_regs[] = {
> > + {0xFC08, SIERRA_DET_STANDEC_A_PREG},
> > + {0x001D, SIERRA_PSM_A3IN_TMR_PREG},
> > + {0x0004, SIERRA_PSC_LN_A3_PREG},
> > + {0x0004, SIERRA_PSC_LN_A4_PREG},
> > + {0x0004, SIERRA_PSC_LN_IDLE_PREG},
> > + {0x1555, SIERRA_DFE_BIASTRIM_PREG},
> > + {0x9703, SIERRA_DRVCTRL_BOOST_PREG},
> > + {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
> > + {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
> > + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
> > + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
> > + {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
> > + {0x0002, SIERRA_CREQ_DCBIASATTEN_OVR_PREG},
> > + {0x9800, SIERRA_RX_CTLE_CAL_PREG},
> > + {0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
> > + {0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
> > + {0x5624, SIERRA_DEQ_CONCUR_CTRL2_PREG},
> > + {0x000F, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
> > + {0x00FF, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
> > + {0x4C4C, SIERRA_DEQ_ERRCMP_CTRL_PREG},
> > + {0x02FA, SIERRA_DEQ_OFFSET_CTRL_PREG},
> > + {0x02FA, SIERRA_DEQ_GAIN_CTRL_PREG},
> > + {0x0041, SIERRA_DEQ_GLUT0},
> > + {0x0082, SIERRA_DEQ_GLUT1},
> > + {0x00C3, SIERRA_DEQ_GLUT2},
> > + {0x0145, SIERRA_DEQ_GLUT3},
> > + {0x0186, SIERRA_DEQ_GLUT4},
> > + {0x09E7, SIERRA_DEQ_ALUT0},
> > + {0x09A6, SIERRA_DEQ_ALUT1},
> > + {0x0965, SIERRA_DEQ_ALUT2},
> > + {0x08E3, SIERRA_DEQ_ALUT3},
> > + {0x00FA, SIERRA_DEQ_DFETAP0},
> > + {0x00FA, SIERRA_DEQ_DFETAP1},
> > + {0x00FA, SIERRA_DEQ_DFETAP2},
> > + {0x00FA, SIERRA_DEQ_DFETAP3},
> > + {0x00FA, SIERRA_DEQ_DFETAP4},
> > + {0x000F, SIERRA_DEQ_PRECUR_PREG},
> > + {0x0280, SIERRA_DEQ_POSTCUR_PREG},
> > + {0x8F00, SIERRA_DEQ_POSTCUR_DECR_PREG},
> > + {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
> > + {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG},
> > + {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG},
> > + {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG},
> > + {0x002B, SIERRA_CPI_TRIM_PREG},
> > + {0x0003, SIERRA_EPI_CTRL_PREG},
> > + {0x803F, SIERRA_SDFILT_H2L_A_PREG},
> > + {0x0004, SIERRA_RXBUFFER_CTLECTRL_PREG},
> > + {0x2010, SIERRA_RXBUFFER_RCDFECTRL_PREG},
> > + {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} };
> > +
> > +static struct cdns_sierra_vals pcie_100_ext_ssc_plllc_cmn_vals = {
> > + .reg_pairs = pcie_100_ext_ssc_plllc_cmn_regs,
> > + .num_regs = ARRAY_SIZE(pcie_100_ext_ssc_plllc_cmn_regs),
> > +};
> > +
> > +static struct cdns_sierra_vals ml_pcie_100_ext_ssc_ln_vals = {
> > + .reg_pairs = ml_pcie_100_ext_ssc_ln_regs,
> > + .num_regs = ARRAY_SIZE(ml_pcie_100_ext_ssc_ln_regs),
> > +};
> > +
> > /* refclk100MHz_32b_PCIe_cmn_pll_no_ssc */ static const struct
> > cdns_reg_pairs cdns_pcie_cmn_regs_no_ssc[] = {
> > {0x2105, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
> > @@ -1710,6 +2018,11 @@ static const struct cdns_sierra_data
> cdns_map_sierra = {
> > [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
> > [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
> > },
> > + [TYPE_QSGMII] = {
> > + [NO_SSC] = &pcie_phy_pcs_cmn_vals,
> > + [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
> > + [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals,
> > + },
> > },
> > },
> > .pma_cmn_vals = {
> > @@ -1719,12 +2032,24 @@ static const struct cdns_sierra_data
> cdns_map_sierra = {
> > [EXTERNAL_SSC] =
> &pcie_100_ext_ssc_cmn_vals,
> > [INTERNAL_SSC] =
> &pcie_100_int_ssc_cmn_vals,
> > },
> > + [TYPE_QSGMII] = {
>
> so this is pcie->qsgmii ->ssc/external/internal ... ok
>
> > + [NO_SSC] =
> &pcie_100_no_ssc_plllc_cmn_vals,
> > + [EXTERNAL_SSC] =
> &pcie_100_ext_ssc_plllc_cmn_vals,
> > + [INTERNAL_SSC] =
> &pcie_100_int_ssc_plllc_cmn_vals,
> > + },
> > },
> > [TYPE_USB] = {
> > [TYPE_NONE] = {
> > [EXTERNAL_SSC] =
> &usb_100_ext_ssc_cmn_vals,
> > },
> > },
> > + [TYPE_QSGMII] = {
> > + [TYPE_PCIE] = {
>
> now it is reverse! qsgmii -> pcie -> ... why?
>
> what is meant by pcie->qsgmii and qsgmii-> pcie?
>

Multi-protocol configuration is done in 2 phases, each for one protocol.
e.g. for PCIe + QSGMII case,
[TYPE_PCIE][TYPE_QSGMII] will configure common and lane registers for PCIe and
[TYPE_QSGMII][TYPE_PCIE] will configure common and lane registers for QSGMII.

Thanks & regards,
Swapnil

> --
> ~Vinod

2021-11-25 05:12:44

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

On 24-11-21, 07:33, Swapnil Kashinath Jakhade wrote:

> > so this is pcie->qsgmii ->ssc/external/internal ... ok
> >
> > > + [NO_SSC] =
> > &pcie_100_no_ssc_plllc_cmn_vals,
> > > + [EXTERNAL_SSC] =
> > &pcie_100_ext_ssc_plllc_cmn_vals,
> > > + [INTERNAL_SSC] =
> > &pcie_100_int_ssc_plllc_cmn_vals,
> > > + },
> > > },
> > > [TYPE_USB] = {
> > > [TYPE_NONE] = {
> > > [EXTERNAL_SSC] =
> > &usb_100_ext_ssc_cmn_vals,
> > > },
> > > },
> > > + [TYPE_QSGMII] = {
> > > + [TYPE_PCIE] = {
> >
> > now it is reverse! qsgmii -> pcie -> ... why?
> >
> > what is meant by pcie->qsgmii and qsgmii-> pcie?
> >
>
> Multi-protocol configuration is done in 2 phases, each for one protocol.
> e.g. for PCIe + QSGMII case,
> [TYPE_PCIE][TYPE_QSGMII] will configure common and lane registers for PCIe and
> [TYPE_QSGMII][TYPE_PCIE] will configure common and lane registers for QSGMII.

Then it should be always common + protocol or protocol + common, not
both please! Pls make an order and stick to it everywhere... If that is
not possible, I would like to understand why

--
~Vinod

Subject: RE: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

Hi Vinod,

> -----Original Message-----
> From: Vinod Koul <[email protected]>
> Sent: Thursday, November 25, 2021 10:41 AM
> To: Swapnil Kashinath Jakhade <[email protected]>
> Cc: [email protected]; [email protected]; [email protected]; linux-
> [email protected]; [email protected];
> [email protected]; Milind Parab <[email protected]>; a-
> [email protected]
> Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY
> multilink configuration
>
> EXTERNAL MAIL
>
>
> On 24-11-21, 07:33, Swapnil Kashinath Jakhade wrote:
>
> > > so this is pcie->qsgmii ->ssc/external/internal ... ok
> > >
> > > > + [NO_SSC] =
> > > &pcie_100_no_ssc_plllc_cmn_vals,
> > > > + [EXTERNAL_SSC] =
> > > &pcie_100_ext_ssc_plllc_cmn_vals,
> > > > + [INTERNAL_SSC] =
> > > &pcie_100_int_ssc_plllc_cmn_vals,
> > > > + },
> > > > },
> > > > [TYPE_USB] = {
> > > > [TYPE_NONE] = {
> > > > [EXTERNAL_SSC] =
> > > &usb_100_ext_ssc_cmn_vals,
> > > > },
> > > > },
> > > > + [TYPE_QSGMII] = {
> > > > + [TYPE_PCIE] = {
> > >
> > > now it is reverse! qsgmii -> pcie -> ... why?
> > >
> > > what is meant by pcie->qsgmii and qsgmii-> pcie?
> > >
> >
> > Multi-protocol configuration is done in 2 phases, each for one protocol.
> > e.g. for PCIe + QSGMII case,
> > [TYPE_PCIE][TYPE_QSGMII] will configure common and lane registers for
> > PCIe and [TYPE_QSGMII][TYPE_PCIE] will configure common and lane
> registers for QSGMII.
>
> Then it should be always common + protocol or protocol + common, not
> both please! Pls make an order and stick to it everywhere... If that is not
> possible, I would like to understand why
>

Could you please elaborate what do you mean by
" common + protocol or protocol + common, not both please!"?
The order is same everywhere which is common + lane configuration for protocol 1
and then for protocol 2. For multiprotocol case, PHY configuration is based on which
protocols are operating simultaneously. So e.g.
[TYPE_QSGMII][TYPE_PCIE] -> QSGMII configuration when other protocol is PCIe
Which might be different than
[TYPE_QSGMII][TYPE_*] -> QSGMII configuration with other protocol.

Thanks & regards,
Swapnil

> --
> ~Vinod

2021-12-09 06:11:51

by Milind Parab

[permalink] [raw]
Subject: RE: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

Hi Vinod,

Do you have any further comments on this.
The implementation follows the same approach as is done for Cadence Torrent multiprotocol Phy

Regards,
Milind

>-----Original Message-----
>From: Swapnil Kashinath Jakhade <[email protected]>
>Sent: Thursday, December 2, 2021 7:43 PM
>To: Vinod Koul <[email protected]>
>Cc: [email protected]; [email protected]; [email protected]; linux-
>[email protected]; [email protected];
>[email protected]; Milind Parab <[email protected]>; a-
>[email protected]
>Subject: RE: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY
>multilink configuration
>
>Hi Vinod,
>
>> -----Original Message-----
>> From: Vinod Koul <[email protected]>
>> Sent: Thursday, November 25, 2021 10:41 AM
>> To: Swapnil Kashinath Jakhade <[email protected]>
>> Cc: [email protected]; [email protected]; [email protected]; linux-
>> [email protected]; [email protected];
>> [email protected]; Milind Parab <[email protected]>; a-
>> [email protected]
>> Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII
>> PHY multilink configuration
>>
>> EXTERNAL MAIL
>>
>>
>> On 24-11-21, 07:33, Swapnil Kashinath Jakhade wrote:
>>
>> > > so this is pcie->qsgmii ->ssc/external/internal ... ok
>> > >
>> > > > + [NO_SSC] =
>> > > &pcie_100_no_ssc_plllc_cmn_vals,
>> > > > + [EXTERNAL_SSC] =
>> > > &pcie_100_ext_ssc_plllc_cmn_vals,
>> > > > + [INTERNAL_SSC] =
>> > > &pcie_100_int_ssc_plllc_cmn_vals,
>> > > > + },
>> > > > },
>> > > > [TYPE_USB] = {
>> > > > [TYPE_NONE] = {
>> > > > [EXTERNAL_SSC] =
>> > > &usb_100_ext_ssc_cmn_vals,
>> > > > },
>> > > > },
>> > > > + [TYPE_QSGMII] = {
>> > > > + [TYPE_PCIE] = {
>> > >
>> > > now it is reverse! qsgmii -> pcie -> ... why?
>> > >
>> > > what is meant by pcie->qsgmii and qsgmii-> pcie?
>> > >
>> >
>> > Multi-protocol configuration is done in 2 phases, each for one protocol.
>> > e.g. for PCIe + QSGMII case,
>> > [TYPE_PCIE][TYPE_QSGMII] will configure common and lane registers
>> > for PCIe and [TYPE_QSGMII][TYPE_PCIE] will configure common and lane
>> registers for QSGMII.
>>
>> Then it should be always common + protocol or protocol + common, not
>> both please! Pls make an order and stick to it everywhere... If that
>> is not possible, I would like to understand why
>>
>
>Could you please elaborate what do you mean by " common + protocol or
>protocol + common, not both please!"?
>The order is same everywhere which is common + lane configuration for
>protocol 1 and then for protocol 2. For multiprotocol case, PHY configuration is
>based on which protocols are operating simultaneously. So e.g.
>[TYPE_QSGMII][TYPE_PCIE] -> QSGMII configuration when other protocol is
>PCIe Which might be different than [TYPE_QSGMII][TYPE_*] -> QSGMII
>configuration with other protocol.
>
>Thanks & regards,
>Swapnil
>
>> --
>> ~Vinod

2021-12-09 07:55:56

by Kishon Vijay Abraham I

[permalink] [raw]
Subject: Re: [PATCH v3 00/15] PHY: Add support for multilink configurations in Cadence Sierra PHY driver



On 22/10/21 10:32 pm, Swapnil Jakhade wrote:
> Cadence Sierra PHY is a multiprotocol PHY supporting different multilink
> PHY configurations. This patch series extends functionality of Sierra PHY
> driver by adding features like support for multilink multiprotocol
> configurations, derived reference clock etc.
>
> The changes have been validated on TI J721E platform.
>
> Version History:
>
> v3:
> - Rebased on latest PHY next
> - Added Reviewed-by and Acked-by tags
>
> v2:
> - Added a new patch 3/15 to rename the SSC macros for dt-bindings
> to use generic names. These macros are not yet used in any DTS file.
>
> Swapnil Jakhade (15):
> phy: cadence: Sierra: Use of_device_get_match_data() to get driver
> data
> phy: cadence: Sierra: Prepare driver to add support for multilink
> configurations
> dt-bindings: phy: cadence-torrent: Rename SSC macros to use generic
> names
> dt-bindings: phy: cadence-sierra: Add binding to specify SSC mode
> phy: cadence: Sierra: Add support to get SSC type from device tree
> phy: cadence: Sierra: Rename some regmap variables to be in sync with
> Sierra documentation
> phy: cadence: Sierra: Add PHY PCS common register configurations
> phy: cadence: Sierra: Check cmn_ready assertion during PHY power on
> phy: cadence: Sierra: Check PIPE mode PHY status to be ready for
> operation
> phy: cadence: Sierra: Update single link PCIe register configuration
> phy: cadence: Sierra: Fix to get correct parent for mux clocks
> phy: cadence: Sierra: Add support for PHY multilink configurations
> phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration
> dt-bindings: phy: cadence-sierra: Add clock ID for derived reference
> clock
> phy: cadence: Sierra: Add support for derived reference clock output
>
> .../bindings/phy/phy-cadence-sierra.yaml | 9 +
> .../bindings/phy/phy-cadence-torrent.yaml | 4 +-
> drivers/phy/cadence/phy-cadence-sierra.c | 1299 +++++++++++++++--
> include/dt-bindings/phy/phy-cadence.h | 9 +-
> 4 files changed, 1226 insertions(+), 95 deletions(-)


Reviewed-by: Kishon Vijay Abraham I <[email protected]>
>

2021-12-09 11:50:12

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

On 09-12-21, 06:11, Milind Parab wrote:
> Hi Vinod,
>
> Do you have any further comments on this.
> The implementation follows the same approach as is done for Cadence Torrent multiprotocol Phy

Pls do *not* top post!

Sure i will look into it soon..

>
> Regards,
> Milind
>
> >-----Original Message-----
> >From: Swapnil Kashinath Jakhade <[email protected]>
> >Sent: Thursday, December 2, 2021 7:43 PM
> >To: Vinod Koul <[email protected]>
> >Cc: [email protected]; [email protected]; [email protected]; linux-
> >[email protected]; [email protected];
> >[email protected]; Milind Parab <[email protected]>; a-
> >[email protected]
> >Subject: RE: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY
> >multilink configuration
> >
> >Hi Vinod,
> >
> >> -----Original Message-----
> >> From: Vinod Koul <[email protected]>
> >> Sent: Thursday, November 25, 2021 10:41 AM
> >> To: Swapnil Kashinath Jakhade <[email protected]>
> >> Cc: [email protected]; [email protected]; [email protected]; linux-
> >> [email protected]; [email protected];
> >> [email protected]; Milind Parab <[email protected]>; a-
> >> [email protected]
> >> Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII
> >> PHY multilink configuration
> >>
> >> EXTERNAL MAIL
> >>
> >>
> >> On 24-11-21, 07:33, Swapnil Kashinath Jakhade wrote:
> >>
> >> > > so this is pcie->qsgmii ->ssc/external/internal ... ok
> >> > >
> >> > > > + [NO_SSC] =
> >> > > &pcie_100_no_ssc_plllc_cmn_vals,
> >> > > > + [EXTERNAL_SSC] =
> >> > > &pcie_100_ext_ssc_plllc_cmn_vals,
> >> > > > + [INTERNAL_SSC] =
> >> > > &pcie_100_int_ssc_plllc_cmn_vals,
> >> > > > + },
> >> > > > },
> >> > > > [TYPE_USB] = {
> >> > > > [TYPE_NONE] = {
> >> > > > [EXTERNAL_SSC] =
> >> > > &usb_100_ext_ssc_cmn_vals,
> >> > > > },
> >> > > > },
> >> > > > + [TYPE_QSGMII] = {
> >> > > > + [TYPE_PCIE] = {
> >> > >
> >> > > now it is reverse! qsgmii -> pcie -> ... why?
> >> > >
> >> > > what is meant by pcie->qsgmii and qsgmii-> pcie?
> >> > >
> >> >
> >> > Multi-protocol configuration is done in 2 phases, each for one protocol.
> >> > e.g. for PCIe + QSGMII case,
> >> > [TYPE_PCIE][TYPE_QSGMII] will configure common and lane registers
> >> > for PCIe and [TYPE_QSGMII][TYPE_PCIE] will configure common and lane
> >> registers for QSGMII.
> >>
> >> Then it should be always common + protocol or protocol + common, not
> >> both please! Pls make an order and stick to it everywhere... If that
> >> is not possible, I would like to understand why
> >>
> >
> >Could you please elaborate what do you mean by " common + protocol or
> >protocol + common, not both please!"?
> >The order is same everywhere which is common + lane configuration for
> >protocol 1 and then for protocol 2. For multiprotocol case, PHY configuration is
> >based on which protocols are operating simultaneously. So e.g.
> >[TYPE_QSGMII][TYPE_PCIE] -> QSGMII configuration when other protocol is
> >PCIe Which might be different than [TYPE_QSGMII][TYPE_*] -> QSGMII
> >configuration with other protocol.
> >
> >Thanks & regards,
> >Swapnil
> >
> >> --
> >> ~Vinod

--
~Vinod

2021-12-09 11:54:08

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

On 02-12-21, 14:12, Swapnil Kashinath Jakhade wrote:
> Hi Vinod,
>
> > -----Original Message-----
> > From: Vinod Koul <[email protected]>
> > Sent: Thursday, November 25, 2021 10:41 AM
> > To: Swapnil Kashinath Jakhade <[email protected]>
> > Cc: [email protected]; [email protected]; [email protected]; linux-
> > [email protected]; [email protected];
> > [email protected]; Milind Parab <[email protected]>; a-
> > [email protected]
> > Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY
> > multilink configuration
> >
> > EXTERNAL MAIL
> >
> >
> > On 24-11-21, 07:33, Swapnil Kashinath Jakhade wrote:
> >
> > > > so this is pcie->qsgmii ->ssc/external/internal ... ok
> > > >
> > > > > + [NO_SSC] =
> > > > &pcie_100_no_ssc_plllc_cmn_vals,
> > > > > + [EXTERNAL_SSC] =
> > > > &pcie_100_ext_ssc_plllc_cmn_vals,
> > > > > + [INTERNAL_SSC] =
> > > > &pcie_100_int_ssc_plllc_cmn_vals,
> > > > > + },
> > > > > },
> > > > > [TYPE_USB] = {
> > > > > [TYPE_NONE] = {
> > > > > [EXTERNAL_SSC] =
> > > > &usb_100_ext_ssc_cmn_vals,
> > > > > },
> > > > > },
> > > > > + [TYPE_QSGMII] = {
> > > > > + [TYPE_PCIE] = {
> > > >
> > > > now it is reverse! qsgmii -> pcie -> ... why?
> > > >
> > > > what is meant by pcie->qsgmii and qsgmii-> pcie?
> > > >
> > >
> > > Multi-protocol configuration is done in 2 phases, each for one protocol.
> > > e.g. for PCIe + QSGMII case,
> > > [TYPE_PCIE][TYPE_QSGMII] will configure common and lane registers for
> > > PCIe and [TYPE_QSGMII][TYPE_PCIE] will configure common and lane
> > registers for QSGMII.
> >
> > Then it should be always common + protocol or protocol + common, not
> > both please! Pls make an order and stick to it everywhere... If that is not
> > possible, I would like to understand why
>
> Could you please elaborate what do you mean by
> " common + protocol or protocol + common, not both please!"?
> The order is same everywhere which is common + lane configuration for protocol 1
> and then for protocol 2. For multiprotocol case, PHY configuration is based on which
> protocols are operating simultaneously. So e.g.
> [TYPE_QSGMII][TYPE_PCIE] -> QSGMII configuration when other protocol is PCIe
> Which might be different than
> [TYPE_QSGMII][TYPE_*] -> QSGMII configuration with other protocol.

As I said I would like to understand what is the difference b/w
[TYPE_QSGMII][TYPE_PCIE] & [TYPE_PCIE][TYPE_QSGMII] and why?

--
~Vinod

Subject: RE: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

Hi Vinod,

> -----Original Message-----
> From: Vinod Koul <[email protected]>
> Sent: Thursday, December 9, 2021 5:24 PM
> To: Swapnil Kashinath Jakhade <[email protected]>
> Cc: [email protected]; [email protected]; [email protected]; linux-
> [email protected]; [email protected];
> [email protected]; Milind Parab <[email protected]>; a-
> [email protected]
> Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY
> multilink configuration
>
> EXTERNAL MAIL
>
>
> On 02-12-21, 14:12, Swapnil Kashinath Jakhade wrote:
> > Hi Vinod,
> >
> > > -----Original Message-----
> > > From: Vinod Koul <[email protected]>
> > > Sent: Thursday, November 25, 2021 10:41 AM
> > > To: Swapnil Kashinath Jakhade <[email protected]>
> > > Cc: [email protected]; [email protected]; [email protected];
> > > linux- [email protected]; [email protected];
> > > [email protected]; Milind Parab <[email protected]>; a-
> > > [email protected]
> > > Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe +
> > > QSGMII PHY multilink configuration
> > >
> > > EXTERNAL MAIL
> > >
> > >
> > > On 24-11-21, 07:33, Swapnil Kashinath Jakhade wrote:
> > >
> > > > > so this is pcie->qsgmii ->ssc/external/internal ... ok
> > > > >
> > > > > > + [NO_SSC] =
> > > > > &pcie_100_no_ssc_plllc_cmn_vals,
> > > > > > + [EXTERNAL_SSC] =
> > > > > &pcie_100_ext_ssc_plllc_cmn_vals,
> > > > > > + [INTERNAL_SSC] =
> > > > > &pcie_100_int_ssc_plllc_cmn_vals,
> > > > > > + },
> > > > > > },
> > > > > > [TYPE_USB] = {
> > > > > > [TYPE_NONE] = {
> > > > > > [EXTERNAL_SSC] =
> > > > > &usb_100_ext_ssc_cmn_vals,
> > > > > > },
> > > > > > },
> > > > > > + [TYPE_QSGMII] = {
> > > > > > + [TYPE_PCIE] = {
> > > > >
> > > > > now it is reverse! qsgmii -> pcie -> ... why?
> > > > >
> > > > > what is meant by pcie->qsgmii and qsgmii-> pcie?
> > > > >
> > > >
> > > > Multi-protocol configuration is done in 2 phases, each for one protocol.
> > > > e.g. for PCIe + QSGMII case,
> > > > [TYPE_PCIE][TYPE_QSGMII] will configure common and lane registers
> > > > for PCIe and [TYPE_QSGMII][TYPE_PCIE] will configure common and
> > > > lane
> > > registers for QSGMII.
> > >
> > > Then it should be always common + protocol or protocol + common, not
> > > both please! Pls make an order and stick to it everywhere... If that
> > > is not possible, I would like to understand why
> >
> > Could you please elaborate what do you mean by " common + protocol or
> > protocol + common, not both please!"?
> > The order is same everywhere which is common + lane configuration for
> > protocol 1 and then for protocol 2. For multiprotocol case, PHY
> > configuration is based on which protocols are operating simultaneously. So
> e.g.
> > [TYPE_QSGMII][TYPE_PCIE] -> QSGMII configuration when other protocol
> > is PCIe Which might be different than [TYPE_QSGMII][TYPE_*] -> QSGMII
> > configuration with other protocol.
>
> As I said I would like to understand what is the difference b/w
> [TYPE_QSGMII][TYPE_PCIE] & [TYPE_PCIE][TYPE_QSGMII] and why?
>

This logic is for implementing multi-link PHY configuration.
Consider a case for a 4 lane PHY with PCIe using 2 lanes and QSGMII other 2 lanes.
Sierra PHY has 2 PLLs, viz. PLLLC and PLLLC1.
So in this case, PLLLC is used for PCIe and PLLLC1 is used for QSGMII and
PHY will be configured in two steps as described below.
1. For first step, phy_t1 = TYPE_PCIE and phy_t2 = TYPE_QSGMII
So we select registers as
[TYPE_PCIE][TYPE_QSGMII][ssc]:
This will configure PHY registers associated for *PCIe* (i.e. first protocol)
involving PLLLC registers and registers for first 2 lanes of PHY.
2. In second step, the variables phy_t1 and phy_t2 are swapped. So now,
phy_t1 = TYPE_QSGMII and phy_t2 = TYPE_PCIE. And we select registers as:
[TYPE_QSGMII][TYPE_PCIE][ssc]:
This will configure PHY registers associated for *QSGMII* (i.e. second protocol)
involving PLLLC1 registers and registers for other 2 lanes of PHY.

This completes the PHY configuration for multilink operation.
Above approach enables dividing the large number of PHY register configurations
into protocol specific smaller groups.

Please let me know if it answers your question.

Thanks & regards,
Swapnil

> --
> ~Vinod

2021-12-14 09:22:33

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY multilink configuration

On 10-12-21, 09:46, Swapnil Kashinath Jakhade wrote:
> Hi Vinod,
>
> > -----Original Message-----
> > From: Vinod Koul <[email protected]>
> > Sent: Thursday, December 9, 2021 5:24 PM
> > To: Swapnil Kashinath Jakhade <[email protected]>
> > Cc: [email protected]; [email protected]; [email protected]; linux-
> > [email protected]; [email protected];
> > [email protected]; Milind Parab <[email protected]>; a-
> > [email protected]
> > Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe + QSGMII PHY
> > multilink configuration
> >
> > EXTERNAL MAIL
> >
> >
> > On 02-12-21, 14:12, Swapnil Kashinath Jakhade wrote:
> > > Hi Vinod,
> > >
> > > > -----Original Message-----
> > > > From: Vinod Koul <[email protected]>
> > > > Sent: Thursday, November 25, 2021 10:41 AM
> > > > To: Swapnil Kashinath Jakhade <[email protected]>
> > > > Cc: [email protected]; [email protected]; [email protected];
> > > > linux- [email protected]; [email protected];
> > > > [email protected]; Milind Parab <[email protected]>; a-
> > > > [email protected]
> > > > Subject: Re: [PATCH v3 13/15] phy: cadence: Sierra: Add PCIe +
> > > > QSGMII PHY multilink configuration
> > > >
> > > > EXTERNAL MAIL
> > > >
> > > >
> > > > On 24-11-21, 07:33, Swapnil Kashinath Jakhade wrote:
> > > >
> > > > > > so this is pcie->qsgmii ->ssc/external/internal ... ok
> > > > > >
> > > > > > > + [NO_SSC] =
> > > > > > &pcie_100_no_ssc_plllc_cmn_vals,
> > > > > > > + [EXTERNAL_SSC] =
> > > > > > &pcie_100_ext_ssc_plllc_cmn_vals,
> > > > > > > + [INTERNAL_SSC] =
> > > > > > &pcie_100_int_ssc_plllc_cmn_vals,
> > > > > > > + },
> > > > > > > },
> > > > > > > [TYPE_USB] = {
> > > > > > > [TYPE_NONE] = {
> > > > > > > [EXTERNAL_SSC] =
> > > > > > &usb_100_ext_ssc_cmn_vals,
> > > > > > > },
> > > > > > > },
> > > > > > > + [TYPE_QSGMII] = {
> > > > > > > + [TYPE_PCIE] = {
> > > > > >
> > > > > > now it is reverse! qsgmii -> pcie -> ... why?
> > > > > >
> > > > > > what is meant by pcie->qsgmii and qsgmii-> pcie?
> > > > > >
> > > > >
> > > > > Multi-protocol configuration is done in 2 phases, each for one protocol.
> > > > > e.g. for PCIe + QSGMII case,
> > > > > [TYPE_PCIE][TYPE_QSGMII] will configure common and lane registers
> > > > > for PCIe and [TYPE_QSGMII][TYPE_PCIE] will configure common and
> > > > > lane
> > > > registers for QSGMII.
> > > >
> > > > Then it should be always common + protocol or protocol + common, not
> > > > both please! Pls make an order and stick to it everywhere... If that
> > > > is not possible, I would like to understand why
> > >
> > > Could you please elaborate what do you mean by " common + protocol or
> > > protocol + common, not both please!"?
> > > The order is same everywhere which is common + lane configuration for
> > > protocol 1 and then for protocol 2. For multiprotocol case, PHY
> > > configuration is based on which protocols are operating simultaneously. So
> > e.g.
> > > [TYPE_QSGMII][TYPE_PCIE] -> QSGMII configuration when other protocol
> > > is PCIe Which might be different than [TYPE_QSGMII][TYPE_*] -> QSGMII
> > > configuration with other protocol.
> >
> > As I said I would like to understand what is the difference b/w
> > [TYPE_QSGMII][TYPE_PCIE] & [TYPE_PCIE][TYPE_QSGMII] and why?
> >
>
> This logic is for implementing multi-link PHY configuration.
> Consider a case for a 4 lane PHY with PCIe using 2 lanes and QSGMII other 2 lanes.
> Sierra PHY has 2 PLLs, viz. PLLLC and PLLLC1.
> So in this case, PLLLC is used for PCIe and PLLLC1 is used for QSGMII and
> PHY will be configured in two steps as described below.
> 1. For first step, phy_t1 = TYPE_PCIE and phy_t2 = TYPE_QSGMII
> So we select registers as
> [TYPE_PCIE][TYPE_QSGMII][ssc]:
> This will configure PHY registers associated for *PCIe* (i.e. first protocol)
> involving PLLLC registers and registers for first 2 lanes of PHY.
> 2. In second step, the variables phy_t1 and phy_t2 are swapped. So now,
> phy_t1 = TYPE_QSGMII and phy_t2 = TYPE_PCIE. And we select registers as:
> [TYPE_QSGMII][TYPE_PCIE][ssc]:
> This will configure PHY registers associated for *QSGMII* (i.e. second protocol)
> involving PLLLC1 registers and registers for other 2 lanes of PHY.
>
> This completes the PHY configuration for multilink operation.
> Above approach enables dividing the large number of PHY register configurations
> into protocol specific smaller groups.
>
> Please let me know if it answers your question.

Thanks this helps. Can you please add this useful info in the comments
for this, that will help folks understanding why it was done like this

--
~Vinod