[PATCH 13/14] phy: cadence-torrent: Add debug information for PHY configuration

2021-04-08 Thread Swapnil Jakhade
Display information in probe regarding PHY configuration parameters like
single link or multilink protocol information along with number of lanes
used for each protocol link.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 32 +--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index bf37569c6c51..39145e56e061 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -574,6 +574,24 @@ static const struct coefficients vltg_coeff[4][4] = {
}
 };
 
+static const char *cdns_torrent_get_phy_type(enum cdns_torrent_phy_type 
phy_type)
+{
+   switch (phy_type) {
+   case TYPE_DP:
+   return "DisplayPort";
+   case TYPE_PCIE:
+   return "PCIe";
+   case TYPE_SGMII:
+   return "SGMII";
+   case TYPE_QSGMII:
+   return "QSGMII";
+   case TYPE_USB:
+   return "USB";
+   default:
+   return "None";
+   }
+}
+
 /*
  * Set registers responsible for enabling and configuring SSC, with second and
  * third register values provided by parameters.
@@ -2504,8 +2522,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
init_dp_regmap++;
}
 
-   dev_info(dev, "%d lanes, max bit rate %d.%03d Gbps\n",
-cdns_phy->phys[node].num_lanes,
+   dev_info(dev, "DP max bit rate %d.%03d Gbps\n",
 cdns_phy->max_bit_rate / 1000,
 cdns_phy->max_bit_rate % 1000);
 
@@ -2539,6 +2556,17 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
goto put_lnk_rst;
}
 
+   if (cdns_phy->nsubnodes > 1)
+   dev_info(dev, "%s (%d lanes) & %s (%d lanes)",
+cdns_torrent_get_phy_type(cdns_phy->phys[0].phy_type),
+cdns_phy->phys[0].num_lanes,
+cdns_torrent_get_phy_type(cdns_phy->phys[1].phy_type),
+cdns_phy->phys[1].num_lanes);
+   else
+   dev_info(dev, "%s (%d lanes)",
+cdns_torrent_get_phy_type(cdns_phy->phys[0].phy_type),
+cdns_phy->phys[0].num_lanes);
+
return 0;
 
 put_child:
-- 
2.26.1



[PATCH 11/14] phy: cadence-torrent: Add multilink DP support

2021-04-08 Thread Swapnil Jakhade
Add multilink support for DP. This needs changes in functions
configuring default single link DP with master lane 0 to support
non-zero master lane values and associated PLL configurations.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 498 +-
 1 file changed, 289 insertions(+), 209 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 44e28ea8ffa7..becbf8456b2d 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -62,16 +62,11 @@
  */
 #define PHY_AUX_CTRL   0x04
 #define PHY_RESET  0x20
-#define PMA_TX_ELEC_IDLE_MASK  0xF0U
 #define PMA_TX_ELEC_IDLE_SHIFT 4
-#define PHY_L00_RESET_N_MASK   0x01U
 #define PHY_PMA_XCVR_PLLCLK_EN 0x24
 #define PHY_PMA_XCVR_PLLCLK_EN_ACK 0x28
 #define PHY_PMA_XCVR_POWER_STATE_REQ   0x2c
-#define PHY_POWER_STATE_LN_0   0x
-#define PHY_POWER_STATE_LN_1   0x0008
-#define PHY_POWER_STATE_LN_2   0x0010
-#define PHY_POWER_STATE_LN_3   0x0018
+#define PHY_POWER_STATE_LN(ln) ((ln) * 8)
 #define PMA_XCVR_POWER_STATE_REQ_LN_MASK   0x3FU
 #define PHY_PMA_XCVR_POWER_STATE_ACK   0x30
 #define PHY_PMA_CMN_READY  0x34
@@ -834,74 +829,90 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(struct 
cdns_torrent_phy *cdns_phy,
/* Setting VCO for 10.8GHz */
case 2700:
case 5400:
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 
0x0028);
-   cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_FBH_OVRD_M0, 
0x0022);
-   cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBH_OVRD_M0, 
0x0022);
-   cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBL_OVRD_M0, 
0x000C);
+   if (cdns_phy->dp_pll & DP_PLL0)
+   cdns_torrent_phy_write(regmap, 
CMN_PLL0_DSM_FBH_OVRD_M0, 0x0022);
+
+   if (cdns_phy->dp_pll & DP_PLL1) {
+   cdns_torrent_phy_write(regmap, 
CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0028);
+   cdns_torrent_phy_write(regmap, 
CMN_PLL1_DSM_FBH_OVRD_M0, 0x0022);
+   cdns_torrent_phy_write(regmap, 
CMN_PLL1_DSM_FBL_OVRD_M0, 0x000C);
+   }
break;
/* Setting VCO for 9.72GHz */
case 1620:
case 2430:
case 3240:
-   cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
-   cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 
0x0509);
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 
0x0509);
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 
0x0F00);
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 
0x0F00);
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 
0x0F08);
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 
0x0F08);
-   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0061);
-   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0061);
-   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x);
-   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x);
-   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
-   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
-   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0042);
-   cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0042);
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
-   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+   if (cdns_phy->dp_pll & DP_PLL0) {
+   cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 
0x0004);
+   cdns_torrent_phy_write(regmap, 
CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
+   cdns_torrent_phy_write(regmap, 
CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
+   cdns_torrent_phy_write(regmap, 
CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 
0x0061);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 
0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 
0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 
0x0042);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 
0x0002);
+   }
+   if (cdns_phy->dp_pll & DP_PLL1) {
+   cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 
0x0004);
+   cdns_torrent_phy_write(regmap, 
CMN_P

[PATCH 04/14] phy: cadence-torrent: Select register configuration based on PHY reference clock

2021-04-08 Thread Swapnil Jakhade
Add PHY input reference clock frequency as a new dimension to select proper
register configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 830 +++---
 1 file changed, 422 insertions(+), 408 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 252920ea7fdf..39a26a1a4c51 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -375,12 +375,12 @@ struct cdns_torrent_data {
[NUM_SSC_MODE];
struct cdns_torrent_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
  [NUM_SSC_MODE];
-   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
- [NUM_SSC_MODE];
-   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
-   [NUM_SSC_MODE];
-   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
-   [NUM_SSC_MODE];
+   struct cdns_torrent_vals *cmn_vals[NUM_REF_CLK][NUM_PHY_TYPE]
+ [NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *tx_ln_vals[NUM_REF_CLK][NUM_PHY_TYPE]
+   [NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *rx_ln_vals[NUM_REF_CLK][NUM_PHY_TYPE]
+   [NUM_PHY_TYPE][NUM_SSC_MODE];
 };
 
 struct cdns_regmap_cdb_context {
@@ -1958,6 +1958,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
const struct cdns_torrent_data *init_data = cdns_phy->init_data;
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
+   enum cdns_torrent_ref_clk ref_clk = cdns_phy->ref_clk_rate;
struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
@@ -2023,7 +2024,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
}
 
/* PMA common registers configurations */
-   cmn_vals = init_data->cmn_vals[phy_type][TYPE_NONE][ssc];
+   cmn_vals = init_data->cmn_vals[ref_clk][phy_type][TYPE_NONE][ssc];
if (cmn_vals) {
reg_pairs = cmn_vals->reg_pairs;
num_regs = cmn_vals->num_regs;
@@ -2034,7 +2035,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
}
 
/* PMA TX lane registers configurations */
-   tx_ln_vals = init_data->tx_ln_vals[phy_type][TYPE_NONE][ssc];
+   tx_ln_vals = init_data->tx_ln_vals[ref_clk][phy_type][TYPE_NONE][ssc];
if (tx_ln_vals) {
reg_pairs = tx_ln_vals->reg_pairs;
num_regs = tx_ln_vals->num_regs;
@@ -2047,7 +2048,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
}
 
/* PMA RX lane registers configurations */
-   rx_ln_vals = init_data->rx_ln_vals[phy_type][TYPE_NONE][ssc];
+   rx_ln_vals = init_data->rx_ln_vals[ref_clk][phy_type][TYPE_NONE][ssc];
if (rx_ln_vals) {
reg_pairs = rx_ln_vals->reg_pairs;
num_regs = rx_ln_vals->num_regs;
@@ -2088,6 +2089,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
 {
const struct cdns_torrent_data *init_data = cdns_phy->init_data;
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
+   enum cdns_torrent_ref_clk ref_clk = cdns_phy->ref_clk_rate;
struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type;
struct cdns_torrent_vals *pcs_cmn_vals;
@@ -2176,7 +2178,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
}
 
/* PMA common registers configurations */
-   cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc];
+   cmn_vals = init_data->cmn_vals[ref_clk][phy_t1][phy_t2][ssc];
if (cmn_vals) {
reg_pairs = cmn_vals->reg_pairs;
num_regs = cmn_vals->num_regs;
@@ -2187,7 +2189,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
}
 
/* PMA TX lane registers configurations */
-   tx_ln_vals = init_data->tx_ln_vals[phy_t1][phy_t2][ssc];
+   tx_ln_vals = 
init_data->tx_ln_vals[ref_clk][phy_t1][phy_t2][ssc];
if (tx_ln_vals) {
reg_pairs = tx_ln_vals->reg_pairs;
num_regs = tx_ln_vals->num_regs;
@@ -2200,7 +2202,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torre

[PATCH 05/14] phy: cadence-torrent: Add PHY registers for DP in array format

2021-04-08 Thread Swapnil Jakhade
Add PHY registers for single link DP in array format to simplify
code and to improve readability.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 450 +-
 1 file changed, 274 insertions(+), 176 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 39a26a1a4c51..4ec5909f192c 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -341,20 +341,12 @@ struct cdns_torrent_derived_refclk {
 #define to_cdns_torrent_derived_refclk(_hw)\
container_of(_hw, struct cdns_torrent_derived_refclk, 
hw)
 
-static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy,
-   struct cdns_torrent_inst *inst);
-static
-void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy);
 static
 void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
 u32 rate, bool ssc);
 static
-void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy);
-static
 void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
   u32 rate, bool ssc);
-static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
-unsigned int lane);
 
 struct cdns_reg_pairs {
u32 val;
@@ -759,9 +751,6 @@ static void cdns_torrent_dp_pma_cmn_rate(struct 
cdns_torrent_phy *cdns_phy,
unsigned int hsclk_div_val = 0;
unsigned int i;
 
-   /* 16'h for single DP link configuration */
-   regmap_field_write(cdns_phy->phy_pll_cfg, 0x0);
-
switch (rate) {
case 1620:
clk_sel_val = 0x0f01;
@@ -806,8 +795,7 @@ static void cdns_torrent_dp_pma_cmn_rate(struct 
cdns_torrent_phy *cdns_phy,
 static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy,
  struct phy_configure_opts_dp *dp)
 {
-   u32 ret;
-   u32 read_val;
+   u32 read_val, ret;
 
/* Disable the cmn_pll0_en before re-programming the new data rate. */
regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x0);
@@ -825,17 +813,12 @@ static int cdns_torrent_dp_configure_rate(struct 
cdns_torrent_phy *cdns_phy,
ndelay(200);
 
/* DP Rate Change - VCO Output settings. */
-   if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) {
+   if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ)
/* PMA common configuration 19.2MHz */
-   cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate,
-   dp->ssc);
-   cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
-   } else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) {
+   cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, 
dp->link_rate, dp->ssc);
+   else if (cdns_phy->ref_clk_rate == CLK_25_MHZ)
/* PMA common configuration 25MHz */
-   cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate,
- dp->ssc);
-   cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
-   }
+   cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, 
dp->ssc);
cdns_torrent_dp_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes);
 
/* Enable the cmn_pll0_en. */
@@ -1184,9 +1167,6 @@ static int cdns_torrent_dp_init(struct phy *phy)
 
cdns_torrent_dp_write(regmap, PHY_AUX_CTRL, 0x0003); /* enable AUX */
 
-   /* PHY PMA registers configuration function */
-   cdns_torrent_dp_pma_cfg(cdns_phy, inst);
-
/*
 * Set lines power state to A0
 * Set lines pll clk enable to 0
@@ -1231,67 +1211,6 @@ static int cdns_torrent_dp_init(struct phy *phy)
return ret;
 }
 
-static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy,
-   struct cdns_torrent_inst *inst)
-{
-   unsigned int i;
-
-   if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ)
-   /* PMA common configuration 19.2MHz */
-   cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
-   else if (cdns_phy->ref_clk_rate == CLK_25_MHZ)
-   /* PMA common configuration 25MHz */
-   cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
-
-   /* PMA lane configuration to deal with multi-link operation */
-   for (i = 0; i < inst->num_lanes; i++)
-   cdns_torrent_dp_pma_lane_cfg(cdns_phy, i);
-}
-
-static
-void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy)
-{
-   struct regmap *regmap = cdns_phy->regmap_common_cdb;
-
-   /* refclock registers - assumes 19.2 MHz refclock */
-   cdns_torrent_phy_write(regmap, C

[PATCH 14/14] phy: cadence-torrent: Check PIPE mode PHY status to be ready for operation

2021-04-08 Thread Swapnil Jakhade
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 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 60 +++
 1 file changed, 60 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 39145e56e061..42a1bdfd18d5 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -51,6 +51,10 @@
 #define TORRENT_PHY_PCS_COMMON_OFFSET(block_offset)\
(0xC000 << (block_offset))
 
+#define TORRENT_PHY_PCS_LANE_CDB_OFFSET(ln, block_offset, reg_offset)  \
+   ((0xD000 << (block_offset)) +   \
+   (((ln) << 9) << (reg_offset)))
+
 #define TORRENT_PHY_PMA_COMMON_OFFSET(block_offset)\
(0xE000 << (block_offset))
 
@@ -218,6 +222,9 @@
 #define PHY_PIPE_USB3_GEN2_POST_CFG0   0x0022U
 #define PHY_PIPE_USB3_GEN2_POST_CFG1   0x0023U
 
+/* PHY PCS lane registers */
+#define PHY_PCS_ISO_LINK_CTRL  0x000BU
+
 /* PHY PMA common registers */
 #define PHY_PMA_CMN_CTRL1  0xU
 #define PHY_PMA_CMN_CTRL2  0x0001U
@@ -242,6 +249,9 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
 static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
+static const struct reg_field phy_pcs_iso_link_ctrl_1 =
+   REG_FIELD(PHY_PCS_ISO_LINK_CTRL, 1, 1);
+
 static const struct reg_field phy_pipe_cmn_ctrl1_0 = 
REG_FIELD(PHY_PIPE_CMN_CTRL1, 0, 0);
 
 #define REFCLK_OUT_NUM_CMN_CONFIG  5
@@ -316,12 +326,14 @@ struct cdns_torrent_phy {
struct regmap *regmap_phy_pma_common_cdb;
struct regmap *regmap_tx_lane_cdb[MAX_NUM_LANES];
struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES];
+   struct regmap *regmap_phy_pcs_lane_cdb[MAX_NUM_LANES];
struct regmap *regmap_dptx_phy_reg;
struct regmap_field *phy_pll_cfg;
struct regmap_field *phy_pma_cmn_ctrl_1;
struct regmap_field *phy_pma_cmn_ctrl_2;
struct regmap_field *phy_pma_pll_raw_ctrl;
struct regmap_field *phy_reset_ctrl;
+   struct regmap_field *phy_pcs_iso_link_ctrl_1[MAX_NUM_LANES];
struct clk *clks[CDNS_TORRENT_REFCLK_DRIVER + 1];
struct clk_onecell_data clk_data;
 };
@@ -456,6 +468,22 @@ static const struct regmap_config 
cdns_torrent_common_cdb_config = {
.reg_read = cdns_regmap_read,
 };
 
+#define TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF(n) \
+{ \
+   .name = "torrent_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_torrent_phy_pcs_lane_cdb_config[] = {
+   TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("0"),
+   TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("1"),
+   TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("2"),
+   TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("3"),
+};
+
 static const struct regmap_config cdns_torrent_phy_pcs_cmn_cdb_config = {
.name = "torrent_phy_pcs_cmn_cdb",
.reg_stride = 1,
@@ -1546,6 +1574,16 @@ static int cdns_torrent_phy_on(struct phy *phy)
return ret;
}
 
+   if (inst->phy_type == TYPE_PCIE || inst->phy_type == TYPE_USB) {
+   ret = 
regmap_field_read_poll_timeout(cdns_phy->phy_pcs_iso_link_ctrl_1[inst->mlane],
+read_val, !read_val, 1000,
+PLL_LOCK_TIMEOUT);
+   if (ret == -ETIMEDOUT) {
+   dev_err(cdns_phy->dev, "Timeout waiting for PHY status 
ready\n");
+   return ret;
+   }
+   }
+
mdelay(10);
 
return 0;
@@ -1822,6 +1860,7 @@ static int cdns_torrent_regfield_init(struct 
cdns_torrent_phy *cdns_phy)
struct device *dev = cdns_phy->dev;
struct regmap_field *field;
struct regmap *regmap;
+   int i;
 
regmap = cdns_phy->regmap_phy_pcs_common_cdb;
field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg);
@@ -1855,6 +1894,16 @@ static int cdns_torrent_regfield_init(struct 
cdns_torrent_phy *cdns_phy)
}
cdns_phy->phy_pma_pll_raw_ctrl = field;
 
+   for (i = 0; i < MAX_NUM_LANES; i++) {
+   regmap = cdns_phy->regmap_phy_pcs_lane_cdb[i];
+   field = devm_regmap_field_alloc(dev, regmap, 
phy_pcs_iso_link_ctrl_1);
+   if (IS_ERR(field)) {
+   dev_err(dev, "PHY_PCS_ISO_LINK_CTRL reg field init for 
l

[PATCH 03/14] phy: cadence-torrent: Add enum to support different input reference clocks

2021-04-08 Thread Swapnil Jakhade
Torrent PHY supports different input reference clock frequencies.
Register configurations will be different based on reference clock value.
Prepare driver to support register configs for multiple reference clocks.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 51 +--
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 6eeb753fbb78..252920ea7fdf 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -26,11 +26,13 @@
 
 #define REF_CLK_19_2MHZ1920
 #define REF_CLK_25MHZ  2500
+#define REF_CLK_100MHZ 1
 
 #define MAX_NUM_LANES  4
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
 #define NUM_SSC_MODE   3
+#define NUM_REF_CLK3
 #define NUM_PHY_TYPE   6
 
 #define POLL_TIMEOUT_US5000
@@ -273,6 +275,12 @@ enum cdns_torrent_phy_type {
TYPE_USB,
 };
 
+enum cdns_torrent_ref_clk {
+   CLK_19_2_MHZ,
+   CLK_25_MHZ,
+   CLK_100_MHZ
+};
+
 enum cdns_torrent_ssc_mode {
NO_SSC,
EXTERNAL_SSC,
@@ -296,7 +304,7 @@ struct cdns_torrent_phy {
struct reset_control *apb_rst;
struct device *dev;
struct clk *clk;
-   unsigned long ref_clk_rate;
+   enum cdns_torrent_ref_clk ref_clk_rate;
struct cdns_torrent_inst phys[MAX_NUM_LANES];
int nsubnodes;
const struct cdns_torrent_data *init_data;
@@ -817,12 +825,12 @@ static int cdns_torrent_dp_configure_rate(struct 
cdns_torrent_phy *cdns_phy,
ndelay(200);
 
/* DP Rate Change - VCO Output settings. */
-   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) {
+   if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) {
/* PMA common configuration 19.2MHz */
cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate,
dp->ssc);
cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
-   } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) {
+   } else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) {
/* PMA common configuration 25MHz */
cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate,
  dp->ssc);
@@ -1165,8 +1173,8 @@ static int cdns_torrent_dp_init(struct phy *phy)
struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
 
switch (cdns_phy->ref_clk_rate) {
-   case REF_CLK_19_2MHZ:
-   case REF_CLK_25MHZ:
+   case CLK_19_2_MHZ:
+   case CLK_25_MHZ:
/* Valid Ref Clock Rate */
break;
default:
@@ -1198,11 +1206,11 @@ static int cdns_torrent_dp_init(struct phy *phy)
 
/* PHY PMA registers configuration functions */
/* Initialize PHY with max supported link rate, without SSC. */
-   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ)
+   if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ)
cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy,
cdns_phy->max_bit_rate,
false);
-   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ)
+   else if (cdns_phy->ref_clk_rate == CLK_25_MHZ)
cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy,
  cdns_phy->max_bit_rate,
  false);
@@ -1228,10 +1236,10 @@ static void cdns_torrent_dp_pma_cfg(struct 
cdns_torrent_phy *cdns_phy,
 {
unsigned int i;
 
-   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ)
+   if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ)
/* PMA common configuration 19.2MHz */
cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
-   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ)
+   else if (cdns_phy->ref_clk_rate == CLK_25_MHZ)
/* PMA common configuration 25MHz */
cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
 
@@ -1636,10 +1644,10 @@ static void cdns_torrent_dp_pma_lane_cfg(struct 
cdns_torrent_phy *cdns_phy,
 unsigned int lane)
 {
/* Per lane, refclock-dependent receiver detection setting */
-   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ)
+   if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ)
cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
   TX_RCVDET_ST_TMR, 0x0780);
-   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ)
+   else if (cdns_phy->ref_clk_rate == CLK_25_MHZ)
cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],

[PATCH 06/14] phy: cadence-torrent: Reorder functions to avoid function declarations

2021-04-08 Thread Swapnil Jakhade
Reorder some functions to avoid function declarations. Also, remove
unnecessary line breaks while moving. No functional change.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 305 +-
 1 file changed, 121 insertions(+), 184 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 4ec5909f192c..396c3810a69d 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -342,9 +342,6 @@ struct cdns_torrent_derived_refclk {
container_of(_hw, struct cdns_torrent_derived_refclk, 
hw)
 
 static
-void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
-u32 rate, bool ssc);
-static
 void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
   u32 rate, bool ssc);
 
@@ -579,6 +576,127 @@ static const struct coefficients vltg_coeff[4][4] = {
}
 };
 
+/*
+ * Set registers responsible for enabling and configuring SSC, with second and
+ * third register values provided by parameters.
+ */
+static
+void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy,
+   u32 ctrl2_val, u32 ctrl3_val)
+{
+   struct regmap *regmap = cdns_phy->regmap_common_cdb;
+
+   cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl3_val);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl3_val);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
+}
+
+static
+void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
+u32 rate, bool ssc)
+{
+   struct regmap *regmap = cdns_phy->regmap_common_cdb;
+
+   /* Assumes 19.2 MHz refclock */
+   switch (rate) {
+   /* Setting VCO for 10.8GHz */
+   case 2700:
+   case 5400:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0119);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x4000);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00BC);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0012);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0119);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x4000);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00BC);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0012);
+   if (ssc)
+   cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A, 
0x006A);
+   break;
+   /* Setting VCO for 9.72GHz */
+   case 1620:
+   case 2430:
+   case 3240:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01FA);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x4000);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0152);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01FA);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x4000);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0152);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+   if (ssc)
+   cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD, 
0x0069);
+   break;
+   /* Setting VCO for 8.64GHz */
+   case 2160:
+   case 4320:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01C2);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x012C);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01C2);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 

[PATCH 07/14] phy: cadence-torrent: Reorder functions to avoid function declarations

2021-04-08 Thread Swapnil Jakhade
Reorder some functions to avoid function declarations.
No functional change.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 250 +++---
 1 file changed, 123 insertions(+), 127 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 396c3810a69d..a6331927d775 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -341,10 +341,6 @@ struct cdns_torrent_derived_refclk {
 #define to_cdns_torrent_derived_refclk(_hw)\
container_of(_hw, struct cdns_torrent_derived_refclk, 
hw)
 
-static
-void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
-  u32 rate, bool ssc);
-
 struct cdns_reg_pairs {
u32 val;
u32 off;
@@ -697,6 +693,129 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct 
cdns_torrent_phy *cdns_phy,
cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x0099);
 }
 
+/*
+ * Set registers responsible for enabling and configuring SSC, with second
+ * register value provided by a parameter.
+ */
+static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy,
+u32 ctrl2_val)
+{
+   struct regmap *regmap = cdns_phy->regmap_common_cdb;
+
+   cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x007F);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x007F);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
+}
+
+static
+void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
+  u32 rate, bool ssc)
+{
+   struct regmap *regmap = cdns_phy->regmap_common_cdb;
+
+   /* Assumes 25 MHz refclock */
+   switch (rate) {
+   /* Setting VCO for 10.8GHz */
+   case 2700:
+   case 5400:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01B0);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0120);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01B0);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0120);
+   if (ssc)
+   cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423);
+   break;
+   /* Setting VCO for 9.72GHz */
+   case 1620:
+   case 2430:
+   case 3240:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0184);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0xCCCD);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0104);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0184);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0xCCCD);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0104);
+   if (ssc)
+   cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9);
+   break;
+   /* Setting VCO for 8.64GHz */
+   case 2160:
+   case 4320:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0159);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x999A);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00E7);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0159);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x999A);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00E7);
+   if (ssc)
+   cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F);
+   break;
+   /* Setting VCO for 8.1GHz */
+   case 8100:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0144);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(

[PATCH 02/14] phy: cadence-torrent: Reorder few functions to remove function declarations

2021-04-08 Thread Swapnil Jakhade
Reorder some functions to avoid function declarations.
No functional change.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 474 +++---
 1 file changed, 229 insertions(+), 245 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index ff647669f1a3..6eeb753fbb78 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -333,12 +333,6 @@ struct cdns_torrent_derived_refclk {
 #define to_cdns_torrent_derived_refclk(_hw)\
container_of(_hw, struct cdns_torrent_derived_refclk, 
hw)
 
-static int cdns_torrent_phy_init(struct phy *phy);
-static int cdns_torrent_dp_init(struct phy *phy);
-static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
-  u32 num_lanes);
-static
-int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy);
 static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy,
struct cdns_torrent_inst *inst);
 static
@@ -353,36 +347,6 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct 
cdns_torrent_phy *cdns_phy,
   u32 rate, bool ssc);
 static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
 unsigned int lane);
-static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
-u32 rate, u32 num_lanes);
-static int cdns_torrent_dp_configure(struct phy *phy,
-union phy_configure_opts *opts);
-static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
-  u32 num_lanes,
-  enum phy_powerstate powerstate);
-static int cdns_torrent_phy_on(struct phy *phy);
-static int cdns_torrent_phy_off(struct phy *phy);
-
-static const struct phy_ops cdns_torrent_phy_ops = {
-   .init   = cdns_torrent_phy_init,
-   .configure  = cdns_torrent_dp_configure,
-   .power_on   = cdns_torrent_phy_on,
-   .power_off  = cdns_torrent_phy_off,
-   .owner  = THIS_MODULE,
-};
-
-static int cdns_torrent_noop_phy_on(struct phy *phy)
-{
-   /* Give 5ms to 10ms delay for the PIPE clock to be stable */
-   usleep_range(5000, 1);
-
-   return 0;
-}
-
-static const struct phy_ops noop_ops = {
-   .power_on   = cdns_torrent_noop_phy_on,
-   .owner  = THIS_MODULE,
-};
 
 struct cdns_reg_pairs {
u32 val;
@@ -669,6 +633,164 @@ static int cdns_torrent_dp_set_pll_en(struct 
cdns_torrent_phy *cdns_phy,
return ret;
 }
 
+static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
+  u32 num_lanes,
+  enum phy_powerstate powerstate)
+{
+   /* Register value for power state for a single byte. */
+   u32 value_part;
+   u32 value;
+   u32 mask;
+   u32 read_val;
+   u32 ret;
+   struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
+
+   switch (powerstate) {
+   case (POWERSTATE_A0):
+   value_part = 0x01U;
+   break;
+   case (POWERSTATE_A2):
+   value_part = 0x04U;
+   break;
+   default:
+   /* Powerstate A3 */
+   value_part = 0x08U;
+   break;
+   }
+
+   /* Select values of registers and mask, depending on enabled
+* lane count.
+*/
+   switch (num_lanes) {
+   /* lane 0 */
+   case (1):
+   value = value_part;
+   mask = 0x003FU;
+   break;
+   /* lanes 0-1 */
+   case (2):
+   value = (value_part
+| (value_part << 8));
+   mask = 0x3F3FU;
+   break;
+   /* lanes 0-3, all */
+   default:
+   value = (value_part
+| (value_part << 8)
+| (value_part << 16)
+| (value_part << 24));
+   mask = 0x3F3F3F3FU;
+   break;
+   }
+
+   /* Set power state A. */
+   cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, value);
+   /* Wait, until PHY acknowledges power state completion. */
+   ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_POWER_STATE_ACK,
+  read_val, (read_val & mask) == value, 0,
+  POLL_TIMEOUT_US);
+   cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, 0x);
+   ndelay(100);
+
+   return ret;
+}
+
+static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, u32 
num_lanes)
+{
+   unsigned int read_val;
+   int ret

[PATCH 00/14] PHY: Add multilink DP support in Cadence Torrent PHY driver

2021-04-08 Thread Swapnil Jakhade
This patch series enables Torrent PHY driver to support different input
reference clock frequencies. It also adds support for multilink
multiprotocol DisplayPort configuration. Currently, PCIe + DP multilink
register sequences are added.

Swapnil Jakhade (14):
  phy: cadence-torrent: Remove use of CamelCase to fix checkpatch CHECK
message
  phy: cadence-torrent: Reorder few functions to remove function
declarations
  phy: cadence-torrent: Add enum to support different input reference
clocks
  phy: cadence-torrent: Select register configuration based on PHY
reference clock
  phy: cadence-torrent: Add PHY registers for DP in array format
  phy: cadence-torrent: Reorder functions to avoid function declarations
  phy: cadence-torrent: Reorder functions to avoid function declarations
  phy: cadence-torrent: Add PHY configuration for DP with 100MHz ref
clock
  phy: cadence-torrent: Add separate functions for reusable code
  phy: cadence-torrent: Add function to get PLL to be configured for DP
  phy: cadence-torrent: Add multilink DP support
  phy: cadence-torrent: Add PCIe + DP multilink configuration
  phy: cadence-torrent: Add debug information for PHY configuration
  phy: cadence-torrent: Check PIPE mode PHY status to be ready for
operation

 drivers/phy/cadence/phy-cadence-torrent.c | 3422 -
 1 file changed, 1993 insertions(+), 1429 deletions(-)

-- 
2.26.1



[PATCH 08/14] phy: cadence-torrent: Add PHY configuration for DP with 100MHz ref clock

2021-04-08 Thread Swapnil Jakhade
Add PHY configuration registers for DP with 100MHz ref clock and NO_SSC.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 162 ++
 1 file changed, 162 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index a6331927d775..69466481af26 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -103,6 +103,7 @@
 #define CMN_PLL0_FRACDIVH_M0   0x0092U
 #define CMN_PLL0_HIGH_THR_M0   0x0093U
 #define CMN_PLL0_DSM_DIAG_M0   0x0094U
+#define CMN_PLL0_DSM_FBH_OVRD_M0   0x0095U
 #define CMN_PLL0_SS_CTRL1_M0   0x0098U
 #define CMN_PLL0_SS_CTRL2_M00x0099U
 #define CMN_PLL0_SS_CTRL3_M00x009AU
@@ -816,6 +817,89 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct 
cdns_torrent_phy *cdns_phy,
cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x00C7);
 }
 
+static
+void cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(struct cdns_torrent_phy *cdns_phy,
+   u32 rate, bool ssc)
+{
+   struct regmap *regmap = cdns_phy->regmap_common_cdb;
+
+   /* Assumes 100 MHz refclock */
+   switch (rate) {
+   /* Setting VCO for 10.8GHz */
+   case 2700:
+   case 5400:
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 
0x0028);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_FBH_OVRD_M0, 
0x0022);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBH_OVRD_M0, 
0x0022);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBL_OVRD_M0, 
0x000C);
+   break;
+   /* Setting VCO for 9.72GHz */
+   case 1620:
+   case 2430:
+   case 3240:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 
0x0509);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 
0x0509);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 
0x0F00);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 
0x0F00);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 
0x0F08);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 
0x0F08);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0061);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0061);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0042);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0042);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+   break;
+   /* Setting VCO for 8.64GHz */
+   case 2160:
+   case 4320:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 
0x0509);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 
0x0509);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 
0x0F00);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 
0x0F00);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 
0x0F08);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 
0x0F08);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0056);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0056);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x003A);
+   cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x003A);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
+   cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
+   break;
+   /* Setting VCO for 8.1GHz */
+   case 8100:
+   cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
+   cdns_torrent_phy_write(reg

[PATCH 09/14] phy: cadence-torrent: Add separate functions for reusable code

2021-04-08 Thread Swapnil Jakhade
Torrent PHY driver currently supports single link DP configuration.
Prepare driver to support multilink DP configurations by adding
separate functions for common initialization sequence.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 53 +++
 1 file changed, 35 insertions(+), 18 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 69466481af26..e4dd8d1711a6 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1472,24 +1472,11 @@ static int cdns_torrent_phy_off(struct phy *phy)
return reset_control_assert(inst->lnk_rst);
 }
 
-static int cdns_torrent_dp_init(struct phy *phy)
+static void cdns_torrent_dp_common_init(struct cdns_torrent_phy *cdns_phy,
+   struct cdns_torrent_inst *inst)
 {
-   unsigned char lane_bits;
-   int ret;
-   struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
-   struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
-
-   switch (cdns_phy->ref_clk_rate) {
-   case CLK_19_2_MHZ:
-   case CLK_25_MHZ:
-   case CLK_100_MHZ:
-   /* Valid Ref Clock Rate */
-   break;
-   default:
-   dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n");
-   return -EINVAL;
-   }
+   unsigned char lane_bits;
 
cdns_torrent_dp_write(regmap, PHY_AUX_CTRL, 0x0003); /* enable AUX */
 
@@ -1510,8 +1497,10 @@ static int cdns_torrent_dp_init(struct phy *phy)
/* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
 
-   /* PHY PMA registers configuration functions */
-   /* Initialize PHY with max supported link rate, without SSC. */
+   /*
+* PHY PMA registers configuration functions
+* Initialize PHY with max supported link rate, without SSC.
+*/
if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ)
cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy,
cdns_phy->max_bit_rate,
@@ -1530,6 +1519,13 @@ static int cdns_torrent_dp_init(struct phy *phy)
 
/* take out of reset */
regmap_field_write(cdns_phy->phy_reset_ctrl, 0x1);
+}
+
+static int cdns_torrent_dp_start(struct cdns_torrent_phy *cdns_phy,
+struct cdns_torrent_inst *inst,
+struct phy *phy)
+{
+   int ret;
 
cdns_torrent_phy_on(phy);
 
@@ -1542,6 +1538,27 @@ static int cdns_torrent_dp_init(struct phy *phy)
return ret;
 }
 
+static int cdns_torrent_dp_init(struct phy *phy)
+{
+   struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
+   struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+
+   switch (cdns_phy->ref_clk_rate) {
+   case CLK_19_2_MHZ:
+   case CLK_25_MHZ:
+   case CLK_100_MHZ:
+   /* Valid Ref Clock Rate */
+   break;
+   default:
+   dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n");
+   return -EINVAL;
+   }
+
+   cdns_torrent_dp_common_init(cdns_phy, inst);
+
+   return cdns_torrent_dp_start(cdns_phy, inst, phy);
+}
+
 static int cdns_torrent_derived_refclk_enable(struct clk_hw *hw)
 {
struct cdns_torrent_derived_refclk *derived_refclk = 
to_cdns_torrent_derived_refclk(hw);
-- 
2.26.1



[PATCH 10/14] phy: cadence-torrent: Add function to get PLL to be configured for DP

2021-04-08 Thread Swapnil Jakhade
Torrent PHY PLL0 or PLL1 is used for DP depending on the single link or
multilink protocol configuration for which PHY is configured. In multilink
configurations with other protocols, either PLL0 or PLL1 will be used
for DP. For single link DP, both PLLs need to be configured at POR.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 32 +++
 1 file changed, 32 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index e4dd8d1711a6..44e28ea8ffa7 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -288,6 +288,11 @@ enum cdns_torrent_ssc_mode {
INTERNAL_SSC
 };
 
+enum cdns_torrent_dp_pll {
+   DP_PLL0 = 0x1,
+   DP_PLL1 = 0x2
+};
+
 struct cdns_torrent_inst {
struct phy *phy;
u32 mlane;
@@ -301,6 +306,7 @@ struct cdns_torrent_phy {
void __iomem *base; /* DPTX registers base */
void __iomem *sd_base; /* SD0801 registers base */
u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */
+   u32 dp_pll;
struct reset_control *phy_rst;
struct reset_control *apb_rst;
struct device *dev;
@@ -900,6 +906,30 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(struct 
cdns_torrent_phy *cdns_phy,
}
 }
 
+/* Set PLL used for DP configuration */
+static int cdns_torrent_dp_get_pll(struct cdns_torrent_phy *cdns_phy,
+  enum cdns_torrent_phy_type phy_t2)
+{
+   switch (phy_t2) {
+   case TYPE_PCIE:
+   case TYPE_USB:
+   cdns_phy->dp_pll = DP_PLL1;
+   break;
+   case TYPE_SGMII:
+   case TYPE_QSGMII:
+   cdns_phy->dp_pll = DP_PLL0;
+   break;
+   case TYPE_NONE:
+   cdns_phy->dp_pll = DP_PLL0 | DP_PLL1;
+   break;
+   default:
+   dev_err(cdns_phy->dev, "Unsupported PHY configuration\n");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 /*
  * Enable or disable PLL for selected lanes.
  */
@@ -1554,6 +1584,8 @@ static int cdns_torrent_dp_init(struct phy *phy)
return -EINVAL;
}
 
+   cdns_torrent_dp_get_pll(cdns_phy, TYPE_NONE);
+
cdns_torrent_dp_common_init(cdns_phy, inst);
 
return cdns_torrent_dp_start(cdns_phy, inst, phy);
-- 
2.26.1



[PATCH 12/14] phy: cadence-torrent: Add PCIe + DP multilink configuration

2021-04-08 Thread Swapnil Jakhade
Add PCIe + DP no SSC multilink configuration sequences.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 131 ++
 1 file changed, 131 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index becbf8456b2d..bf37569c6c51 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -2572,6 +2572,77 @@ static int cdns_torrent_phy_remove(struct 
platform_device *pdev)
return 0;
 }
 
+/* PCIe and DP link configuration */
+static struct cdns_reg_pairs pcie_dp_link_cmn_regs[] = {
+   {0x0003, PHY_PLL_CFG},
+   {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0},
+   {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1}
+};
+
+static struct cdns_reg_pairs pcie_dp_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x0012, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs dp_pcie_xcvr_diag_ln_regs[] = {
+   {0x0001, XCVR_DIAG_HSCLK_SEL},
+   {0x0009, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals pcie_dp_link_cmn_vals = {
+   .reg_pairs = pcie_dp_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(pcie_dp_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals pcie_dp_xcvr_diag_ln_vals = {
+   .reg_pairs = pcie_dp_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(pcie_dp_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals dp_pcie_xcvr_diag_ln_vals = {
+   .reg_pairs = dp_pcie_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(dp_pcie_xcvr_diag_ln_regs),
+};
+
+/* DP Multilink, 100 MHz Ref clk, no SSC */
+static struct cdns_reg_pairs dp_100_no_ssc_cmn_regs[] = {
+   {0x007F, CMN_TXPUCAL_TUNE},
+   {0x007F, CMN_TXPDCAL_TUNE}
+};
+
+static struct cdns_reg_pairs dp_100_no_ssc_tx_ln_regs[] = {
+   {0x00FB, TX_PSC_A0},
+   {0x04AA, TX_PSC_A2},
+   {0x04AA, TX_PSC_A3},
+   {0x000F, XCVR_DIAG_BIDI_CTRL}
+};
+
+static struct cdns_reg_pairs dp_100_no_ssc_rx_ln_regs[] = {
+   {0x, RX_PSC_A0},
+   {0x, RX_PSC_A2},
+   {0x, RX_PSC_A3},
+   {0x, RX_PSC_CAL},
+   {0x, RX_REE_GCSM1_CTRL},
+   {0x, RX_REE_GCSM2_CTRL},
+   {0x, RX_REE_PERGCSM_CTRL}
+};
+
+static struct cdns_torrent_vals dp_100_no_ssc_cmn_vals = {
+   .reg_pairs = dp_100_no_ssc_cmn_regs,
+   .num_regs = ARRAY_SIZE(dp_100_no_ssc_cmn_regs),
+};
+
+static struct cdns_torrent_vals dp_100_no_ssc_tx_ln_vals = {
+   .reg_pairs = dp_100_no_ssc_tx_ln_regs,
+   .num_regs = ARRAY_SIZE(dp_100_no_ssc_tx_ln_regs),
+};
+
+static struct cdns_torrent_vals dp_100_no_ssc_rx_ln_vals = {
+   .reg_pairs = dp_100_no_ssc_rx_ln_regs,
+   .num_regs = ARRAY_SIZE(dp_100_no_ssc_rx_ln_regs),
+};
+
 /* Single DisplayPort(DP) link configuration */
 static struct cdns_reg_pairs sl_dp_link_cmn_regs[] = {
{0x, PHY_PLL_CFG},
@@ -3514,6 +3585,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
[TYPE_NONE] = {
[NO_SSC] = _dp_link_cmn_vals,
},
+   [TYPE_PCIE] = {
+   [NO_SSC] = _dp_link_cmn_vals,
+   },
},
[TYPE_PCIE] = {
[TYPE_NONE] = {
@@ -3536,6 +3610,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
[EXTERNAL_SSC] = _usb_link_cmn_vals,
[INTERNAL_SSC] = _usb_link_cmn_vals,
},
+   [TYPE_DP] = {
+   [NO_SSC] = _dp_link_cmn_vals,
+   },
},
[TYPE_SGMII] = {
[TYPE_NONE] = {
@@ -3595,6 +3672,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
[TYPE_NONE] = {
[NO_SSC] = _dp_xcvr_diag_ln_vals,
},
+   [TYPE_PCIE] = {
+   [NO_SSC] = _pcie_xcvr_diag_ln_vals,
+   },
},
[TYPE_PCIE] = {
[TYPE_NONE] = {
@@ -3617,6 +3697,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
[EXTERNAL_SSC] = _usb_xcvr_diag_ln_vals,
[INTERNAL_SSC] = _usb_xcvr_diag_ln_vals,
},
+   [TYPE_DP] = {
+   [NO_SSC] = _dp_xcvr_diag_ln_vals,
+   },
},
[TYPE_SGMII] = {
[TYPE_NONE] = {
@@ -3715,6 +3798,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
[TYPE_NONE] = {
[NO_SSC] = _dp_100_no_ssc_cmn_vals

[PATCH 01/14] phy: cadence-torrent: Remove use of CamelCase to fix checkpatch CHECK message

2021-04-08 Thread Swapnil Jakhade
Script checkpatch with --strict option gives message:
CHECK: Avoid CamelCase: 
CHECK: Avoid CamelCase: 
Fix this by removing CamelCase usage. No functional change.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 24 +++
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 0477e7beebbf..ff647669f1a3 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -24,8 +24,8 @@
 #include 
 #include 
 
-#define REF_CLK_19_2MHz1920
-#define REF_CLK_25MHz  2500
+#define REF_CLK_19_2MHZ1920
+#define REF_CLK_25MHZ  2500
 
 #define MAX_NUM_LANES  4
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
@@ -695,12 +695,12 @@ static int cdns_torrent_dp_configure_rate(struct 
cdns_torrent_phy *cdns_phy,
ndelay(200);
 
/* DP Rate Change - VCO Output settings. */
-   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) {
+   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) {
/* PMA common configuration 19.2MHz */
cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate,
dp->ssc);
cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
-   } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) {
+   } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) {
/* PMA common configuration 25MHz */
cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate,
  dp->ssc);
@@ -993,8 +993,8 @@ static int cdns_torrent_dp_init(struct phy *phy)
struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
 
switch (cdns_phy->ref_clk_rate) {
-   case REF_CLK_19_2MHz:
-   case REF_CLK_25MHz:
+   case REF_CLK_19_2MHZ:
+   case REF_CLK_25MHZ:
/* Valid Ref Clock Rate */
break;
default:
@@ -1026,11 +1026,11 @@ static int cdns_torrent_dp_init(struct phy *phy)
 
/* PHY PMA registers configuration functions */
/* Initialize PHY with max supported link rate, without SSC. */
-   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
+   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ)
cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy,
cdns_phy->max_bit_rate,
false);
-   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
+   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ)
cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy,
  cdns_phy->max_bit_rate,
  false);
@@ -1074,10 +1074,10 @@ static void cdns_torrent_dp_pma_cfg(struct 
cdns_torrent_phy *cdns_phy,
 {
unsigned int i;
 
-   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
+   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ)
/* PMA common configuration 19.2MHz */
cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
-   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
+   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ)
/* PMA common configuration 25MHz */
cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
 
@@ -1529,10 +1529,10 @@ static void cdns_torrent_dp_pma_lane_cfg(struct 
cdns_torrent_phy *cdns_phy,
 unsigned int lane)
 {
/* Per lane, refclock-dependent receiver detection setting */
-   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
+   if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ)
cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
   TX_RCVDET_ST_TMR, 0x0780);
-   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
+   else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ)
cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
   TX_RCVDET_ST_TMR, 0x09C4);
 
-- 
2.26.1



[PATCH 0/4] PHY: Update Cadence Torrent PHY multilink configurations specific to TI

2021-03-03 Thread Swapnil Jakhade
This patch series updates Torrent PHY driver for multilink configurations
specific to TI platform. It also adds support for configuring QSGMII in
TI Wiz driver.

This patch series is dependent on [1] and should be applied on
top of this.

[1] 
https://patchwork.kernel.org/project/linux-phy/cover/20210222112314.10772-1-kis...@ti.com/

Kishon Vijay Abraham I (2):
  phy: ti: j721e-wiz: Add support for configuring QSGMII
  phy: cadence-torrent: Update SGMII/QSGMII configuration specific to TI

Swapnil Jakhade (2):
  phy: cadence-torrent: Update PCIe + QSGMII config for correct PLL1
clock
  phy: cadence-torrent: Update PCIe + USB config for correct PLL1 clock

 drivers/phy/cadence/phy-cadence-torrent.c | 182 +++---
 drivers/phy/ti/phy-j721e-wiz.c|  64 +++-
 2 files changed, 186 insertions(+), 60 deletions(-)

-- 
2.26.1



[PATCH 4/4] phy: cadence-torrent: Update PCIe + USB config for correct PLL1 clock

2021-03-03 Thread Swapnil Jakhade
Update PCIe + USB register sequences for correct PLL1 clock configuration.
Also, update sequences for other USB configurations with dependent changes.

Signed-off-by: Swapnil Jakhade 
Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 47 +++
 1 file changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index f78a6731c26a..b371795e66a2 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -2655,8 +2655,6 @@ static struct cdns_reg_pairs usb_100_int_ssc_cmn_regs[] = 
{
{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
-   {0x0003, CMN_PLL0_VCOCAL_TCTRL},
-   {0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
@@ -2664,7 +2662,9 @@ static struct cdns_reg_pairs usb_100_int_ssc_cmn_regs[] = 
{
{0x0005, CMN_PLL0_LOCK_PLLCNT_THR},
{0x0005, CMN_PLL1_LOCK_PLLCNT_THR},
{0x8200, CMN_CDIAG_CDB_PWRI_OVRD},
-   {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD}
+   {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD},
+   {0x007F, CMN_TXPUCAL_TUNE},
+   {0x007F, CMN_TXPDCAL_TUNE}
 };
 
 static struct cdns_torrent_vals usb_100_int_ssc_cmn_vals = {
@@ -2707,13 +2707,28 @@ static struct cdns_torrent_vals usb_phy_pcs_cmn_vals = {
 };
 
 /* USB 100 MHz Ref clk, no SSC */
-static struct cdns_reg_pairs usb_100_no_ssc_cmn_regs[] = {
+static struct cdns_reg_pairs sl_usb_100_no_ssc_cmn_regs[] = {
+   {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+   {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+   {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0},
{0x0003, CMN_PLL0_VCOCAL_TCTRL},
{0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x8200, CMN_CDIAG_CDB_PWRI_OVRD},
{0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD}
 };
 
+static struct cdns_torrent_vals sl_usb_100_no_ssc_cmn_vals = {
+   .reg_pairs = sl_usb_100_no_ssc_cmn_regs,
+   .num_regs = ARRAY_SIZE(sl_usb_100_no_ssc_cmn_regs),
+};
+
+static struct cdns_reg_pairs usb_100_no_ssc_cmn_regs[] = {
+   {0x8200, CMN_CDIAG_CDB_PWRI_OVRD},
+   {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD},
+   {0x007F, CMN_TXPUCAL_TUNE},
+   {0x007F, CMN_TXPDCAL_TUNE}
+};
+
 static struct cdns_reg_pairs usb_100_no_ssc_tx_ln_regs[] = {
{0x02FF, TX_PSC_A0},
{0x06AF, TX_PSC_A1},
@@ -3497,8 +3512,8 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
[TYPE_USB] = {
[TYPE_NONE] = {
-   [NO_SSC] = _100_no_ssc_cmn_vals,
-   [EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
+   [NO_SSC] = _usb_100_no_ssc_cmn_vals,
+   [EXTERNAL_SSC] = _usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = _usb_100_int_ssc_cmn_vals,
},
[TYPE_PCIE] = {
@@ -3507,13 +3522,13 @@ static const struct cdns_torrent_data cdns_map_torrent 
= {
[INTERNAL_SSC] = _100_int_ssc_cmn_vals,
},
[TYPE_SGMII] = {
-   [NO_SSC] = _100_no_ssc_cmn_vals,
-   [EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
+   [NO_SSC] = _usb_100_no_ssc_cmn_vals,
+   [EXTERNAL_SSC] = _usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = _usb_100_int_ssc_cmn_vals,
},
[TYPE_QSGMII] = {
-   [NO_SSC] = _100_no_ssc_cmn_vals,
-   [EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
+   [NO_SSC] = _usb_100_no_ssc_cmn_vals,
+   [EXTERNAL_SSC] = _usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = _usb_100_int_ssc_cmn_vals,
},
},
@@ -3906,8 +3921,8 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
},
[TYPE_USB] = {
[TYPE_NONE] = {
-   [NO_SSC] = _100_no_ssc_cmn_vals,
-   [EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
+   [NO_SSC] = _usb_100_no_ssc_cmn_vals,
+   [EXTERNAL_SSC] = _usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = _usb_100_int_ssc_cmn_vals,
},
[TYPE_PCIE] = {
@@ -3916,13 +3931,13 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
[INTERNAL_SSC] = _100_int_ssc_cmn_vals

[PATCH 3/4] phy: cadence-torrent: Update SGMII/QSGMII configuration specific to TI

2021-03-03 Thread Swapnil Jakhade
From: Kishon Vijay Abraham I 

Update SGMII/QSGMII configuration specific to TI.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 58 +--
 1 file changed, 44 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index ae1cea2271be..f78a6731c26a 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -174,6 +174,7 @@
 #define XCVR_DIAG_PLLDRC_CTRL  0x00E5U
 #define XCVR_DIAG_HSCLK_SEL0x00E6U
 #define XCVR_DIAG_HSCLK_DIV0x00E7U
+#define XCVR_DIAG_RXCLK_CTRL   0x00E9U
 #define XCVR_DIAG_BIDI_CTRL0x00EAU
 #define XCVR_DIAG_PSC_OVRD 0x00EBU
 #define TX_PSC_A0  0x0100U
@@ -2870,6 +2871,15 @@ static struct cdns_reg_pairs 
sgmii_100_no_ssc_tx_ln_regs[] = {
{0x00B3, DRV_DIAG_TX_DRV}
 };
 
+static struct cdns_reg_pairs ti_sgmii_100_no_ssc_tx_ln_regs[] = {
+   {0x00F3, TX_PSC_A0},
+   {0x04A2, TX_PSC_A2},
+   {0x04A2, TX_PSC_A3},
+   {0x, TX_TXCC_CPOST_MULT_00},
+   {0x00B3, DRV_DIAG_TX_DRV},
+   {0x4000, XCVR_DIAG_RXCLK_CTRL},
+};
+
 static struct cdns_reg_pairs sgmii_100_no_ssc_rx_ln_regs[] = {
{0x091D, RX_PSC_A0},
{0x0900, RX_PSC_A2},
@@ -2898,6 +2908,11 @@ static struct cdns_torrent_vals 
sgmii_100_no_ssc_tx_ln_vals = {
.num_regs = ARRAY_SIZE(sgmii_100_no_ssc_tx_ln_regs),
 };
 
+static struct cdns_torrent_vals ti_sgmii_100_no_ssc_tx_ln_vals = {
+   .reg_pairs = ti_sgmii_100_no_ssc_tx_ln_regs,
+   .num_regs = ARRAY_SIZE(ti_sgmii_100_no_ssc_tx_ln_regs),
+};
+
 static struct cdns_torrent_vals sgmii_100_no_ssc_rx_ln_vals = {
.reg_pairs = sgmii_100_no_ssc_rx_ln_regs,
.num_regs = ARRAY_SIZE(sgmii_100_no_ssc_rx_ln_regs),
@@ -2988,6 +3003,16 @@ static struct cdns_reg_pairs 
qsgmii_100_no_ssc_tx_ln_regs[] = {
{0x0003, DRV_DIAG_TX_DRV}
 };
 
+static struct cdns_reg_pairs ti_qsgmii_100_no_ssc_tx_ln_regs[] = {
+   {0x00F3, TX_PSC_A0},
+   {0x04A2, TX_PSC_A2},
+   {0x04A2, TX_PSC_A3},
+   {0x, TX_TXCC_CPOST_MULT_00},
+   {0x0011, TX_TXCC_MGNFS_MULT_100},
+   {0x0003, DRV_DIAG_TX_DRV},
+   {0x4000, XCVR_DIAG_RXCLK_CTRL},
+};
+
 static struct cdns_reg_pairs qsgmii_100_no_ssc_rx_ln_regs[] = {
{0x091D, RX_PSC_A0},
{0x0900, RX_PSC_A2},
@@ -3016,6 +3041,11 @@ static struct cdns_torrent_vals 
qsgmii_100_no_ssc_tx_ln_vals = {
.num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_tx_ln_regs),
 };
 
+static struct cdns_torrent_vals ti_qsgmii_100_no_ssc_tx_ln_vals = {
+   .reg_pairs = ti_qsgmii_100_no_ssc_tx_ln_regs,
+   .num_regs = ARRAY_SIZE(ti_qsgmii_100_no_ssc_tx_ln_regs),
+};
+
 static struct cdns_torrent_vals qsgmii_100_no_ssc_rx_ln_vals = {
.reg_pairs = qsgmii_100_no_ssc_rx_ln_regs,
.num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_rx_ln_regs),
@@ -3922,32 +3952,32 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
},
[TYPE_SGMII] = {
[TYPE_NONE] = {
-   [NO_SSC] = _100_no_ssc_tx_ln_vals,
+   [NO_SSC] = _sgmii_100_no_ssc_tx_ln_vals,
},
[TYPE_PCIE] = {
-   [NO_SSC] = _100_no_ssc_tx_ln_vals,
-   [EXTERNAL_SSC] = _100_no_ssc_tx_ln_vals,
-   [INTERNAL_SSC] = _100_no_ssc_tx_ln_vals,
+   [NO_SSC] = _sgmii_100_no_ssc_tx_ln_vals,
+   [EXTERNAL_SSC] = 
_sgmii_100_no_ssc_tx_ln_vals,
+   [INTERNAL_SSC] = 
_sgmii_100_no_ssc_tx_ln_vals,
},
[TYPE_USB] = {
-   [NO_SSC] = _100_no_ssc_tx_ln_vals,
-   [EXTERNAL_SSC] = _100_no_ssc_tx_ln_vals,
-   [INTERNAL_SSC] = _100_no_ssc_tx_ln_vals,
+   [NO_SSC] = _sgmii_100_no_ssc_tx_ln_vals,
+   [EXTERNAL_SSC] = 
_sgmii_100_no_ssc_tx_ln_vals,
+   [INTERNAL_SSC] = 
_sgmii_100_no_ssc_tx_ln_vals,
},
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
-   [NO_SSC] = _100_no_ssc_tx_ln_vals,
+   [NO_SSC] = _qsgmii_100_no_ssc_tx_ln_vals,
},
[TYPE_PCIE] = {
-   [NO_SSC] = _100_no_ssc_tx_ln_vals,
-   [EXTERNAL_SSC] = _100_no_ssc_tx_ln_vals,
-   [INTERNAL_SSC] = _100_no_ssc_tx_ln_vals,
+   [NO_SSC] = _qsgmii_100_no_ssc_tx_ln_vals

[PATCH 2/4] phy: ti: j721e-wiz: Add support for configuring QSGMII

2021-03-03 Thread Swapnil Jakhade
From: Kishon Vijay Abraham I 

Configure MAC clock dividers required for QSGMII to be functional.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/ti/phy-j721e-wiz.c | 64 --
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index 03896240a5d5..995c7dbec77b 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -27,6 +27,7 @@
 #define WIZ_SERDES_RST 0x40c
 #define WIZ_SERDES_TYPEC   0x410
 #define WIZ_LANECTL(n) (0x480 + (0x40 * (n)))
+#define WIZ_LANEDIV(n) (0x484 + (0x40 * (n)))
 
 #define WIZ_MAX_INPUT_CLOCKS   4
 /* To include mux clocks, divider clocks and gate clocks */
@@ -127,6 +128,20 @@ static const struct reg_field p0_fullrt_div[WIZ_MAX_LANES] 
= {
REG_FIELD(WIZ_LANECTL(3), 22, 23),
 };
 
+static const struct reg_field p_mac_div_sel0[WIZ_MAX_LANES] = {
+   REG_FIELD(WIZ_LANEDIV(0), 16, 22),
+   REG_FIELD(WIZ_LANEDIV(1), 16, 22),
+   REG_FIELD(WIZ_LANEDIV(2), 16, 22),
+   REG_FIELD(WIZ_LANEDIV(3), 16, 22),
+};
+
+static const struct reg_field p_mac_div_sel1[WIZ_MAX_LANES] = {
+   REG_FIELD(WIZ_LANEDIV(0), 0, 8),
+   REG_FIELD(WIZ_LANEDIV(1), 0, 8),
+   REG_FIELD(WIZ_LANEDIV(2), 0, 8),
+   REG_FIELD(WIZ_LANEDIV(3), 0, 8),
+};
+
 static const struct reg_field typec_ln10_swap =
REG_FIELD(WIZ_SERDES_TYPEC, 30, 30);
 
@@ -252,6 +267,8 @@ struct wiz {
struct regmap_field *p_align[WIZ_MAX_LANES];
struct regmap_field *p_raw_auto_start[WIZ_MAX_LANES];
struct regmap_field *p_standard_mode[WIZ_MAX_LANES];
+   struct regmap_field *p_mac_div_sel0[WIZ_MAX_LANES];
+   struct regmap_field *p_mac_div_sel1[WIZ_MAX_LANES];
struct regmap_field *p0_fullrt_div[WIZ_MAX_LANES];
struct regmap_field *pma_cmn_refclk_int_mode;
struct regmap_field *pma_cmn_refclk_mode;
@@ -290,6 +307,27 @@ static int wiz_reset(struct wiz *wiz)
return 0;
 }
 
+static int wiz_p_mac_div_sel(struct wiz *wiz)
+{
+   u32 num_lanes = wiz->num_lanes;
+   int ret;
+   int i;
+
+   for (i = 0; i < num_lanes; i++) {
+   if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
+   ret = regmap_field_write(wiz->p_mac_div_sel0[i], 1);
+   if (ret)
+   return ret;
+
+   ret = regmap_field_write(wiz->p_mac_div_sel1[i], 2);
+   if (ret)
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
 static int wiz_mode_select(struct wiz *wiz)
 {
u32 num_lanes = wiz->num_lanes;
@@ -300,8 +338,8 @@ static int wiz_mode_select(struct wiz *wiz)
for (i = 0; i < num_lanes; i++) {
if (wiz->lane_phy_type[i] == PHY_TYPE_DP)
mode = LANE_MODE_GEN1;
-   else
-   mode = LANE_MODE_GEN4;
+   else if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII)
+   mode = LANE_MODE_GEN2;
 
ret = regmap_field_write(wiz->p_standard_mode[i], mode);
if (ret)
@@ -347,6 +385,12 @@ static int wiz_init(struct wiz *wiz)
return ret;
}
 
+   ret = wiz_p_mac_div_sel(wiz);
+   if (ret) {
+   dev_err(dev, "Configuring P0 MAC DIV SEL failed\n");
+   return ret;
+   }
+
ret = wiz_init_raw_interface(wiz, true);
if (ret) {
dev_err(dev, "WIZ interface initialization failed\n");
@@ -471,6 +515,22 @@ static int wiz_regfield_init(struct wiz *wiz)
dev_err(dev, "P%d_FULLRT_DIV reg field init failed\n", 
i);
return PTR_ERR(wiz->p0_fullrt_div[i]);
}
+
+   wiz->p_mac_div_sel0[i] =
+ devm_regmap_field_alloc(dev, regmap, p_mac_div_sel0[i]);
+   if (IS_ERR(wiz->p_mac_div_sel0[i])) {
+   dev_err(dev, "P%d_MAC_DIV_SEL0 reg field init fail\n",
+   i);
+   return PTR_ERR(wiz->p_mac_div_sel0[i]);
+   }
+
+   wiz->p_mac_div_sel1[i] =
+ devm_regmap_field_alloc(dev, regmap, p_mac_div_sel1[i]);
+   if (IS_ERR(wiz->p_mac_div_sel1[i])) {
+   dev_err(dev, "P%d_MAC_DIV_SEL1 reg field init fail\n",
+   i);
+   return PTR_ERR(wiz->p_mac_div_sel1[i]);
+   }
}
 
wiz->typec_ln10_swap = devm_regmap_field_alloc(dev, regmap,
-- 
2.26.1



[PATCH 1/4] phy: cadence-torrent: Update PCIe + QSGMII config for correct PLL1 clock

2021-03-03 Thread Swapnil Jakhade
For PCIe + QSGMII configuration where QSGMII was using PLL1 and was
expecting 10GHz clock, configuration was giving 8GHz clock. Update
register sequences to get correct PLL1 configuration.

Also, update single link PCIe and single link SGMII/QSGMII configurations
with related changes.

Signed-off-by: Swapnil Jakhade 
Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 77 ++-
 1 file changed, 49 insertions(+), 28 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 9a882bcfd7be..ae1cea2271be 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -126,6 +126,8 @@
 #define CMN_PLL1_FRACDIVH_M0   0x00D2U
 #define CMN_PLL1_HIGH_THR_M0   0x00D3U
 #define CMN_PLL1_DSM_DIAG_M0   0x00D4U
+#define CMN_PLL1_DSM_FBH_OVRD_M0   0x00D5U
+#define CMN_PLL1_DSM_FBL_OVRD_M0   0x00D6U
 #define CMN_PLL1_SS_CTRL1_M0   0x00D8U
 #define CMN_PLL1_SS_CTRL2_M00x00D9U
 #define CMN_PLL1_SS_CTRL3_M00x00DAU
@@ -167,6 +169,7 @@
 #define TX_TXCC_CPOST_MULT_00  0x004CU
 #define TX_TXCC_CPOST_MULT_01  0x004DU
 #define TX_TXCC_MGNFS_MULT_000 0x0050U
+#define TX_TXCC_MGNFS_MULT_100 0x0054U
 #define DRV_DIAG_TX_DRV0x00C6U
 #define XCVR_DIAG_PLLDRC_CTRL  0x00E5U
 #define XCVR_DIAG_HSCLK_SEL0x00E6U
@@ -2841,12 +2844,22 @@ static struct cdns_torrent_vals 
sgmii_pcie_xcvr_diag_ln_vals = {
 };
 
 /* SGMII 100 MHz Ref clk, no SSC */
-static struct cdns_reg_pairs sgmii_100_no_ssc_cmn_regs[] = {
+static struct cdns_reg_pairs sl_sgmii_100_no_ssc_cmn_regs[] = {
+   {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+   {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+   {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0},
{0x0003, CMN_PLL0_VCOCAL_TCTRL},
-   {0x0003, CMN_PLL1_VCOCAL_TCTRL},
-   {0x3700, CMN_DIAG_BIAS_OVRD1},
-   {0x0008, CMN_TXPUCAL_TUNE},
-   {0x0008, CMN_TXPDCAL_TUNE}
+   {0x0003, CMN_PLL1_VCOCAL_TCTRL}
+};
+
+static struct cdns_torrent_vals sl_sgmii_100_no_ssc_cmn_vals = {
+   .reg_pairs = sl_sgmii_100_no_ssc_cmn_regs,
+   .num_regs = ARRAY_SIZE(sl_sgmii_100_no_ssc_cmn_regs),
+};
+
+static struct cdns_reg_pairs sgmii_100_no_ssc_cmn_regs[] = {
+   {0x007F, CMN_TXPUCAL_TUNE},
+   {0x007F, CMN_TXPDCAL_TUNE}
 };
 
 static struct cdns_reg_pairs sgmii_100_no_ssc_tx_ln_regs[] = {
@@ -2932,17 +2945,14 @@ static struct cdns_reg_pairs 
sgmii_100_int_ssc_cmn_regs[] = {
{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
-   {0x0003, CMN_PLL0_VCOCAL_TCTRL},
-   {0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
{0x00C7, CMN_PLL1_LOCK_PLLCNT_START},
{0x0005, CMN_PLL0_LOCK_PLLCNT_THR},
{0x0005, CMN_PLL1_LOCK_PLLCNT_THR},
-   {0x3700, CMN_DIAG_BIAS_OVRD1},
-   {0x0008, CMN_TXPUCAL_TUNE},
-   {0x0008, CMN_TXPDCAL_TUNE}
+   {0x007F, CMN_TXPUCAL_TUNE},
+   {0x007F, CMN_TXPDCAL_TUNE}
 };
 
 static struct cdns_torrent_vals sgmii_100_int_ssc_cmn_vals = {
@@ -2951,16 +2961,30 @@ static struct cdns_torrent_vals 
sgmii_100_int_ssc_cmn_vals = {
 };
 
 /* QSGMII 100 MHz Ref clk, no SSC */
-static struct cdns_reg_pairs qsgmii_100_no_ssc_cmn_regs[] = {
+static struct cdns_reg_pairs sl_qsgmii_100_no_ssc_cmn_regs[] = {
+   {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+   {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+   {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0},
{0x0003, CMN_PLL0_VCOCAL_TCTRL},
{0x0003, CMN_PLL1_VCOCAL_TCTRL}
 };
 
+static struct cdns_torrent_vals sl_qsgmii_100_no_ssc_cmn_vals = {
+   .reg_pairs = sl_qsgmii_100_no_ssc_cmn_regs,
+   .num_regs = ARRAY_SIZE(sl_qsgmii_100_no_ssc_cmn_regs),
+};
+
+static struct cdns_reg_pairs qsgmii_100_no_ssc_cmn_regs[] = {
+   {0x007F, CMN_TXPUCAL_TUNE},
+   {0x007F, CMN_TXPDCAL_TUNE}
+};
+
 static struct cdns_reg_pairs qsgmii_100_no_ssc_tx_ln_regs[] = {
{0x00F3, TX_PSC_A0},
{0x04A2, TX_PSC_A2},
{0x04A2, TX_PSC_A3},
{0x, TX_TXCC_CPOST_MULT_00},
+   {0x0011, TX_TXCC_MGNFS_MULT_100},
{0x0003, DRV_DIAG_TX_DRV}
 };
 
@@ -3039,14 +3063,14 @@ static struct cdns_reg_pairs 
qsgmii_100_int_ssc_cmn_regs[] = {
{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
-   {0x0003, CMN_PLL0_VCOCAL_TCTRL},
-   {0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
{0x00C7, CMN_PLL1_LOCK_PLLCNT_START},
{0x0005, CMN_PLL0_LOCK_PLLCNT_THR},
-   {0x0005

[PATCH] dt-bindings: phy: Add Cadence Sierra PHY bindings in YAML format

2020-10-28 Thread Swapnil Jakhade
Add Cadence Sierra PHY bindings in YAML format.

Signed-off-by: Swapnil Jakhade 
---
 .../bindings/phy/phy-cadence-sierra.txt   |  70 
 .../bindings/phy/phy-cadence-sierra.yaml  | 152 ++
 2 files changed, 152 insertions(+), 70 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt
 create mode 100644 
Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml

diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt 
b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt
deleted file mode 100644
index 03f5939d3d19..
--- a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-Cadence Sierra PHY

-
-Required properties:
-- compatible:  Must be "cdns,sierra-phy-t0" for Sierra in Cadence platform
-   Must be "ti,sierra-phy-t0" for Sierra in TI's J721E SoC.
-- resets:  Must contain an entry for each in reset-names.
-   See ../reset/reset.txt for details.
-- reset-names: Must include "sierra_reset" and "sierra_apb".
-   "sierra_reset" must control the reset line to the PHY.
-   "sierra_apb" must control the reset line to the APB PHY
-   interface ("sierra_apb" is optional).
-- reg: register range for the PHY.
-- #address-cells: Must be 1
-- #size-cells: Must be 0
-
-Optional properties:
-- clocks:  Must contain an entry in clock-names.
-   See ../clocks/clock-bindings.txt for details.
-- clock-names: Must contain "cmn_refclk_dig_div" and
-   "cmn_refclk1_dig_div" for configuring the frequency of
-   the clock to the lanes. "phy_clk" is deprecated.
-- cdns,autoconf:   A boolean property whose presence indicates that the
-   PHY registers will be configured by hardware. If not
-   present, all sub-node optional properties must be
-   provided.
-
-Sub-nodes:
-  Each group of PHY lanes with a single master lane should be represented as
-  a sub-node. Note that the actual configuration of each lane is determined by
-  hardware strapping, and must match the configuration specified here.
-
-Sub-node required properties:
-- #phy-cells:  Generic PHY binding; must be 0.
-- reg: The master lane number.  This is the lowest numbered lane
-   in the lane group.
-- resets:  Must contain one entry which controls the reset line for the
-   master lane of the sub-node.
-   See ../reset/reset.txt for details.
-
-Sub-node optional properties:
-- cdns,num-lanes:  Number of lanes in this group.  From 1 to 4.  The
-   group is made up of consecutive lanes.
-- cdns,phy-type:   Can be PHY_TYPE_PCIE or PHY_TYPE_USB3, depending on
-   configuration of lanes.
-
-Example:
-   pcie_phy4: pcie-phy@fd24 {
-   compatible = "cdns,sierra-phy-t0";
-   reg = <0x0 0xfd24 0x0 0x4>;
-   resets = < 0>, < 1>;
-   reset-names = "sierra_reset", "sierra_apb";
-   clocks = <>;
-   clock-names = "phy_clk";
-   #address-cells = <1>;
-   #size-cells = <0>;
-   pcie0_phy0: pcie-phy@0 {
-   reg = <0>;
-   resets = < 2>;
-   cdns,num-lanes = <2>;
-   #phy-cells = <0>;
-   cdns,phy-type = ;
-   };
-   pcie0_phy1: pcie-phy@2 {
-   reg = <2>;
-   resets = < 4>;
-   cdns,num-lanes = <1>;
-   #phy-cells = <0>;
-   cdns,phy-type = ;
-   };
diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml 
b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
new file mode 100644
index ..d210843863df
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
@@ -0,0 +1,152 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/phy-cadence-sierra.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Cadence Sierra PHY binding
+
+description:
+  This binding describes the Cadence Sierra PHY. Sierra PHY supports multilink
+  multiprotocol combinations including protocols such as PCIe, USB etc.
+
+maintainers:
+  - Swapnil Jakhade 
+  - Yuti Amonkar 
+
+properties:
+  compatible:
+enum:
+  - c

[PATCH v11 0/3] drm: Add support for Cadence MHDP8546 DPI/DP bridge and J721E wrapper.

2020-09-18 Thread Swapnil Jakhade
3:
- Added if / then clause to validate that the reg length is proper
  based on the value of the compatible property.
- Updated phy property description in YAML to a generic one.
- Renamed num_lanes and max_bit_rate property strings to cdns,num-lanes
  and cdns,max-bit-rate.

v2:
- Use enum in compatible property of YAML file.
- Add reg-names property to YAML file
- Add minItems and maxItems to reg property in YAML.
- Remove cdns_mhdp_link_probe function to remove
  duplication of reading dpcd capabilities.

Swapnil Jakhade (2):
  drm: bridge: Add support for Cadence MHDP8546 DPI/DP bridge
  drm: bridge: cdns-mhdp8546: Add TI J721E wrapper

Yuti Amonkar (1):
  dt-bindings: drm/bridge: Document Cadence MHDP8546 bridge bindings

 .../display/bridge/cdns,mhdp8546.yaml |  169 ++
 drivers/gpu/drm/bridge/Kconfig|2 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/cadence/Kconfig|   24 +
 drivers/gpu/drm/bridge/cadence/Makefile   |4 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 2532 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  400 +++
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.c  |   78 +
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.h  |   19 +
 9 files changed, 3229 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
 create mode 100644 drivers/gpu/drm/bridge/cadence/Kconfig
 create mode 100644 drivers/gpu/drm/bridge/cadence/Makefile
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.h

-- 
2.26.1



[PATCH v11 1/3] dt-bindings: drm/bridge: Document Cadence MHDP8546 bridge bindings

2020-09-18 Thread Swapnil Jakhade
From: Yuti Amonkar 

Document the bindings used for the Cadence MHDP8546 DPI/DP bridge in
yaml format.

Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
---
 .../display/bridge/cdns,mhdp8546.yaml | 169 ++
 1 file changed, 169 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml

diff --git 
a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml 
b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
new file mode 100644
index ..74d675fc6e7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
@@ -0,0 +1,169 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/bridge/cdns,mhdp8546.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Cadence MHDP8546 bridge
+
+maintainers:
+  - Swapnil Jakhade 
+  - Yuti Amonkar 
+
+properties:
+  compatible:
+enum:
+  - cdns,mhdp8546
+  - ti,j721e-mhdp8546
+
+  reg:
+minItems: 1
+maxItems: 2
+items:
+  - description:
+  Register block of mhdptx apb registers up to PHY mapped area 
(AUX_CONFIG_P).
+  The AUX and PMA registers are not part of this range, they are 
instead
+  included in the associated PHY.
+  - description:
+  Register block for DSS_EDP0_INTG_CFG_VP registers in case of TI J7 
SoCs.
+
+  reg-names:
+minItems: 1
+maxItems: 2
+items:
+  - const: mhdptx
+  - const: j721e-intg
+
+  clocks:
+maxItems: 1
+description:
+  DP bridge clock, used by the IP to know how to translate a number of
+  clock cycles into a time (which is used to comply with DP standard 
timings
+  and delays).
+
+  phys:
+maxItems: 1
+description:
+  phandle to the DisplayPort PHY.
+
+  phy-names:
+items:
+  - const: dpphy
+
+  power-domains:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  ports:
+type: object
+description:
+  Ports as described in Documentation/devicetree/bindings/graph.txt.
+
+properties:
+  '#address-cells':
+const: 1
+
+  '#size-cells':
+const: 0
+
+  port@0:
+type: object
+description:
+  First input port representing the DP bridge input.
+
+  port@1:
+type: object
+description:
+  Second input port representing the DP bridge input.
+
+  port@2:
+type: object
+description:
+  Third input port representing the DP bridge input.
+
+  port@3:
+type: object
+description:
+  Fourth input port representing the DP bridge input.
+
+  port@4:
+type: object
+description:
+  Output port representing the DP bridge output.
+
+required:
+  - port@0
+  - port@4
+  - '#address-cells'
+  - '#size-cells'
+
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: ti,j721e-mhdp8546
+then:
+  properties:
+reg:
+  minItems: 2
+reg-names:
+  minItems: 2
+else:
+  properties:
+reg:
+  maxItems: 1
+reg-names:
+  maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - reg
+  - reg-names
+  - phys
+  - phy-names
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mhdp: dp-bridge@f0fb00 {
+compatible = "cdns,mhdp8546";
+reg = <0xf0 0xfb00 0x0 0x100>;
+reg-names = "mhdptx";
+clocks = <_clock>;
+phys = <_phy>;
+phy-names = "dpphy";
+interrupts = ;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+dp_bridge_input: endpoint {
+remote-endpoint = <_dpi_output>;
+};
+};
+
+port@4 {
+reg = <4>;
+dp_bridge_output: endpoint {
+remote-endpoint = <_dp_connector_input>;
+};
+};
+};
+};
+};
+...
-- 
2.26.1



[PATCH v11 2/3] drm: bridge: Add support for Cadence MHDP8546 DPI/DP bridge

2020-09-18 Thread Swapnil Jakhade
Add a new DRM bridge driver for Cadence MHDP8546 DPTX IP used in TI J721E
SoC. MHDP DPTX IP is the component that complies with VESA DisplayPort (DP)
and embedded Display Port (eDP) standards. It integrates uCPU running the
embedded Firmware (FW) interfaced over APB interface.

Basically, it takes a DPI stream as input and outputs it encoded in DP
format. Currently, it supports only SST mode.

Co-developed-by: Tomi Valkeinen 
Signed-off-by: Tomi Valkeinen 
Co-developed-by: Jyri Sarha 
Signed-off-by: Jyri Sarha 
Signed-off-by: Quentin Schulz 
Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Reviewed-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/Kconfig|2 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/cadence/Kconfig|   11 +
 drivers/gpu/drm/bridge/cadence/Makefile   |3 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 2522 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  399 +++
 6 files changed, 2938 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/Kconfig
 create mode 100644 drivers/gpu/drm/bridge/cadence/Makefile
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 3e11af4e9f63..ef91646441b1 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -241,6 +241,8 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig"
 
 source "drivers/gpu/drm/bridge/adv7511/Kconfig"
 
+source "drivers/gpu/drm/bridge/cadence/Kconfig"
+
 source "drivers/gpu/drm/bridge/synopsys/Kconfig"
 
 endmenu
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index c589a6a7cbe1..2b3aff104e46 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -25,4 +25,5 @@ obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
 obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
 
 obj-y += analogix/
+obj-y += cadence/
 obj-y += synopsys/
diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig 
b/drivers/gpu/drm/bridge/cadence/Kconfig
new file mode 100644
index ..f49d77eb7814
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config DRM_CDNS_MHDP8546
+   tristate "Cadence DPI/DP bridge"
+   select DRM_KMS_HELPER
+   select DRM_PANEL_BRIDGE
+   depends on OF
+   help
+ Support Cadence DPI to DP bridge. This is an internal
+ bridge and is meant to be directly embedded in a SoC.
+ It takes a DPI stream as input and outputs it encoded
+ in DP format.
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile 
b/drivers/gpu/drm/bridge/cadence/Makefile
new file mode 100644
index ..676739cdf5e6
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
+cdns-mhdp8546-y := cdns-mhdp8546-core.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
new file mode 100644
index ..7b1bd5d10923
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -0,0 +1,2522 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cadence MHDP8546 DP bridge driver.
+ *
+ * Copyright (C) 2020 Cadence Design Systems, Inc.
+ *
+ * Authors: Quentin Schulz 
+ *  Swapnil Jakhade 
+ *  Yuti Amonkar 
+ *  Tomi Valkeinen 
+ *  Jyri Sarha 
+ *
+ * TODO:
+ * - Implement optimized mailbox communication using mailbox interrupts
+ * - Add support for power management
+ * - Add support for features like audio, MST and fast link training
+ * - Implement request_fw_cancel to handle HW_STATE
+ * - Fix asynchronous loading of firmware implementation
+ * - Add DRM helper function for cdns_mhdp_lower_link_rate
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "cdns-mhdp8546-core.h"
+
+static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
+{
+   int ret, empty;
+
+   WARN_ON(!mutex_is_locked(>mbox_mutex));
+
+   ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY,
+empty, !empty, MAILBOX_RETRY_US,
+MAILBOX_TIMEOUT_US);
+   if (ret < 0)
+   return ret;
+
+   return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
+}
+
+static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val)
+{
+   in

[PATCH v11 3/3] drm: bridge: cdns-mhdp8546: Add TI J721E wrapper

2020-09-18 Thread Swapnil Jakhade
Add J721E wrapper for mhdp, which sets up the clock and data muxes.

Signed-off-by: Jyri Sarha 
Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Reviewed-by: Tomi Valkeinen 
Reviewed-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/cadence/Kconfig| 13 
 drivers/gpu/drm/bridge/cadence/Makefile   |  1 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 10 +++
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  1 +
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.c  | 78 +++
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.h  | 19 +
 6 files changed, 122 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.h

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig 
b/drivers/gpu/drm/bridge/cadence/Kconfig
index f49d77eb7814..511d67b16d14 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -9,3 +9,16 @@ config DRM_CDNS_MHDP8546
  bridge and is meant to be directly embedded in a SoC.
  It takes a DPI stream as input and outputs it encoded
  in DP format.
+
+if DRM_CDNS_MHDP8546
+
+config DRM_CDNS_MHDP8546_J721E
+   depends on ARCH_K3_J721E_SOC || COMPILE_TEST
+   bool "J721E Cadence DPI/DP wrapper support"
+   default y
+   help
+ Support J721E Cadence DPI/DP wrapper. This is a wrapper
+ which adds support for J721E related platform ops. It
+ initializes the J721E Display Port and sets up the
+ clock and data muxes.
+endif
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile 
b/drivers/gpu/drm/bridge/cadence/Makefile
index 676739cdf5e6..8f647991b374 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o
+cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 7b1bd5d10923..621ebdbff8a3 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -50,6 +50,8 @@
 
 #include "cdns-mhdp8546-core.h"
 
+#include "cdns-mhdp8546-j721e.h"
+
 static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
 {
int ret, empty;
@@ -2496,6 +2498,14 @@ static int cdns_mhdp_remove(struct platform_device *pdev)
 
 static const struct of_device_id mhdp_ids[] = {
{ .compatible = "cdns,mhdp8546", },
+#ifdef CONFIG_DRM_CDNS_MHDP8546_J721E
+   { .compatible = "ti,j721e-mhdp8546",
+ .data = &(const struct cdns_mhdp_platform_info) {
+ .timings = _ti_j721e_bridge_timings,
+ .ops = _ti_j721e_ops,
+ },
+   },
+#endif
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mhdp_ids);
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
index c0fff78d15be..5897a85e3159 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -341,6 +341,7 @@ struct cdns_mhdp_platform_info {
 
 struct cdns_mhdp_device {
void __iomem *regs;
+   void __iomem *j721e_regs;
 
struct device *dev;
struct clk *clk;
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
new file mode 100644
index ..dfe1b59514f7
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI j721e Cadence MHDP8546 DP wrapper
+ *
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Jyri Sarha 
+ */
+
+#include 
+#include 
+
+#include "cdns-mhdp8546-j721e.h"
+
+#defineREVISION0x00
+#defineDPTX_IPCFG  0x04
+#defineECC_MEM_CFG 0x08
+#defineDPTX_DSC_CFG0x0c
+#defineDPTX_SRC_CFG0x10
+#defineDPTX_VIF_SECURE_MODE_CFG0x14
+#defineDPTX_VIF_CONN_STATUS0x18
+#definePHY_CLK_STATUS  0x1c
+
+#define DPTX_SRC_AIF_ENBIT(16)
+#define DPTX_SRC_VIF_3_IN30B   BIT(11)
+#define DPTX_SRC_VIF_2_IN30B   BIT(10)
+#define DPTX_SRC_VIF_1_IN30B   BIT(9)
+#define DPTX_SRC_VIF_0_IN30B   BIT(8)
+#define DPTX_SRC_VIF_3_SEL_DPI5BIT(7)
+#define DPTX_SRC_VIF_3_SEL_DPI30
+#define DPTX_SRC_VIF_2_SEL_DPI4BIT(6)
+#define DPTX_SRC_VIF_2_SEL_DPI20
+#define DPTX_SRC_VIF_1

[PATCH v3 04/13] dt-bindings: phy: Add PHY_TYPE_QSGMII definition

2020-09-17 Thread Swapnil Jakhade
Add definition for QSGMII phy type.

Signed-off-by: Swapnil Jakhade 
Acked-by: Rob Herring 
---
 include/dt-bindings/phy/phy.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
index 36e8c241cf48..887a31b250a8 100644
--- a/include/dt-bindings/phy/phy.h
+++ b/include/dt-bindings/phy/phy.h
@@ -19,5 +19,6 @@
 #define PHY_TYPE_DP6
 #define PHY_TYPE_XPCS  7
 #define PHY_TYPE_SGMII 8
+#define PHY_TYPE_QSGMII9
 
 #endif /* _DT_BINDINGS_PHY */
-- 
2.26.1



[PATCH v3 03/13] phy: cadence-torrent: Add PHY APB reset support

2020-09-17 Thread Swapnil Jakhade
Add support for PHY APB reset and make it optional.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 9e900f389b08..1d0c9bb7cfa0 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -228,6 +228,7 @@ struct cdns_torrent_phy {
void __iomem *sd_base; /* SD0801 registers base */
u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */
struct reset_control *phy_rst;
+   struct reset_control *apb_rst;
struct device *dev;
struct clk *clk;
unsigned long ref_clk_rate;
@@ -1883,6 +1884,13 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
return PTR_ERR(cdns_phy->phy_rst);
}
 
+   cdns_phy->apb_rst = devm_reset_control_get_optional(dev, "torrent_apb");
+   if (IS_ERR(cdns_phy->apb_rst)) {
+   dev_err(dev, "%s: failed to get apb reset\n",
+   dev->of_node->full_name);
+   return PTR_ERR(cdns_phy->apb_rst);
+   }
+
cdns_phy->clk = devm_clk_get(dev, "refclk");
if (IS_ERR(cdns_phy->clk)) {
dev_err(dev, "phy ref clock not found\n");
@@ -1907,6 +1915,9 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
if (ret)
return ret;
 
+   /* Enable APB */
+   reset_control_deassert(cdns_phy->apb_rst);
+
for_each_available_child_of_node(dev->of_node, child) {
struct phy *gphy;
 
@@ -2059,6 +2070,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
for (i = 0; i < node; i++)
reset_control_put(cdns_phy->phys[i].lnk_rst);
of_node_put(child);
+   reset_control_assert(cdns_phy->apb_rst);
return ret;
 }
 
@@ -2068,6 +2080,7 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
int i;
 
reset_control_assert(cdns_phy->phy_rst);
+   reset_control_assert(cdns_phy->apb_rst);
for (i = 0; i < cdns_phy->nsubnodes; i++) {
reset_control_assert(cdns_phy->phys[i].lnk_rst);
reset_control_put(cdns_phy->phys[i].lnk_rst);
-- 
2.26.1



[PATCH v3 13/13] phy: cadence-torrent: Add USB + SGMII/QSGMII multilink configuration

2020-09-17 Thread Swapnil Jakhade
Add USB + SGMII/QSGMII multilink configuration sequences.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 254 ++
 1 file changed, 254 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index e82ab72bd3d8..f310e15d94cb 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -2343,6 +2343,40 @@ static int cdns_torrent_phy_remove(struct 
platform_device *pdev)
return 0;
 }
 
+/* USB and SGMII/QSGMII link configuration */
+static struct cdns_reg_pairs usb_sgmii_link_cmn_regs[] = {
+   {0x0002, PHY_PLL_CFG},
+   {0x8600, CMN_PDIAG_PLL0_CLK_SEL_M0},
+   {0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs usb_sgmii_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x0041, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs sgmii_usb_xcvr_diag_ln_regs[] = {
+   {0x0011, XCVR_DIAG_HSCLK_SEL},
+   {0x0003, XCVR_DIAG_HSCLK_DIV},
+   {0x009B, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals usb_sgmii_link_cmn_vals = {
+   .reg_pairs = usb_sgmii_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(usb_sgmii_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals usb_sgmii_xcvr_diag_ln_vals = {
+   .reg_pairs = usb_sgmii_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(usb_sgmii_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals sgmii_usb_xcvr_diag_ln_vals = {
+   .reg_pairs = sgmii_usb_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(sgmii_usb_xcvr_diag_ln_regs),
+};
+
 /* PCIe and USB Unique SSC link configuration */
 static struct cdns_reg_pairs pcie_usb_link_cmn_regs[] = {
{0x0003, PHY_PLL_CFG},
@@ -3016,6 +3050,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
[INTERNAL_SSC] = _sgmii_link_cmn_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
@@ -3026,6 +3065,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
[INTERNAL_SSC] = _sgmii_link_cmn_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
[TYPE_USB] = {
[TYPE_NONE] = {
@@ -3038,6 +3082,16 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _usb_link_cmn_vals,
[INTERNAL_SSC] = _usb_link_cmn_vals,
},
+   [TYPE_SGMII] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
+   [TYPE_QSGMII] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
},
.xcvr_diag_vals = {
@@ -3072,6 +3126,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
[INTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _usb_xcvr_diag_ln_vals,
+   [EXTERNAL_SSC] = _usb_xcvr_diag_ln_vals,
+   [INTERNAL_SSC] = _usb_xcvr_diag_ln_vals,
+   },
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
@@ -3082,6 +3141,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
[INTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _usb_xcvr_diag_ln_vals,
+   [EXTERNAL_SSC] = _usb_xcvr_diag_ln_vals

[PATCH v3 09/13] phy: cadence-torrent: Configure PHY_PLL_CFG as part of link_cmn_vals

2020-09-17 Thread Swapnil Jakhade
Include PHY_PLL_CFG as a first register value to configure in
link_cmn_vals array values.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 0367c0fe15e2..0c4abe959f19 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1830,7 +1830,14 @@ static int cdns_torrent_phy_init(struct phy *phy)
reg_pairs = link_cmn_vals->reg_pairs;
num_regs = link_cmn_vals->num_regs;
regmap = cdns_phy->regmap_common_cdb;
-   for (i = 0; i < num_regs; i++)
+
+   /**
+* First array value in link_cmn_vals must be of
+* PHY_PLL_CFG register
+*/
+   regmap_field_write(cdns_phy->phy_pll_cfg, reg_pairs[0].val);
+
+   for (i = 1; i < num_regs; i++)
regmap_write(regmap, reg_pairs[i].off,
 reg_pairs[i].val);
}
@@ -1907,8 +1914,6 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
phy_t1 = cdns_phy->phys[0].phy_type;
phy_t2 = cdns_phy->phys[1].phy_type;
 
-   regmap_field_write(cdns_phy->phy_pll_cfg, 0x0003);
-
/**
 * First configure the PHY for first link with phy_t1. Get the array
 * values as [phy_t1][phy_t2][ssc].
@@ -1944,7 +1949,15 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
reg_pairs = link_cmn_vals->reg_pairs;
num_regs = link_cmn_vals->num_regs;
regmap = cdns_phy->regmap_common_cdb;
-   for (i = 0; i < num_regs; i++)
+
+   /**
+* First array value in link_cmn_vals must be of
+* PHY_PLL_CFG register
+*/
+   regmap_field_write(cdns_phy->phy_pll_cfg,
+  reg_pairs[0].val);
+
+   for (i = 1; i < num_regs; i++)
regmap_write(regmap, reg_pairs[i].off,
 reg_pairs[i].val);
}
@@ -2280,6 +2293,7 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
 
 /* PCIe and SGMII/QSGMII Unique SSC link configuration */
 static struct cdns_reg_pairs pcie_sgmii_link_cmn_regs[] = {
+   {0x0003, PHY_PLL_CFG},
{0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0},
{0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1},
{0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0}
-- 
2.26.1



[PATCH v3 10/13] phy: cadence-torrent: Add single link SGMII/QSGMII register sequences

2020-09-17 Thread Swapnil Jakhade
Add support for single link SGMII/QSGMII configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 89 +++
 1 file changed, 89 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 0c4abe959f19..844ec0ee8c66 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1824,6 +1824,13 @@ static int cdns_torrent_phy_init(struct phy *phy)
if (phy_type == TYPE_DP)
return cdns_torrent_dp_init(phy);
 
+   /**
+* Spread spectrum generation is not required or supported
+* for SGMII/QSGMII
+*/
+   if (phy_type == TYPE_SGMII || phy_type == TYPE_QSGMII)
+   ssc = NO_SSC;
+
/* PHY configuration specific registers for single link */
link_cmn_vals = init_data->link_cmn_vals[phy_type][TYPE_NONE][ssc];
if (link_cmn_vals) {
@@ -2540,6 +2547,28 @@ static struct cdns_torrent_vals 
qsgmii_100_int_ssc_cmn_vals = {
.num_regs = ARRAY_SIZE(qsgmii_100_int_ssc_cmn_regs),
 };
 
+/* Single SGMII/QSGMII link configuration */
+static struct cdns_reg_pairs sl_sgmii_link_cmn_regs[] = {
+   {0x, PHY_PLL_CFG},
+   {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs sl_sgmii_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0003, XCVR_DIAG_HSCLK_DIV},
+   {0x0013, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals sl_sgmii_link_cmn_vals = {
+   .reg_pairs = sl_sgmii_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(sl_sgmii_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals sl_sgmii_xcvr_diag_ln_vals = {
+   .reg_pairs = sl_sgmii_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(sl_sgmii_xcvr_diag_ln_regs),
+};
+
 /* Multi link PCIe, 100 MHz Ref clk, internal SSC */
 static struct cdns_reg_pairs pcie_100_int_ssc_cmn_regs[] = {
{0x0004, CMN_PLL0_DSM_DIAG_M0},
@@ -2698,6 +2727,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2705,6 +2737,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2731,6 +2766,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_xcvr_diag_ln_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _pcie_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
@@ -2738,6 +2776,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_xcvr_diag_ln_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _pcie_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
@@ -2764,6 +2805,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _100_no_ssc_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _100_no_ssc_cmn_vals,
[EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
@@ -2771,6 +2815,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _100_no_ssc_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _100_no_ssc_cmn_vals,
[EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
@@ -2797,6 +2844,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SG

[PATCH v3 08/13] phy: cadence-torrent: Add PHY link configuration sequences for single link

2020-09-17 Thread Swapnil Jakhade
Add support to configure link_cmn_vals and xcvr_diag_vals in case of single
link PHY configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 44 +++
 1 file changed, 44 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 6641f2f3a367..0367c0fe15e2 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1809,6 +1809,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
const struct cdns_torrent_data *init_data = cdns_phy->init_data;
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
+   struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
enum cdns_torrent_ssc_mode ssc = inst->ssc_mode;
@@ -1823,6 +1824,29 @@ static int cdns_torrent_phy_init(struct phy *phy)
if (phy_type == TYPE_DP)
return cdns_torrent_dp_init(phy);
 
+   /* PHY configuration specific registers for single link */
+   link_cmn_vals = init_data->link_cmn_vals[phy_type][TYPE_NONE][ssc];
+   if (link_cmn_vals) {
+   reg_pairs = link_cmn_vals->reg_pairs;
+   num_regs = link_cmn_vals->num_regs;
+   regmap = cdns_phy->regmap_common_cdb;
+   for (i = 0; i < num_regs; i++)
+   regmap_write(regmap, reg_pairs[i].off,
+reg_pairs[i].val);
+   }
+
+   xcvr_diag_vals = init_data->xcvr_diag_vals[phy_type][TYPE_NONE][ssc];
+   if (xcvr_diag_vals) {
+   reg_pairs = xcvr_diag_vals->reg_pairs;
+   num_regs = xcvr_diag_vals->num_regs;
+   for (i = 0; i < inst->num_lanes; i++) {
+   regmap = cdns_phy->regmap_tx_lane_cdb[i + inst->mlane];
+   for (j = 0; j < num_regs; j++)
+   regmap_write(regmap, reg_pairs[j].off,
+reg_pairs[j].val);
+   }
+   }
+
/* PMA common registers configurations */
cmn_vals = init_data->cmn_vals[phy_type][TYPE_NONE][ssc];
if (cmn_vals) {
@@ -2643,6 +2667,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
.reg_offset_shift = 0x2,
.link_cmn_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2671,6 +2700,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
},
.xcvr_diag_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _sgmii_xcvr_diag_ln_vals,
@@ -2803,6 +2837,11 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
.reg_offset_shift = 0x1,
.link_cmn_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2831,6 +2870,11 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
},
.xcvr_diag_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _sgmii_xcvr_diag_ln_vals,
-- 
2.26.1



[PATCH v3 02/13] phy: cadence-torrent: Check cmn_ready assertion during PHY power on

2020-09-17 Thread Swapnil Jakhade
Check if cmn_ready is set after both PLL0 and PLL1 are locked.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 31 ++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 052cff34208d..9e900f389b08 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -32,6 +32,7 @@
 #define NUM_PHY_TYPE   2
 
 #define POLL_TIMEOUT_US5000
+#define PLL_LOCK_TIMEOUT   10
 
 #define TORRENT_COMMON_CDB_OFFSET  0x0
 
@@ -183,12 +184,16 @@
 #define PHY_PLL_CFG0x000EU
 
 /* PHY PMA common registers */
+#define PHY_PMA_CMN_CTRL1  0xU
 #define PHY_PMA_CMN_CTRL2  0x0001U
 #define PHY_PMA_PLL_RAW_CTRL   0x0003U
 
 static const struct reg_field phy_pll_cfg =
REG_FIELD(PHY_PLL_CFG, 0, 1);
 
+static const struct reg_field phy_pma_cmn_ctrl_1 =
+   REG_FIELD(PHY_PMA_CMN_CTRL1, 0, 0);
+
 static const struct reg_field phy_pma_cmn_ctrl_2 =
REG_FIELD(PHY_PMA_CMN_CTRL2, 0, 7);
 
@@ -237,6 +242,7 @@ struct cdns_torrent_phy {
struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES];
struct regmap *regmap_dptx_phy_reg;
struct regmap_field *phy_pll_cfg;
+   struct regmap_field *phy_pma_cmn_ctrl_1;
struct regmap_field *phy_pma_cmn_ctrl_2;
struct regmap_field *phy_pma_pll_raw_ctrl;
struct regmap_field *phy_reset_ctrl;
@@ -1570,6 +1576,7 @@ static int cdns_torrent_phy_on(struct phy *phy)
 {
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+   u32 read_val;
int ret;
 
/* Take the PHY out of reset */
@@ -1578,7 +1585,21 @@ static int cdns_torrent_phy_on(struct phy *phy)
return ret;
 
/* Take the PHY lane group out of reset */
-   return reset_control_deassert(inst->lnk_rst);
+   reset_control_deassert(inst->lnk_rst);
+
+   /*
+* Wait for cmn_ready assertion
+* PHY_PMA_CMN_CTRL1[0] == 1
+*/
+   ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_1,
+read_val, read_val, 1000,
+PLL_LOCK_TIMEOUT);
+   if (ret) {
+   dev_err(cdns_phy->dev, "Timeout waiting for CMN ready\n");
+   return ret;
+   }
+
+   return 0;
 }
 
 static int cdns_torrent_phy_off(struct phy *phy)
@@ -1643,6 +1664,14 @@ static int cdns_torrent_regfield_init(struct 
cdns_torrent_phy *cdns_phy)
}
cdns_phy->phy_pll_cfg = field;
 
+   regmap = cdns_phy->regmap_phy_pma_common_cdb;
+   field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_1);
+   if (IS_ERR(field)) {
+   dev_err(dev, "PHY_PMA_CMN_CTRL1 reg field init failed\n");
+   return PTR_ERR(field);
+   }
+   cdns_phy->phy_pma_cmn_ctrl_1 = field;
+
regmap = cdns_phy->regmap_phy_pma_common_cdb;
field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_2);
if (IS_ERR(field)) {
-- 
2.26.1



[PATCH v3 06/13] phy: cadence-torrent: Update PHY reset for multilink configuration

2020-09-17 Thread Swapnil Jakhade
For multilink configuration, deassert PHY and link reset after PHY
registers are configured in probe and only check link status in
power_on callback.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 28 +--
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index cd02aa47dbc9..bdd96c76751e 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1603,13 +1603,15 @@ static int cdns_torrent_phy_on(struct phy *phy)
u32 read_val;
int ret;
 
-   /* Take the PHY out of reset */
-   ret = reset_control_deassert(cdns_phy->phy_rst);
-   if (ret)
-   return ret;
+   if (cdns_phy->nsubnodes == 1) {
+   /* Take the PHY lane group out of reset */
+   reset_control_deassert(inst->lnk_rst);
 
-   /* Take the PHY lane group out of reset */
-   reset_control_deassert(inst->lnk_rst);
+   /* Take the PHY out of reset */
+   ret = reset_control_deassert(cdns_phy->phy_rst);
+   if (ret)
+   return ret;
+   }
 
/*
 * Wait for cmn_ready assertion
@@ -1623,6 +1625,8 @@ static int cdns_torrent_phy_on(struct phy *phy)
return ret;
}
 
+   mdelay(10);
+
return 0;
 }
 
@@ -1632,6 +1636,9 @@ static int cdns_torrent_phy_off(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
int ret;
 
+   if (cdns_phy->nsubnodes != 1)
+   return 0;
+
ret = reset_control_assert(cdns_phy->phy_rst);
if (ret)
return ret;
@@ -1886,7 +1893,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type;
-   int i, j, node, mlane, num_lanes;
+   int i, j, node, mlane, num_lanes, ret;
struct cdns_reg_pairs *reg_pairs;
enum cdns_torrent_ssc_mode ssc;
struct regmap *regmap;
@@ -1989,8 +1996,15 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
 reg_pairs[j].val);
}
}
+
+   reset_control_deassert(cdns_phy->phys[node].lnk_rst);
}
 
+   /* Take the PHY out of reset */
+   ret = reset_control_deassert(cdns_phy->phy_rst);
+   if (ret)
+   return ret;
+
return 0;
 }
 
-- 
2.26.1



[PATCH v3 12/13] phy: cadence-torrent: Add PCIe + USB multilink configuration

2020-09-17 Thread Swapnil Jakhade
Add PCIe + USB Unique SSC multilink configuration sequences.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 216 ++
 1 file changed, 216 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 3758c4b183af..e82ab72bd3d8 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1938,6 +1938,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type;
+   struct cdns_torrent_vals *pcs_cmn_vals;
int i, j, node, mlane, num_lanes, ret;
struct cdns_reg_pairs *reg_pairs;
enum cdns_torrent_ssc_mode ssc;
@@ -2011,6 +2012,17 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
}
}
 
+   /* 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 = cdns_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 */
cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc];
if (cmn_vals) {
@@ -2331,6 +2343,100 @@ static int cdns_torrent_phy_remove(struct 
platform_device *pdev)
return 0;
 }
 
+/* PCIe and USB Unique SSC link configuration */
+static struct cdns_reg_pairs pcie_usb_link_cmn_regs[] = {
+   {0x0003, PHY_PLL_CFG},
+   {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0},
+   {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1},
+   {0x8600, CMN_PDIAG_PLL1_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs pcie_usb_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x0012, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs usb_pcie_xcvr_diag_ln_regs[] = {
+   {0x0011, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x00C9, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals pcie_usb_link_cmn_vals = {
+   .reg_pairs = pcie_usb_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(pcie_usb_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals pcie_usb_xcvr_diag_ln_vals = {
+   .reg_pairs = pcie_usb_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(pcie_usb_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals usb_pcie_xcvr_diag_ln_vals = {
+   .reg_pairs = usb_pcie_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(usb_pcie_xcvr_diag_ln_regs),
+};
+
+/* USB 100 MHz Ref clk, internal SSC */
+static struct cdns_reg_pairs usb_100_int_ssc_cmn_regs[] = {
+   {0x0004, CMN_PLL0_DSM_DIAG_M0},
+   {0x0004, CMN_PLL0_DSM_DIAG_M1},
+   {0x0004, CMN_PLL1_DSM_DIAG_M0},
+   {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0},
+   {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M1},
+   {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0},
+   {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0},
+   {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M1},
+   {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0},
+   {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0},
+   {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M1},
+   {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0},
+   {0x0064, CMN_PLL0_INTDIV_M0},
+   {0x0050, CMN_PLL0_INTDIV_M1},
+   {0x0064, CMN_PLL1_INTDIV_M0},
+   {0x0002, CMN_PLL0_FRACDIVH_M0},
+   {0x0002, CMN_PLL0_FRACDIVH_M1},
+   {0x0002, CMN_PLL1_FRACDIVH_M0},
+   {0x0044, CMN_PLL0_HIGH_THR_M0},
+   {0x0036, CMN_PLL0_HIGH_THR_M1},
+   {0x0044, CMN_PLL1_HIGH_THR_M0},
+   {0x0002, CMN_PDIAG_PLL0_CTRL_M0},
+   {0x0002, CMN_PDIAG_PLL0_CTRL_M1},
+   {0x0002, CMN_PDIAG_PLL1_CTRL_M0},
+   {0x0001, CMN_PLL0_SS_CTRL1_M0},
+   {0x0001, CMN_PLL0_SS_CTRL1_M1},
+   {0x0001, CMN_PLL1_SS_CTRL1_M0},
+   {0x011B, CMN_PLL0_SS_CTRL2_M0},
+   {0x011B, CMN_PLL0_SS_CTRL2_M1},
+   {0x011B, CMN_PLL1_SS_CTRL2_M0},
+   {0x006E, CMN_PLL0_SS_CTRL3_M0},
+   {0x0058, CMN_PLL0_SS_CTRL3_M1},
+   {0x006E, CMN_PLL1_SS_CTRL3_M0},
+   {0x000E, CMN_PLL0_SS_CTRL4_M0},
+   {0x0012, CMN_PLL0_SS_CTRL4_M1},
+   {0x000E, CMN_PLL1_SS_CTRL4_M0},
+   {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START},
+   {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
+   {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
+   {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
+   {0x0003, CMN_PLL0_VCOCAL_TCTRL},
+   {0x0003, CMN_PLL1_VCOCAL_TCTRL

[PATCH v3 07/13] phy: cadence-torrent: Add clk changes for multilink configuration

2020-09-17 Thread Swapnil Jakhade
Prepare and enable clock in probe instead of phy_init.
Also, remove phy_exit callback.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 41 ++-
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index bdd96c76751e..6641f2f3a367 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -273,7 +273,6 @@ enum phy_powerstate {
 };
 
 static int cdns_torrent_phy_init(struct phy *phy);
-static int cdns_torrent_phy_exit(struct phy *phy);
 static int cdns_torrent_dp_init(struct phy *phy);
 static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
   u32 num_lanes);
@@ -305,7 +304,6 @@ static int cdns_torrent_phy_off(struct phy *phy);
 
 static const struct phy_ops cdns_torrent_phy_ops = {
.init   = cdns_torrent_phy_init,
-   .exit   = cdns_torrent_phy_exit,
.configure  = cdns_torrent_dp_configure,
.power_on   = cdns_torrent_phy_on,
.power_off  = cdns_torrent_phy_off,
@@ -977,14 +975,6 @@ static int cdns_torrent_dp_init(struct phy *phy)
return ret;
 }
 
-static int cdns_torrent_phy_exit(struct phy *phy)
-{
-   struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
-
-   clk_disable_unprepare(cdns_phy->clk);
-   return 0;
-}
-
 static
 int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
 {
@@ -1825,20 +1815,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_reg_pairs *reg_pairs;
struct regmap *regmap;
u32 num_regs;
-   int ret, i, j;
-
-   ret = clk_prepare_enable(cdns_phy->clk);
-   if (ret) {
-   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
-   return ret;
-   }
-
-   cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
-   if (!(cdns_phy->ref_clk_rate)) {
-   dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
-   clk_disable_unprepare(cdns_phy->clk);
-   return -EINVAL;
-   }
+   int i, j;
 
if (cdns_phy->nsubnodes > 1)
return 0;
@@ -2071,6 +2048,19 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
if (ret)
return ret;
 
+   ret = clk_prepare_enable(cdns_phy->clk);
+   if (ret) {
+   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+   return ret;
+   }
+
+   cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
+   if (!(cdns_phy->ref_clk_rate)) {
+   dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+   clk_disable_unprepare(cdns_phy->clk);
+   return -EINVAL;
+   }
+
/* Enable APB */
reset_control_deassert(cdns_phy->apb_rst);
 
@@ -2243,6 +2233,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
reset_control_put(cdns_phy->phys[i].lnk_rst);
of_node_put(child);
reset_control_assert(cdns_phy->apb_rst);
+   clk_disable_unprepare(cdns_phy->clk);
return ret;
 }
 
@@ -2258,6 +2249,8 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
reset_control_put(cdns_phy->phys[i].lnk_rst);
}
 
+   clk_disable_unprepare(cdns_phy->clk);
+
return 0;
 }
 
-- 
2.26.1



[PATCH v3 01/13] phy: cadence-torrent: Add single link PCIe support

2020-09-17 Thread Swapnil Jakhade
Add single link PCIe register sequences in Torrent PHY driver.
Also, add support for getting SSC type from DT.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 296 +++---
 1 file changed, 266 insertions(+), 30 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 6c199400fa5b..052cff34208d 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -28,6 +28,9 @@
 #define MAX_NUM_LANES  4
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
+#define NUM_SSC_MODE   3
+#define NUM_PHY_TYPE   2
+
 #define POLL_TIMEOUT_US5000
 
 #define TORRENT_COMMON_CDB_OFFSET  0x0
@@ -98,6 +101,14 @@
 #define CMN_PLL0_LOCK_REFCNT_START  0x009CU
 #define CMN_PLL0_LOCK_PLLCNT_START 0x009EU
 #define CMN_PLL0_LOCK_PLLCNT_THR0x009FU
+#define CMN_PLL0_INTDIV_M1 0x00A0U
+#define CMN_PLL0_FRACDIVH_M1   0x00A2U
+#define CMN_PLL0_HIGH_THR_M1   0x00A3U
+#define CMN_PLL0_DSM_DIAG_M1   0x00A4U
+#define CMN_PLL0_SS_CTRL1_M1   0x00A8U
+#define CMN_PLL0_SS_CTRL2_M1   0x00A9U
+#define CMN_PLL0_SS_CTRL3_M1   0x00AAU
+#define CMN_PLL0_SS_CTRL4_M1   0x00ABU
 #define CMN_PLL1_VCOCAL_TCTRL  0x00C2U
 #define CMN_PLL1_VCOCAL_INIT_TMR   0x00C4U
 #define CMN_PLL1_VCOCAL_ITER_TMR   0x00C5U
@@ -130,8 +141,10 @@
 #define CMN_PDIAG_PLL0_CP_PADJ_M0  0x01A4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M0  0x01A5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M00x01A6U
+#define CMN_PDIAG_PLL0_CTRL_M1 0x01B0U
 #define CMN_PDIAG_PLL0_CP_PADJ_M1  0x01B4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M1  0x01B5U
+#define CMN_PDIAG_PLL0_FILT_PADJ_M10x01B6U
 #define CMN_PDIAG_PLL1_CTRL_M0 0x01C0U
 #define CMN_PDIAG_PLL1_CLK_SEL_M0  0x01C1U
 #define CMN_PDIAG_PLL1_CP_PADJ_M0  0x01C4U
@@ -162,6 +175,9 @@
 #define RX_REE_GCSM1_CTRL  0x0108U
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
+#define RX_REE_TAP1_CLIP   0x0171U
+#define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
 #define PHY_PLL_CFG0x000EU
@@ -182,12 +198,24 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
 static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
+enum cdns_torrent_phy_type {
+   TYPE_DP,
+   TYPE_PCIE
+};
+
+enum cdns_torrent_ssc_mode {
+   NO_SSC,
+   EXTERNAL_SSC,
+   INTERNAL_SSC
+};
+
 struct cdns_torrent_inst {
struct phy *phy;
u32 mlane;
-   u32 phy_type;
+   enum cdns_torrent_phy_type phy_type;
u32 num_lanes;
struct reset_control *lnk_rst;
+   enum cdns_torrent_ssc_mode ssc_mode;
 };
 
 struct cdns_torrent_phy {
@@ -221,8 +249,9 @@ enum phy_powerstate {
POWERSTATE_A3 = 3,
 };
 
+static int cdns_torrent_phy_init(struct phy *phy);
+static int cdns_torrent_phy_exit(struct phy *phy);
 static int cdns_torrent_dp_init(struct phy *phy);
-static int cdns_torrent_dp_exit(struct phy *phy);
 static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
   u32 num_lanes);
 static
@@ -252,17 +281,30 @@ static int cdns_torrent_phy_on(struct phy *phy);
 static int cdns_torrent_phy_off(struct phy *phy);
 
 static const struct phy_ops cdns_torrent_phy_ops = {
-   .init   = cdns_torrent_dp_init,
-   .exit   = cdns_torrent_dp_exit,
+   .init   = cdns_torrent_phy_init,
+   .exit   = cdns_torrent_phy_exit,
.configure  = cdns_torrent_dp_configure,
.power_on   = cdns_torrent_phy_on,
.power_off  = cdns_torrent_phy_off,
.owner  = THIS_MODULE,
 };
 
+struct cdns_reg_pairs {
+   u32 val;
+   u32 off;
+};
+
+struct cdns_torrent_vals {
+   struct cdns_reg_pairs *reg_pairs;
+   u32 num_regs;
+};
+
 struct cdns_torrent_data {
-   u8 block_offset_shift;
-   u8 reg_offset_shift;
+   u8 block_offset_shift;
+   u8 reg_offset_shift;
+   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
 };
 
 struct cdns_regmap_cdb_context {
@@ -846,19 +888,6 @@ static int cdns_torrent_dp_init(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
 
-   ret = clk_prepare_enable(cdns_phy->clk);
-   if (ret) {
-   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
-   return ret;
-   }
-
-   cdns_phy->ref_clk_rate = c

[PATCH v3 00/13] PHY: Add support for multilink configurations in Cadence Torrent PHY driver

2020-09-17 Thread Swapnil Jakhade
Cadence Torrent PHY is a multiprotocol PHY supporting different multilink
PHY configurations including DisplayPort, PCIe, USB, SGMII, QSGMII etc.
This patch series extends functionality of Torrent PHY driver to support
following configurations:
- Single link PCIe configuration
- PCIe + SGMII/QSGMII Unique SSC multilink configuration
- Single link SGMII/QSGMII configuration
- Single link USB configuration
- PCIe + USB Unique SSC multilink configuration
- USB + SGMII/QSGMII multilink configuration

The changes have been validated on TI J7200 platform.

This patch series is dependent on [1] and should be applied on
top of this.

[1] https://lkml.org/lkml/2020/9/16/668

Version History:

v3:
   - Rebased on latest PHY next and new PHY patch series [1]

v2:
   - Rebased on latest PHY next and new PHY patch series [1] and [2]

Swapnil Jakhade (13):
  phy: cadence-torrent: Add single link PCIe support
  phy: cadence-torrent: Check cmn_ready assertion during PHY power on
  phy: cadence-torrent: Add PHY APB reset support
  dt-bindings: phy: Add PHY_TYPE_QSGMII definition
  phy: cadence-torrent: Add support for PHY multilink configuration
  phy: cadence-torrent: Update PHY reset for multilink configuration
  phy: cadence-torrent: Add clk changes for multilink configuration
  phy: cadence-torrent: Add PHY link configuration sequences for single
link
  phy: cadence-torrent: Configure PHY_PLL_CFG as part of link_cmn_vals
  phy: cadence-torrent: Add single link SGMII/QSGMII register sequences
  phy: cadence-torrent: Add single link USB register sequences
  phy: cadence-torrent: Add PCIe + USB multilink configuration
  phy: cadence-torrent: Add USB + SGMII/QSGMII multilink configuration

 drivers/phy/cadence/phy-cadence-torrent.c | 1975 -
 include/dt-bindings/phy/phy.h |1 +
 2 files changed, 1934 insertions(+), 42 deletions(-)

-- 
2.26.1



[PATCH v3 11/13] phy: cadence-torrent: Add single link USB register sequences

2020-09-17 Thread Swapnil Jakhade
Add support for single link USB configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 260 +-
 1 file changed, 259 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 844ec0ee8c66..3758c4b183af 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -29,7 +29,7 @@
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
 #define NUM_SSC_MODE   3
-#define NUM_PHY_TYPE   5
+#define NUM_PHY_TYPE   6
 
 #define POLL_TIMEOUT_US5000
 #define PLL_LOCK_TIMEOUT   10
@@ -82,6 +82,8 @@
 #define CMN_PLLSM0_PLLLOCK_TMR 0x002CU
 #define CMN_PLLSM1_PLLPRE_TMR  0x0032U
 #define CMN_PLLSM1_PLLLOCK_TMR 0x0034U
+#define CMN_CDIAG_CDB_PWRI_OVRD0x0041U
+#define CMN_CDIAG_XCVRC_PWRI_OVRD  0x0047U
 #define CMN_BGCAL_INIT_TMR 0x0064U
 #define CMN_BGCAL_ITER_TMR 0x0065U
 #define CMN_IBCAL_INIT_TMR 0x0074U
@@ -159,13 +161,16 @@
 /* PMA TX Lane registers */
 #define TX_TXCC_CTRL   0x0040U
 #define TX_TXCC_CPOST_MULT_00  0x004CU
+#define TX_TXCC_CPOST_MULT_01  0x004DU
 #define TX_TXCC_MGNFS_MULT_000 0x0050U
 #define DRV_DIAG_TX_DRV0x00C6U
 #define XCVR_DIAG_PLLDRC_CTRL  0x00E5U
 #define XCVR_DIAG_HSCLK_SEL0x00E6U
 #define XCVR_DIAG_HSCLK_DIV0x00E7U
 #define XCVR_DIAG_BIDI_CTRL0x00EAU
+#define XCVR_DIAG_PSC_OVRD 0x00EBU
 #define TX_PSC_A0  0x0100U
+#define TX_PSC_A1  0x0101U
 #define TX_PSC_A2  0x0102U
 #define TX_PSC_A3  0x0103U
 #define TX_RCVDET_ST_TMR   0x0123U
@@ -174,27 +179,37 @@
 
 /* PMA RX Lane registers */
 #define RX_PSC_A0  0xU
+#define RX_PSC_A1  0x0001U
 #define RX_PSC_A2  0x0002U
 #define RX_PSC_A3  0x0003U
 #define RX_PSC_CAL 0x0006U
 #define RX_CDRLF_CNFG  0x0080U
+#define RX_CDRLF_CNFG3 0x0082U
+#define RX_SIGDET_HL_FILT_TMR  0x0090U
 #define RX_REE_GCSM1_CTRL  0x0108U
 #define RX_REE_GCSM1_EQENM_PH1 0x0109U
 #define RX_REE_GCSM1_EQENM_PH2 0x010AU
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
+#define RX_REE_ATTEN_THR   0x0149U
 #define RX_REE_TAP1_CLIP   0x0171U
 #define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_REE_SMGM_CTRL1  0x0177U
+#define RX_REE_SMGM_CTRL2  0x0178U
 #define RX_DIAG_DFE_CTRL   0x01E0U
 #define RX_DIAG_DFE_AMP_TUNE_2 0x01E2U
 #define RX_DIAG_DFE_AMP_TUNE_3 0x01E3U
 #define RX_DIAG_NQST_CTRL  0x01E5U
+#define RX_DIAG_SIGDET_TUNE0x01E8U
 #define RX_DIAG_PI_RATE0x01F4U
 #define RX_DIAG_PI_CAP 0x01F5U
 #define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
 #define PHY_PLL_CFG0x000EU
+#define PHY_PIPE_USB3_GEN2_PRE_CFG00x0020U
+#define PHY_PIPE_USB3_GEN2_POST_CFG0   0x0022U
+#define PHY_PIPE_USB3_GEN2_POST_CFG1   0x0023U
 
 /* PHY PMA common registers */
 #define PHY_PMA_CMN_CTRL1  0xU
@@ -222,6 +237,7 @@ enum cdns_torrent_phy_type {
TYPE_PCIE,
TYPE_SGMII,
TYPE_QSGMII,
+   TYPE_USB,
 };
 
 enum cdns_torrent_ssc_mode {
@@ -327,6 +343,8 @@ struct cdns_torrent_data {
   [NUM_SSC_MODE];
struct cdns_torrent_vals *xcvr_diag_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
[NUM_SSC_MODE];
+   struct cdns_torrent_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
  [NUM_SSC_MODE];
struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
@@ -1813,6 +1831,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
enum cdns_torrent_ssc_mode ssc = inst->ssc_mode;
+   struct cdns_torrent_vals *pcs_cmn_vals;
struct cdns_reg_pairs *reg_pairs;
struct regmap *regmap;
u32 num_regs;
@@ -1861,6 +1880,17 @@ static int cdns_torrent_phy_init(struct phy *phy)
}
}
 
+   /* 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;
+   

[PATCH v3 05/13] phy: cadence-torrent: Add support for PHY multilink configuration

2020-09-17 Thread Swapnil Jakhade
Added support for multilink configuration of Torrent PHY. Currently,
maximum two links are supported. In case of multilink configuration,
PHY needs to be configured for both the protocols simultaneously at
the beginning as per the requirement of Torrent PHY.
Also, register sequences for PCIe + SGMII/QSGMII Unique SSC PHY multilink
configurations are added.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 783 +-
 1 file changed, 757 insertions(+), 26 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 1d0c9bb7cfa0..cd02aa47dbc9 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -29,7 +29,7 @@
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
 #define NUM_SSC_MODE   3
-#define NUM_PHY_TYPE   2
+#define NUM_PHY_TYPE   5
 
 #define POLL_TIMEOUT_US5000
 #define PLL_LOCK_TIMEOUT   10
@@ -127,8 +127,10 @@
 #define CMN_PLL1_LOCK_REFCNT_START  0x00DCU
 #define CMN_PLL1_LOCK_PLLCNT_START 0x00DEU
 #define CMN_PLL1_LOCK_PLLCNT_THR0x00DFU
+#define CMN_TXPUCAL_TUNE   0x0103U
 #define CMN_TXPUCAL_INIT_TMR   0x0104U
 #define CMN_TXPUCAL_ITER_TMR   0x0105U
+#define CMN_TXPDCAL_TUNE   0x010BU
 #define CMN_TXPDCAL_INIT_TMR   0x010CU
 #define CMN_TXPDCAL_ITER_TMR   0x010DU
 #define CMN_RXCAL_INIT_TMR 0x0114U
@@ -143,6 +145,7 @@
 #define CMN_PDIAG_PLL0_CP_IADJ_M0  0x01A5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M00x01A6U
 #define CMN_PDIAG_PLL0_CTRL_M1 0x01B0U
+#define CMN_PDIAG_PLL0_CLK_SEL_M1  0x01B1U
 #define CMN_PDIAG_PLL0_CP_PADJ_M1  0x01B4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M1  0x01B5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M10x01B6U
@@ -151,6 +154,7 @@
 #define CMN_PDIAG_PLL1_CP_PADJ_M0  0x01C4U
 #define CMN_PDIAG_PLL1_CP_IADJ_M0  0x01C5U
 #define CMN_PDIAG_PLL1_FILT_PADJ_M00x01C6U
+#define CMN_DIAG_BIAS_OVRD10x01E1U
 
 /* PMA TX Lane registers */
 #define TX_TXCC_CTRL   0x0040U
@@ -173,11 +177,20 @@
 #define RX_PSC_A2  0x0002U
 #define RX_PSC_A3  0x0003U
 #define RX_PSC_CAL 0x0006U
+#define RX_CDRLF_CNFG  0x0080U
 #define RX_REE_GCSM1_CTRL  0x0108U
+#define RX_REE_GCSM1_EQENM_PH1 0x0109U
+#define RX_REE_GCSM1_EQENM_PH2 0x010AU
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
 #define RX_REE_TAP1_CLIP   0x0171U
 #define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_DIAG_DFE_CTRL   0x01E0U
+#define RX_DIAG_DFE_AMP_TUNE_2 0x01E2U
+#define RX_DIAG_DFE_AMP_TUNE_3 0x01E3U
+#define RX_DIAG_NQST_CTRL  0x01E5U
+#define RX_DIAG_PI_RATE0x01F4U
+#define RX_DIAG_PI_CAP 0x01F5U
 #define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
@@ -204,8 +217,11 @@ static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
 enum cdns_torrent_phy_type {
+   TYPE_NONE,
TYPE_DP,
-   TYPE_PCIE
+   TYPE_PCIE,
+   TYPE_SGMII,
+   TYPE_QSGMII,
 };
 
 enum cdns_torrent_ssc_mode {
@@ -309,9 +325,16 @@ struct cdns_torrent_vals {
 struct cdns_torrent_data {
u8 block_offset_shift;
u8 reg_offset_shift;
-   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
-   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
-   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *link_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+  [NUM_SSC_MODE];
+   struct cdns_torrent_vals *xcvr_diag_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
+   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
+   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
+   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
 };
 
 struct cdns_regmap_cdb_context {
@@ -1787,6 +1810,7 @@ static int cdns_torrent_regmap_init(struct 
cdns_torrent_phy *cdns_phy)
 static int cdns_torrent_phy_init(struct phy *phy)
 {
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+   const struct cdns_torrent_data *init_data = cdns_phy->init_data;
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
@@ -1809,11

[PATCH v3 3/7] phy: cadence-torrent: Enable support for multiple subnodes

2020-09-16 Thread Swapnil Jakhade
Enable support for multiple subnodes in torrent PHY to
include multi-link combinations.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index bd8656dfc919..966aeec8ec06 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1746,9 +1746,6 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
if (subnodes == 0) {
dev_err(dev, "No available link subnodes found\n");
return -EINVAL;
-   } else if (subnodes != 1) {
-   dev_err(dev, "Driver supports only one link subnode.\n");
-   return -EINVAL;
}
 
for_each_available_child_of_node(dev->of_node, child) {
@@ -1771,14 +1768,6 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
goto put_child;
}
 
-   if (cdns_phy->phys[node].mlane != 0) {
-   dev_err(dev,
-   "%s: Driver supports only lane-0 as master 
lane.\n",
-   child->full_name);
-   ret = -EINVAL;
-   goto put_child;
-   }
-
if (of_property_read_u32(child, "cdns,phy-type",
 _phy->phys[node].phy_type)) {
dev_err(dev, "%s: No \"cdns,phy-type\"-property.\n",
@@ -1849,10 +1838,6 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
gphy->attrs.bus_width = cdns_phy->phys[node].num_lanes;
gphy->attrs.max_link_rate = cdns_phy->max_bit_rate;
gphy->attrs.mode = PHY_MODE_DP;
-   } else {
-   dev_err(dev, "Driver supports only PHY_TYPE_DP\n");
-   ret = -ENOTSUPP;
-   goto put_child;
}
cdns_phy->phys[node].phy = gphy;
phy_set_drvdata(gphy, _phy->phys[node]);
-- 
2.26.1



[PATCH v3 6/7] dt-bindings: phy: cadence-torrent: Add binding to specify SSC mode

2020-09-16 Thread Swapnil Jakhade
Add binding to specify Spread Spectrum Clocking mode used.

Signed-off-by: Swapnil Jakhade 
Reviewed-by: Rob Herring 
---
 .../bindings/phy/phy-cadence-torrent.yaml   |  9 +
 include/dt-bindings/phy/phy-cadence-torrent.h   | 13 +
 2 files changed, 22 insertions(+)
 create mode 100644 include/dt-bindings/phy/phy-cadence-torrent.h

diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml 
b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
index 4071438be2ba..a7ee19d27c19 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
@@ -87,6 +87,15 @@ patternProperties:
 enum: [1, 2, 4]
 default: 4
 
+  cdns,ssc-mode:
+description:
+  Specifies the Spread Spectrum Clocking mode used. It can be NO_SSC,
+  EXTERNAL_SSC or INTERNAL_SSC.
+  Refer include/dt-bindings/phy/phy-cadence-torrent.h for the 
constants to be used.
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [0, 1, 2]
+default: 0
+
   cdns,max-bit-rate:
 description:
   Maximum DisplayPort link bit rate to use, in Mbps
diff --git a/include/dt-bindings/phy/phy-cadence-torrent.h 
b/include/dt-bindings/phy/phy-cadence-torrent.h
new file mode 100644
index ..e387b6a95741
--- /dev/null
+++ b/include/dt-bindings/phy/phy-cadence-torrent.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides constants for Cadence Torrent SERDES.
+ */
+
+#ifndef _DT_BINDINGS_TORRENT_SERDES_H
+#define _DT_BINDINGS_TORRENT_SERDES_H
+
+#define TORRENT_SERDES_NO_SSC  0
+#define TORRENT_SERDES_EXTERNAL_SSC1
+#define TORRENT_SERDES_INTERNAL_SSC2
+
+#endif /* _DT_BINDINGS_TORRENT_SERDES_H */
-- 
2.26.1



[PATCH v3 2/7] phy: cadence-torrent: Use devm_platform_ioremap_resource() to get reg addresses

2020-09-16 Thread Swapnil Jakhade
Use devm_platform_ioremap_resource() to get register addresses instead of
boilerplate code.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 0211083a4d09..bd8656dfc919 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1705,7 +1705,6 @@ static int cdns_regmap_init_torrent_dp(struct 
cdns_torrent_phy *cdns_phy,
 
 static int cdns_torrent_phy_probe(struct platform_device *pdev)
 {
-   struct resource *regs;
struct cdns_torrent_phy *cdns_phy;
struct device *dev = >dev;
struct phy_provider *phy_provider;
@@ -1739,8 +1738,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
return PTR_ERR(cdns_phy->clk);
}
 
-   regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   cdns_phy->sd_base = devm_ioremap_resource(>dev, regs);
+   cdns_phy->sd_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(cdns_phy->sd_base))
return PTR_ERR(cdns_phy->sd_base);
 
@@ -1830,9 +1828,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
}
 
/* DPTX registers */
-   regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-   cdns_phy->base = devm_ioremap_resource(>dev,
-  regs);
+   cdns_phy->base = devm_platform_ioremap_resource(pdev, 
1);
if (IS_ERR(cdns_phy->base)) {
ret = PTR_ERR(cdns_phy->base);
goto put_child;
-- 
2.26.1



[PATCH v3 4/7] phy: cadence-torrent: Add separate regmap functions for torrent and DP

2020-09-16 Thread Swapnil Jakhade
Added separate functions for regmap initialization of torrent PHY
generic registers and DP specific registers.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 99 +++
 1 file changed, 66 insertions(+), 33 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 966aeec8ec06..9dba7ba33fcd 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1584,7 +1584,24 @@ static struct regmap *cdns_regmap_init(struct device 
*dev, void __iomem *base,
return devm_regmap_init(dev, NULL, ctx, config);
 }
 
-static int cdns_regfield_init(struct cdns_torrent_phy *cdns_phy)
+static int cdns_torrent_dp_regfield_init(struct cdns_torrent_phy *cdns_phy)
+{
+   struct device *dev = cdns_phy->dev;
+   struct regmap_field *field;
+   struct regmap *regmap;
+
+   regmap = cdns_phy->regmap_dptx_phy_reg;
+   field = devm_regmap_field_alloc(dev, regmap, phy_reset_ctrl);
+   if (IS_ERR(field)) {
+   dev_err(dev, "PHY_RESET reg field init failed\n");
+   return PTR_ERR(field);
+   }
+   cdns_phy->phy_reset_ctrl = field;
+
+   return 0;
+}
+
+static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy)
 {
struct device *dev = cdns_phy->dev;
struct regmap_field *field;
@@ -1614,28 +1631,44 @@ static int cdns_regfield_init(struct cdns_torrent_phy 
*cdns_phy)
}
cdns_phy->phy_pma_pll_raw_ctrl = field;
 
-   regmap = cdns_phy->regmap_dptx_phy_reg;
-   field = devm_regmap_field_alloc(dev, regmap, phy_reset_ctrl);
-   if (IS_ERR(field)) {
-   dev_err(dev, "PHY_RESET reg field init failed\n");
-   return PTR_ERR(field);
+   return 0;
+}
+
+static int cdns_torrent_dp_regmap_init(struct cdns_torrent_phy *cdns_phy)
+{
+   void __iomem *base = cdns_phy->base;
+   struct device *dev = cdns_phy->dev;
+   struct regmap *regmap;
+   u8 reg_offset_shift;
+   u32 block_offset;
+
+   reg_offset_shift = cdns_phy->init_data->reg_offset_shift;
+
+   block_offset = TORRENT_DPTX_PHY_OFFSET;
+   regmap = cdns_regmap_init(dev, base, block_offset,
+ reg_offset_shift,
+ _torrent_dptx_phy_config);
+   if (IS_ERR(regmap)) {
+   dev_err(dev, "Failed to init DPTX PHY regmap\n");
+   return PTR_ERR(regmap);
}
-   cdns_phy->phy_reset_ctrl = field;
+   cdns_phy->regmap_dptx_phy_reg = regmap;
 
return 0;
 }
 
-static int cdns_regmap_init_torrent_dp(struct cdns_torrent_phy *cdns_phy,
-  void __iomem *sd_base,
-  void __iomem *base,
-  u8 block_offset_shift,
-  u8 reg_offset_shift)
+static int cdns_torrent_regmap_init(struct cdns_torrent_phy *cdns_phy)
 {
+   void __iomem *sd_base = cdns_phy->sd_base;
+   u8 block_offset_shift, reg_offset_shift;
struct device *dev = cdns_phy->dev;
struct regmap *regmap;
u32 block_offset;
int i;
 
+   block_offset_shift = cdns_phy->init_data->block_offset_shift;
+   reg_offset_shift = cdns_phy->init_data->reg_offset_shift;
+
for (i = 0; i < MAX_NUM_LANES; i++) {
block_offset = TORRENT_TX_LANE_CDB_OFFSET(i, block_offset_shift,
  reg_offset_shift);
@@ -1690,16 +1723,6 @@ static int cdns_regmap_init_torrent_dp(struct 
cdns_torrent_phy *cdns_phy,
}
cdns_phy->regmap_phy_pma_common_cdb = regmap;
 
-   block_offset = TORRENT_DPTX_PHY_OFFSET;
-   regmap = cdns_regmap_init(dev, base, block_offset,
- reg_offset_shift,
- _torrent_dptx_phy_config);
-   if (IS_ERR(regmap)) {
-   dev_err(dev, "Failed to init DPTX PHY regmap\n");
-   return PTR_ERR(regmap);
-   }
-   cdns_phy->regmap_dptx_phy_reg = regmap;
-
return 0;
 }
 
@@ -1711,6 +1734,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
const struct cdns_torrent_data *data;
struct device_node *child;
int ret, subnodes, node = 0, i;
+   u8 init_dp_regmap = 0;
 
/* Get init data for this PHY */
data = of_device_get_match_data(dev);
@@ -1748,6 +1772,14 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
return -EINVAL;
}
 
+   ret = cdns_torrent_regmap_init(cdns_phy);
+   if (ret)
+   return ret;
+
+   ret = cdns_torrent_regfield_init(cdns_phy);
+   if (ret)
+   return ret;
+
for_each_available_chi

[PATCH v3 0/7] PHY: Prepare Cadence Torrent PHY driver to support multilink configurations

2020-09-16 Thread Swapnil Jakhade
Cadence Torrent PHY is a multiprotocol PHY supporting different multilink
PHY configurations including DisplayPort, PCIe, USB, SGMII, QSGMII etc.
Existing Torrent PHY driver supports only DisplayPort. This patch series
prepares Torrent PHY driver so that different multilink configurations can
be supported. It also updates DT bindings accordingly. This doesn't affect
ABI as Torrent PHY driver has never been functional, and therefore do not
exist in any active use case.

Support for different multilink configurations with register sequences for
protocols above will be added in a separate patch series.

Version History:

v3:
   - Rebased on latest PHY next
   - Fixed v2 review comments for DT patch 7/7

v2:
   - Rebased on latest PHY next and new PHY attributes patch series [1]

Swapnil Jakhade (7):
  phy: cadence-torrent: Use of_device_get_match_data() to get driver
data
  phy: cadence-torrent: Use devm_platform_ioremap_resource() to get reg
addresses
  phy: cadence-torrent: Enable support for multiple subnodes
  phy: cadence-torrent: Add separate regmap functions for torrent and DP
  phy: cadence-torrent: Check total lane count for all subnodes is
within limit
  dt-bindings: phy: cadence-torrent: Add binding to specify SSC mode
  dt-bindings: phy: cadence-torrent: Update Torrent PHY bindings for
generic use

 .../bindings/phy/phy-cadence-torrent.yaml |  86 +--
 drivers/phy/cadence/phy-cadence-torrent.c | 146 ++
 include/dt-bindings/phy/phy-cadence-torrent.h |  13 ++
 3 files changed, 166 insertions(+), 79 deletions(-)
 create mode 100644 include/dt-bindings/phy/phy-cadence-torrent.h

-- 
2.26.1



[PATCH v3 5/7] phy: cadence-torrent: Check total lane count for all subnodes is within limit

2020-09-16 Thread Swapnil Jakhade
Add checking if total number of lanes for all subnodes is not greater than
number of lanes supported by PHY.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 9dba7ba33fcd..6c199400fa5b 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -25,7 +25,6 @@
 #define REF_CLK_19_2MHz1920
 #define REF_CLK_25MHz  2500
 
-#define DEFAULT_NUM_LANES  4
 #define MAX_NUM_LANES  4
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
@@ -1734,6 +1733,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
const struct cdns_torrent_data *data;
struct device_node *child;
int ret, subnodes, node = 0, i;
+   u32 total_num_lanes = 0;
u8 init_dp_regmap = 0;
 
/* Get init data for this PHY */
@@ -1808,9 +1808,15 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
goto put_child;
}
 
-   cdns_phy->phys[node].num_lanes = DEFAULT_NUM_LANES;
-   of_property_read_u32(child, "cdns,num-lanes",
-_phy->phys[node].num_lanes);
+   if (of_property_read_u32(child, "cdns,num-lanes",
+_phy->phys[node].num_lanes)) {
+   dev_err(dev, "%s: No \"cdns,num-lanes\"-property.\n",
+   child->full_name);
+   ret = -EINVAL;
+   goto put_child;
+   }
+
+   total_num_lanes += cdns_phy->phys[node].num_lanes;
 
if (cdns_phy->phys[node].phy_type == PHY_TYPE_DP) {
switch (cdns_phy->phys[node].num_lanes) {
@@ -1890,6 +1896,11 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
}
cdns_phy->nsubnodes = node;
 
+   if (total_num_lanes > MAX_NUM_LANES) {
+   dev_err(dev, "Invalid lane configuration\n");
+   goto put_lnk_rst;
+   }
+
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (IS_ERR(phy_provider)) {
ret = PTR_ERR(phy_provider);
-- 
2.26.1



[PATCH v3 1/7] phy: cadence-torrent: Use of_device_get_match_data() to get driver data

2020-09-16 Thread Swapnil Jakhade
Use of_device_get_match_data() to get driver data instead of boilerplate
code.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index a065fc17de65..0211083a4d09 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -183,8 +183,6 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
 static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
-static const struct of_device_id cdns_torrent_phy_of_match[];
-
 struct cdns_torrent_inst {
struct phy *phy;
u32 mlane;
@@ -203,6 +201,7 @@ struct cdns_torrent_phy {
unsigned long ref_clk_rate;
struct cdns_torrent_inst phys[MAX_NUM_LANES];
int nsubnodes;
+   const struct cdns_torrent_data *init_data;
struct regmap *regmap;
struct regmap *regmap_common_cdb;
struct regmap *regmap_phy_pcs_common_cdb;
@@ -1710,24 +1709,22 @@ static int cdns_torrent_phy_probe(struct 
platform_device *pdev)
struct cdns_torrent_phy *cdns_phy;
struct device *dev = >dev;
struct phy_provider *phy_provider;
-   const struct of_device_id *match;
-   struct cdns_torrent_data *data;
+   const struct cdns_torrent_data *data;
struct device_node *child;
int ret, subnodes, node = 0, i;
 
/* Get init data for this PHY */
-   match = of_match_device(cdns_torrent_phy_of_match, dev);
-   if (!match)
+   data = of_device_get_match_data(dev);
+   if (!data)
return -EINVAL;
 
-   data = (struct cdns_torrent_data *)match->data;
-
cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
if (!cdns_phy)
return -ENOMEM;
 
dev_set_drvdata(dev, cdns_phy);
cdns_phy->dev = dev;
+   cdns_phy->init_data = data;
 
cdns_phy->phy_rst = devm_reset_control_get_exclusive_by_index(dev, 0);
if (IS_ERR(cdns_phy->phy_rst)) {
-- 
2.26.1



[PATCH v3 7/7] dt-bindings: phy: cadence-torrent: Update Torrent PHY bindings for generic use

2020-09-16 Thread Swapnil Jakhade
Torrent PHY can be used in different multi-link multi-protocol
configurations including protocols other than DisplayPort also,
such as PCIe, USB, SGMII, QSGMII etc. Update the bindings to have
support for these configurations.

Signed-off-by: Swapnil Jakhade 
---
 .../bindings/phy/phy-cadence-torrent.yaml | 77 +++
 1 file changed, 60 insertions(+), 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml 
b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
index a7ee19d27c19..26480f89627d 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
@@ -4,11 +4,13 @@
 $id: "http://devicetree.org/schemas/phy/phy-cadence-torrent.yaml#;
 $schema: "http://devicetree.org/meta-schemas/core.yaml#;
 
-title: Cadence Torrent SD0801 PHY binding for DisplayPort
+title: Cadence Torrent SD0801 PHY binding
 
 description:
   This binding describes the Cadence SD0801 PHY (also known as Torrent PHY)
-  hardware included with the Cadence MHDP DisplayPort controller.
+  hardware included with the Cadence MHDP DisplayPort controller. Torrent
+  PHY also supports multilink multiprotocol combinations including protocols
+  such as PCIe, USB, SGMII, QSGMII etc.
 
 maintainers:
   - Swapnil Jakhade 
@@ -49,13 +51,14 @@ properties:
   - const: dptx_phy
 
   resets:
-maxItems: 1
-description:
-  Torrent PHY reset.
-  See Documentation/devicetree/bindings/reset/reset.txt
+minItems: 1
+maxItems: 2
+items:
+  - description: Torrent PHY reset.
+  - description: Torrent APB reset. This is optional.
 
 patternProperties:
-  '^phy@[0-7]+$':
+  '^phy@[0-3]$':
 type: object
 description:
   Each group of PHY lanes with a single master lane should be represented 
as a sub-node.
@@ -63,6 +66,8 @@ patternProperties:
   reg:
 description:
   The master lane number. This is the lowest numbered lane in the lane 
group.
+minimum: 0
+maximum: 3
 
   resets:
 minItems: 1
@@ -78,13 +83,14 @@ patternProperties:
   Specifies the type of PHY for which the group of PHY lanes is used.
   Refer include/dt-bindings/phy/phy.h. Constants from the header 
should be used.
 $ref: /schemas/types.yaml#/definitions/uint32
-enum: [1, 2, 3, 4, 5, 6]
+minimum: 1
+maximum: 9
 
   cdns,num-lanes:
 description:
-  Number of DisplayPort lanes.
+  Number of lanes.
 $ref: /schemas/types.yaml#/definitions/uint32
-enum: [1, 2, 4]
+enum: [1, 2, 3, 4]
 default: 4
 
   cdns,ssc-mode:
@@ -108,6 +114,7 @@ patternProperties:
   - resets
   - "#phy-cells"
   - cdns,phy-type
+  - cdns,num-lanes
 
 additionalProperties: false
 
@@ -142,13 +149,49 @@ examples:
 #address-cells = <1>;
 #size-cells = <0>;
 phy@0 {
-  reg = <0>;
-  resets = < 1>, < 2>,
-   < 3>, < 4>;
-  #phy-cells = <0>;
-  cdns,phy-type = ;
-  cdns,num-lanes = <4>;
-  cdns,max-bit-rate = <8100>;
+reg = <0>;
+resets = < 1>, < 2>,
+ < 3>, < 4>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <4>;
+cdns,max-bit-rate = <8100>;
+};
+};
+};
+  - |
+#include 
+#include 
+
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+
+torrent-phy@f0fb50 {
+compatible = "cdns,torrent-phy";
+reg = <0xf0 0xfb50 0x0 0x0010>;
+reg-names = "torrent_phy";
+resets = < 0>, < 1>;
+clocks = <_clk>;
+clock-names = "refclk";
+#address-cells = <1>;
+#size-cells = <0>;
+phy@0 {
+reg = <0>;
+resets = < 2>, < 3>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <2>;
+cdns,ssc-mode = ;
+};
+
+phy@2 {
+reg = <2>;
+resets = < 4>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <1>;
+cdns,ssc-mode = ;
 };
 };
 };
-- 
2.26.1



[PATCH v10 3/3] drm: bridge: cdns-mhdp8546: Add TI J721E wrapper

2020-09-14 Thread Swapnil Jakhade
Add J721E wrapper for mhdp, which sets up the clock and data muxes.

Signed-off-by: Jyri Sarha 
Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Reviewed-by: Tomi Valkeinen 
Reviewed-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/cadence/Kconfig| 13 
 drivers/gpu/drm/bridge/cadence/Makefile   |  1 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 10 +++
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  1 +
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.c  | 78 +++
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.h  | 19 +
 6 files changed, 122 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.h

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig 
b/drivers/gpu/drm/bridge/cadence/Kconfig
index f49d77eb7814..511d67b16d14 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -9,3 +9,16 @@ config DRM_CDNS_MHDP8546
  bridge and is meant to be directly embedded in a SoC.
  It takes a DPI stream as input and outputs it encoded
  in DP format.
+
+if DRM_CDNS_MHDP8546
+
+config DRM_CDNS_MHDP8546_J721E
+   depends on ARCH_K3_J721E_SOC || COMPILE_TEST
+   bool "J721E Cadence DPI/DP wrapper support"
+   default y
+   help
+ Support J721E Cadence DPI/DP wrapper. This is a wrapper
+ which adds support for J721E related platform ops. It
+ initializes the J721E Display Port and sets up the
+ clock and data muxes.
+endif
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile 
b/drivers/gpu/drm/bridge/cadence/Makefile
index 676739cdf5e6..8f647991b374 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o
+cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 7b1bd5d10923..621ebdbff8a3 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -50,6 +50,8 @@
 
 #include "cdns-mhdp8546-core.h"
 
+#include "cdns-mhdp8546-j721e.h"
+
 static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
 {
int ret, empty;
@@ -2496,6 +2498,14 @@ static int cdns_mhdp_remove(struct platform_device *pdev)
 
 static const struct of_device_id mhdp_ids[] = {
{ .compatible = "cdns,mhdp8546", },
+#ifdef CONFIG_DRM_CDNS_MHDP8546_J721E
+   { .compatible = "ti,j721e-mhdp8546",
+ .data = &(const struct cdns_mhdp_platform_info) {
+ .timings = _ti_j721e_bridge_timings,
+ .ops = _ti_j721e_ops,
+ },
+   },
+#endif
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mhdp_ids);
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
index c0fff78d15be..5897a85e3159 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -341,6 +341,7 @@ struct cdns_mhdp_platform_info {
 
 struct cdns_mhdp_device {
void __iomem *regs;
+   void __iomem *j721e_regs;
 
struct device *dev;
struct clk *clk;
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
new file mode 100644
index ..dfe1b59514f7
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI j721e Cadence MHDP8546 DP wrapper
+ *
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Jyri Sarha 
+ */
+
+#include 
+#include 
+
+#include "cdns-mhdp8546-j721e.h"
+
+#defineREVISION0x00
+#defineDPTX_IPCFG  0x04
+#defineECC_MEM_CFG 0x08
+#defineDPTX_DSC_CFG0x0c
+#defineDPTX_SRC_CFG0x10
+#defineDPTX_VIF_SECURE_MODE_CFG0x14
+#defineDPTX_VIF_CONN_STATUS0x18
+#definePHY_CLK_STATUS  0x1c
+
+#define DPTX_SRC_AIF_ENBIT(16)
+#define DPTX_SRC_VIF_3_IN30B   BIT(11)
+#define DPTX_SRC_VIF_2_IN30B   BIT(10)
+#define DPTX_SRC_VIF_1_IN30B   BIT(9)
+#define DPTX_SRC_VIF_0_IN30B   BIT(8)
+#define DPTX_SRC_VIF_3_SEL_DPI5BIT(7)
+#define DPTX_SRC_VIF_3_SEL_DPI30
+#define DPTX_SRC_VIF_2_SEL_DPI4BIT(6)
+#define DPTX_SRC_VIF_2_SEL_DPI20
+#define DPTX_SRC_VIF_1

[PATCH v10 0/3] drm: Add support for Cadence MHDP8546 DPI/DP bridge and J721E wrapper.

2020-09-14 Thread Swapnil Jakhade
pdated phy property description in YAML to a generic one.
- Renamed num_lanes and max_bit_rate property strings to cdns,num-lanes
  and cdns,max-bit-rate.

v2:
- Use enum in compatible property of YAML file.
- Add reg-names property to YAML file
- Add minItems and maxItems to reg property in YAML.
- Remove cdns_mhdp_link_probe function to remove
  duplication of reading dpcd capabilities.

Swapnil Jakhade (2):
  drm: bridge: Add support for Cadence MHDP8546 DPI/DP bridge
  drm: bridge: cdns-mhdp8546: Add TI J721E wrapper

Yuti Amonkar (1):
  dt-bindings: drm/bridge: Document Cadence MHDP8546 bridge bindings

 .../display/bridge/cdns,mhdp8546.yaml |  154 +
 drivers/gpu/drm/bridge/Kconfig|2 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/cadence/Kconfig|   24 +
 drivers/gpu/drm/bridge/cadence/Makefile   |4 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 2532 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  400 +++
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.c  |   78 +
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.h  |   19 +
 9 files changed, 3214 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
 create mode 100644 drivers/gpu/drm/bridge/cadence/Kconfig
 create mode 100644 drivers/gpu/drm/bridge/cadence/Makefile
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.h

-- 
2.26.1



[PATCH v10 1/3] dt-bindings: drm/bridge: Document Cadence MHDP8546 bridge bindings

2020-09-14 Thread Swapnil Jakhade
From: Yuti Amonkar 

Document the bindings used for the Cadence MHDP8546 DPI/DP bridge in
yaml format.

Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
---
 .../display/bridge/cdns,mhdp8546.yaml | 154 ++
 1 file changed, 154 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml

diff --git 
a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml 
b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
new file mode 100644
index ..a21a4bfe15cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
@@ -0,0 +1,154 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/bridge/cdns,mhdp8546.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Cadence MHDP8546 bridge
+
+maintainers:
+  - Swapnil Jakhade 
+  - Yuti Amonkar 
+
+properties:
+  compatible:
+enum:
+  - cdns,mhdp8546
+  - ti,j721e-mhdp8546
+
+  reg:
+minItems: 1
+maxItems: 2
+items:
+  - description:
+  Register block of mhdptx apb registers up to PHY mapped area 
(AUX_CONFIG_P).
+  The AUX and PMA registers are not part of this range, they are 
instead
+  included in the associated PHY.
+  - description:
+  Register block for DSS_EDP0_INTG_CFG_VP registers in case of TI J7 
SoCs.
+
+  reg-names:
+minItems: 1
+maxItems: 2
+items:
+  - const: mhdptx
+  - const: j721e-intg
+
+  clocks:
+maxItems: 1
+description:
+  DP bridge clock, used by the IP to know how to translate a number of
+  clock cycles into a time (which is used to comply with DP standard 
timings
+  and delays).
+
+  phys:
+maxItems: 1
+description:
+  phandle to the DisplayPort PHY.
+
+  ports:
+type: object
+description:
+  Ports as described in Documentation/devicetree/bindings/graph.txt.
+
+properties:
+  '#address-cells':
+const: 1
+
+  '#size-cells':
+const: 0
+
+  port@0:
+type: object
+description:
+  First input port representing the DP bridge input.
+
+  port@1:
+type: object
+description:
+  Second input port representing the DP bridge input.
+
+  port@2:
+type: object
+description:
+  Third input port representing the DP bridge input.
+
+  port@3:
+type: object
+description:
+  Fourth input port representing the DP bridge input.
+
+  port@4:
+type: object
+description:
+  Output port representing the DP bridge output.
+
+required:
+  - port@0
+  - port@4
+  - '#address-cells'
+  - '#size-cells'
+
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: ti,j721e-mhdp8546
+then:
+  properties:
+reg:
+  minItems: 2
+reg-names:
+  minItems: 2
+else:
+  properties:
+reg:
+  maxItems: 1
+reg-names:
+  maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - reg
+  - reg-names
+  - phys
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mhdp: dp-bridge@f0fb00 {
+compatible = "cdns,mhdp8546";
+reg = <0xf0 0xfb00 0x0 0x100>;
+reg-names = "mhdptx";
+clocks = <_clock>;
+phys = <_phy>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+dp_bridge_input: endpoint {
+remote-endpoint = <_dpi_output>;
+};
+};
+
+port@4 {
+reg = <4>;
+dp_bridge_output: endpoint {
+remote-endpoint = <_dp_connector_input>;
+};
+};
+};
+};
+};
+...
-- 
2.26.1



[PATCH v10 2/3] drm: bridge: Add support for Cadence MHDP8546 DPI/DP bridge

2020-09-14 Thread Swapnil Jakhade
Add a new DRM bridge driver for Cadence MHDP8546 DPTX IP used in TI J721E
SoC. MHDP DPTX IP is the component that complies with VESA DisplayPort (DP)
and embedded Display Port (eDP) standards. It integrates uCPU running the
embedded Firmware (FW) interfaced over APB interface.

Basically, it takes a DPI stream as input and outputs it encoded in DP
format. Currently, it supports only SST mode.

Co-developed-by: Tomi Valkeinen 
Signed-off-by: Tomi Valkeinen 
Co-developed-by: Jyri Sarha 
Signed-off-by: Jyri Sarha 
Signed-off-by: Quentin Schulz 
Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Reviewed-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/Kconfig|2 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/cadence/Kconfig|   11 +
 drivers/gpu/drm/bridge/cadence/Makefile   |3 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 2522 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  399 +++
 6 files changed, 2938 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/Kconfig
 create mode 100644 drivers/gpu/drm/bridge/cadence/Makefile
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 3e11af4e9f63..ef91646441b1 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -241,6 +241,8 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig"
 
 source "drivers/gpu/drm/bridge/adv7511/Kconfig"
 
+source "drivers/gpu/drm/bridge/cadence/Kconfig"
+
 source "drivers/gpu/drm/bridge/synopsys/Kconfig"
 
 endmenu
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index c589a6a7cbe1..2b3aff104e46 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -25,4 +25,5 @@ obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
 obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
 
 obj-y += analogix/
+obj-y += cadence/
 obj-y += synopsys/
diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig 
b/drivers/gpu/drm/bridge/cadence/Kconfig
new file mode 100644
index ..f49d77eb7814
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config DRM_CDNS_MHDP8546
+   tristate "Cadence DPI/DP bridge"
+   select DRM_KMS_HELPER
+   select DRM_PANEL_BRIDGE
+   depends on OF
+   help
+ Support Cadence DPI to DP bridge. This is an internal
+ bridge and is meant to be directly embedded in a SoC.
+ It takes a DPI stream as input and outputs it encoded
+ in DP format.
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile 
b/drivers/gpu/drm/bridge/cadence/Makefile
new file mode 100644
index ..676739cdf5e6
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
+cdns-mhdp8546-y := cdns-mhdp8546-core.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
new file mode 100644
index ..7b1bd5d10923
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -0,0 +1,2522 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cadence MHDP8546 DP bridge driver.
+ *
+ * Copyright (C) 2020 Cadence Design Systems, Inc.
+ *
+ * Authors: Quentin Schulz 
+ *  Swapnil Jakhade 
+ *  Yuti Amonkar 
+ *  Tomi Valkeinen 
+ *  Jyri Sarha 
+ *
+ * TODO:
+ * - Implement optimized mailbox communication using mailbox interrupts
+ * - Add support for power management
+ * - Add support for features like audio, MST and fast link training
+ * - Implement request_fw_cancel to handle HW_STATE
+ * - Fix asynchronous loading of firmware implementation
+ * - Add DRM helper function for cdns_mhdp_lower_link_rate
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "cdns-mhdp8546-core.h"
+
+static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
+{
+   int ret, empty;
+
+   WARN_ON(!mutex_is_locked(>mbox_mutex));
+
+   ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY,
+empty, !empty, MAILBOX_RETRY_US,
+MAILBOX_TIMEOUT_US);
+   if (ret < 0)
+   return ret;
+
+   return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
+}
+
+static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val)
+{
+   in

[PATCH v6 1/2] phy: Add new PHY attribute max_link_rate

2020-09-11 Thread Swapnil Jakhade
Add new PHY attribute max_link_rate to struct phy_attrs. This indicates
maximum link rate supported by PHY (in Mbps).

Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Acked-by: Kishon Vijay Abraham I 
---
 include/linux/phy/phy.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index bcee8eba62b3..e435bdb0bab3 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -115,10 +115,12 @@ struct phy_ops {
 /**
  * struct phy_attrs - represents phy attributes
  * @bus_width: Data path width implemented by PHY
+ * @max_link_rate: Maximum link rate supported by PHY (in Mbps)
  * @mode: PHY mode
  */
 struct phy_attrs {
u32 bus_width;
+   u32 max_link_rate;
enum phy_mode   mode;
 };
 
-- 
2.26.1



[PATCH v6 0/2] PHY: Add new PHY attribute max_link_rate

2020-09-11 Thread Swapnil Jakhade
This patch series adds a new PHY attribute max_link_rate.
It also updates Cadence Torrent PHY driver to set attributes bus_width,
max_link_rate and mode for DisplayPort.

It includes following patches:

1. 0001-phy-Add-new-PHY-attribute-max_link_rate.patch
This patch adds max_link_rate as a new PHY attribute.

2. 0002-phy-cadence-torrent-Set-Torrent-PHY-attributes.patch
This patch sets PHY attributes in Cadence Torrent PHY driver. This will
enable drivers using this PHY to read these properties.

These attributes will be used in the Cadence MHDP DRM bridge driver [1]
which is in the process of upstreaming.

[1]

https://lkml.org/lkml/2020/8/31/171

Version History:

v6:
   - Remove implementation of new APIs phy_get_attrs/phy_set_attrs
   - Set attributes manually in Torrent PHY driver

v5:
- Add kernel-doc comments for phy_get_attrs/phy_set_attrs APIs
- Pass second parameter of phy_set_attrs() as const struct *
- Add Acked-by: Kishon Vijay Abraham I 

v4:
- Protect phy_get_attrs/phy_set_attrs APIs with mutex

v3:
- Add comment describing new PHY attribute max_link_rate
- Use of memcpy to copy structure members
- Change commit log a bit

v2:
- Implemented single pair of functions to get/set all PHY attributes

Swapnil Jakhade (2):
  phy: Add new PHY attribute max_link_rate
  phy: cadence-torrent: Set Torrent PHY attributes

 drivers/phy/cadence/phy-cadence-torrent.c | 4 
 include/linux/phy/phy.h   | 2 ++
 2 files changed, 6 insertions(+)

-- 
2.26.1



[PATCH v6 2/2] phy: cadence-torrent: Set Torrent PHY attributes

2020-09-11 Thread Swapnil Jakhade
Set Torrent PHY attributes bus_width, max_link_rate and mode
for DisplayPort.

Signed-off-by: Swapnil Jakhade 
Acked-by: Kishon Vijay Abraham I 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 7116127358ee..116aca36f7dd 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1852,6 +1852,10 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
 cdns_phy->phys[node].num_lanes,
 cdns_phy->max_bit_rate / 1000,
 cdns_phy->max_bit_rate % 1000);
+
+   gphy->attrs.bus_width = cdns_phy->phys[node].num_lanes;
+   gphy->attrs.max_link_rate = cdns_phy->max_bit_rate;
+   gphy->attrs.mode = PHY_MODE_DP;
} else {
dev_err(dev, "Driver supports only PHY_TYPE_DP\n");
ret = -ENOTSUPP;
-- 
2.26.1



[PATCH v9 1/3] dt-bindings: drm/bridge: Document Cadence MHDP8546 bridge bindings

2020-08-31 Thread Swapnil Jakhade
From: Yuti Amonkar 

Document the bindings used for the Cadence MHDP8546 DPI/DP bridge in
yaml format.

Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
---
 .../display/bridge/cdns,mhdp8546.yaml | 154 ++
 1 file changed, 154 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml

diff --git 
a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml 
b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
new file mode 100644
index ..a21a4bfe15cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
@@ -0,0 +1,154 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/bridge/cdns,mhdp8546.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Cadence MHDP8546 bridge
+
+maintainers:
+  - Swapnil Jakhade 
+  - Yuti Amonkar 
+
+properties:
+  compatible:
+enum:
+  - cdns,mhdp8546
+  - ti,j721e-mhdp8546
+
+  reg:
+minItems: 1
+maxItems: 2
+items:
+  - description:
+  Register block of mhdptx apb registers up to PHY mapped area 
(AUX_CONFIG_P).
+  The AUX and PMA registers are not part of this range, they are 
instead
+  included in the associated PHY.
+  - description:
+  Register block for DSS_EDP0_INTG_CFG_VP registers in case of TI J7 
SoCs.
+
+  reg-names:
+minItems: 1
+maxItems: 2
+items:
+  - const: mhdptx
+  - const: j721e-intg
+
+  clocks:
+maxItems: 1
+description:
+  DP bridge clock, used by the IP to know how to translate a number of
+  clock cycles into a time (which is used to comply with DP standard 
timings
+  and delays).
+
+  phys:
+maxItems: 1
+description:
+  phandle to the DisplayPort PHY.
+
+  ports:
+type: object
+description:
+  Ports as described in Documentation/devicetree/bindings/graph.txt.
+
+properties:
+  '#address-cells':
+const: 1
+
+  '#size-cells':
+const: 0
+
+  port@0:
+type: object
+description:
+  First input port representing the DP bridge input.
+
+  port@1:
+type: object
+description:
+  Second input port representing the DP bridge input.
+
+  port@2:
+type: object
+description:
+  Third input port representing the DP bridge input.
+
+  port@3:
+type: object
+description:
+  Fourth input port representing the DP bridge input.
+
+  port@4:
+type: object
+description:
+  Output port representing the DP bridge output.
+
+required:
+  - port@0
+  - port@4
+  - '#address-cells'
+  - '#size-cells'
+
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: ti,j721e-mhdp8546
+then:
+  properties:
+reg:
+  minItems: 2
+reg-names:
+  minItems: 2
+else:
+  properties:
+reg:
+  maxItems: 1
+reg-names:
+  maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - reg
+  - reg-names
+  - phys
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mhdp: dp-bridge@f0fb00 {
+compatible = "cdns,mhdp8546";
+reg = <0xf0 0xfb00 0x0 0x100>;
+reg-names = "mhdptx";
+clocks = <_clock>;
+phys = <_phy>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+dp_bridge_input: endpoint {
+remote-endpoint = <_dpi_output>;
+};
+};
+
+port@4 {
+reg = <4>;
+dp_bridge_output: endpoint {
+remote-endpoint = <_dp_connector_input>;
+};
+};
+};
+};
+};
+...
-- 
2.26.1



[PATCH v9 3/3] drm: bridge: cdns-mhdp8546: Add TI J721E wrapper

2020-08-31 Thread Swapnil Jakhade
Add J721E wrapper for mhdp, which sets up the clock and data muxes.

Signed-off-by: Jyri Sarha 
Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Reviewed-by: Tomi Valkeinen 
Reviewed-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/cadence/Kconfig| 13 
 drivers/gpu/drm/bridge/cadence/Makefile   |  1 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 10 +++
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  1 +
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.c  | 78 +++
 .../drm/bridge/cadence/cdns-mhdp8546-j721e.h  | 19 +
 6 files changed, 122 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.h

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig 
b/drivers/gpu/drm/bridge/cadence/Kconfig
index f49d77eb7814..511d67b16d14 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -9,3 +9,16 @@ config DRM_CDNS_MHDP8546
  bridge and is meant to be directly embedded in a SoC.
  It takes a DPI stream as input and outputs it encoded
  in DP format.
+
+if DRM_CDNS_MHDP8546
+
+config DRM_CDNS_MHDP8546_J721E
+   depends on ARCH_K3_J721E_SOC || COMPILE_TEST
+   bool "J721E Cadence DPI/DP wrapper support"
+   default y
+   help
+ Support J721E Cadence DPI/DP wrapper. This is a wrapper
+ which adds support for J721E related platform ops. It
+ initializes the J721E Display Port and sets up the
+ clock and data muxes.
+endif
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile 
b/drivers/gpu/drm/bridge/cadence/Makefile
index 676739cdf5e6..8f647991b374 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o
+cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 14be6f370d6e..5dc83b2e3603 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -50,6 +50,8 @@
 
 #include "cdns-mhdp8546-core.h"
 
+#include "cdns-mhdp8546-j721e.h"
+
 static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
 {
int ret, empty;
@@ -2522,6 +2524,14 @@ static int cdns_mhdp_remove(struct platform_device *pdev)
 
 static const struct of_device_id mhdp_ids[] = {
{ .compatible = "cdns,mhdp8546", },
+#ifdef CONFIG_DRM_CDNS_MHDP8546_J721E
+   { .compatible = "ti,j721e-mhdp8546",
+ .data = &(const struct cdns_mhdp_platform_info) {
+ .timings = _ti_j721e_bridge_timings,
+ .ops = _ti_j721e_ops,
+ },
+   },
+#endif
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mhdp_ids);
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
index 14ba7431fab8..d2183f3f3263 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -344,6 +344,7 @@ struct cdns_mhdp_platform_info {
 
 struct cdns_mhdp_device {
void __iomem *regs;
+   void __iomem *j721e_regs;
 
struct device *dev;
struct clk *clk;
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
new file mode 100644
index ..dfe1b59514f7
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-j721e.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI j721e Cadence MHDP8546 DP wrapper
+ *
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Jyri Sarha 
+ */
+
+#include 
+#include 
+
+#include "cdns-mhdp8546-j721e.h"
+
+#defineREVISION0x00
+#defineDPTX_IPCFG  0x04
+#defineECC_MEM_CFG 0x08
+#defineDPTX_DSC_CFG0x0c
+#defineDPTX_SRC_CFG0x10
+#defineDPTX_VIF_SECURE_MODE_CFG0x14
+#defineDPTX_VIF_CONN_STATUS0x18
+#definePHY_CLK_STATUS  0x1c
+
+#define DPTX_SRC_AIF_ENBIT(16)
+#define DPTX_SRC_VIF_3_IN30B   BIT(11)
+#define DPTX_SRC_VIF_2_IN30B   BIT(10)
+#define DPTX_SRC_VIF_1_IN30B   BIT(9)
+#define DPTX_SRC_VIF_0_IN30B   BIT(8)
+#define DPTX_SRC_VIF_3_SEL_DPI5BIT(7)
+#define DPTX_SRC_VIF_3_SEL_DPI30
+#define DPTX_SRC_VIF_2_SEL_DPI4BIT(6)
+#define DPTX_SRC_VIF_2_SEL_DPI20
+#define DPTX_SRC_VIF_1

[PATCH v9 2/3] drm: bridge: Add support for Cadence MHDP8546 DPI/DP bridge

2020-08-31 Thread Swapnil Jakhade
Add a new DRM bridge driver for Cadence MHDP8546 DPTX IP used in TI J721E
SoC. MHDP DPTX IP is the component that complies with VESA DisplayPort (DP)
and embedded Display Port (eDP) standards. It integrates uCPU running the
embedded Firmware (FW) interfaced over APB interface.

Basically, it takes a DPI stream as input and outputs it encoded in DP
format. Currently, it supports only SST mode.

Co-developed-by: Tomi Valkeinen 
Signed-off-by: Tomi Valkeinen 
Co-developed-by: Jyri Sarha 
Signed-off-by: Jyri Sarha 
Signed-off-by: Quentin Schulz 
Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
---
 drivers/gpu/drm/bridge/Kconfig|2 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/cadence/Kconfig|   11 +
 drivers/gpu/drm/bridge/cadence/Makefile   |3 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 2548 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  402 +++
 6 files changed, 2967 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/Kconfig
 create mode 100644 drivers/gpu/drm/bridge/cadence/Makefile
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 3e11af4e9f63..ef91646441b1 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -241,6 +241,8 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig"
 
 source "drivers/gpu/drm/bridge/adv7511/Kconfig"
 
+source "drivers/gpu/drm/bridge/cadence/Kconfig"
+
 source "drivers/gpu/drm/bridge/synopsys/Kconfig"
 
 endmenu
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index c589a6a7cbe1..2b3aff104e46 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -25,4 +25,5 @@ obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
 obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
 
 obj-y += analogix/
+obj-y += cadence/
 obj-y += synopsys/
diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig 
b/drivers/gpu/drm/bridge/cadence/Kconfig
new file mode 100644
index ..f49d77eb7814
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config DRM_CDNS_MHDP8546
+   tristate "Cadence DPI/DP bridge"
+   select DRM_KMS_HELPER
+   select DRM_PANEL_BRIDGE
+   depends on OF
+   help
+ Support Cadence DPI to DP bridge. This is an internal
+ bridge and is meant to be directly embedded in a SoC.
+ It takes a DPI stream as input and outputs it encoded
+ in DP format.
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile 
b/drivers/gpu/drm/bridge/cadence/Makefile
new file mode 100644
index ..676739cdf5e6
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
+cdns-mhdp8546-y := cdns-mhdp8546-core.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
new file mode 100644
index ..14be6f370d6e
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -0,0 +1,2548 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cadence MHDP8546 DP bridge driver.
+ *
+ * Copyright (C) 2020 Cadence Design Systems, Inc.
+ *
+ * Authors: Quentin Schulz 
+ *  Swapnil Jakhade 
+ *  Yuti Amonkar 
+ *  Tomi Valkeinen 
+ *  Jyri Sarha 
+ *
+ * TODO:
+ * - Implement optimized mailbox communication using mailbox interrupts
+ * - Add support for power management
+ * - Add support for features like audio, MST and fast link training
+ * - Implement request_fw_cancel to handle HW_STATE
+ * - Fix asynchronous loading of firmware implementation
+ * - Add DRM helper function for cdns_mhdp_lower_link_rate
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "cdns-mhdp8546-core.h"
+
+static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
+{
+   int ret, empty;
+
+   WARN_ON(!mutex_is_locked(>mbox_mutex));
+
+   ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY,
+empty, !empty, MAILBOX_RETRY_US,
+MAILBOX_TIMEOUT_US);
+   if (ret < 0)
+   return ret;
+
+   return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
+}
+
+static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val)
+{
+   int ret, full;
+
+   WARN_ON(!mutex_i

[PATCH v9 0/3] drm: Add support for Cadence MHDP8546 DPI/DP bridge and J721E wrapper.

2020-08-31 Thread Swapnil Jakhade
This patch series adds new DRM bridge driver for Cadence MHDP8546 DPI/DP
bridge. The Cadence Display Port IP is also referred as MHDP (Mobile High
Definition Link, High-Definition Multimedia Interface, Display Port).
Cadence Display Port complies with VESA DisplayPort (DP) and embedded
Display Port (eDP) standards.

The MHDP bridge driver currently implements Single Stream Transport (SST)
mode. It also adds Texas Instruments j721e SoC specific wrapper and adds
the device tree bindings in YAML format.

Some of the features that will be added later on include (but are not
limited to):
- Power Management (PM) support: We will implement the PM functions in
  next stage once there will be a stable driver in upstream
- Audio and MST support

The patch series has three patches in the below sequence:
1. 0001-dt-bindings-drm-bridge-Document-Cadence-MHDP8546-.patch
Documents the bindings in yaml format.
2. 0002-drm-bridge-Add-support-for-Cadence-MHDP8546-DPI-D.patch
This patch adds new DRM bridge driver for Cadence MHDP Display Port.
The patch implements support for single stream transport mode.
3. 0003-drm-bridge-cdns-mhdp8546-Add-TI-J721E-wrapper.patch
Adds Texas Instruments (TI) j721e wrapper for MHDP. The wrapper configures
MHDP clocks and muxes as required by SoC.

This patch series is dependent on PHY patch series [1] to add new PHY APIs
to get/set PHY attributes which is under review and not merged yet.

[1] https://lkml.org/lkml/2020/8/24/1586

Version History:

v9:

In 1/3
- Rename bindings file to cdns,mhdp8546.yaml.
- Minor changes replacing mhdp with mhdp8546 to include IP part number.
- Add 4 input ports and one output port supporting MST for DP bridge.

In 2/3
- Add driver files in cadence folder under drm/bridge.
- Rename driver files to include part number mhdp8546.
- Remove link training calls from atomic_check.
- Support DRM_BRIDGE_OP_HPD with hpd_enable, hpd_disable callbacks.
- Remove unnecessary fw states.
- Fix other review comments for v8 patches.

In 3/3
- Add input_bus_flags specific for J721E in drm_bridge_timings.
- Fix other review comments for v8 patches.

v8:

In 1/3
- Fix error reported by dt_binding_check
- Fix indent in the example
- Fix other comments given for v7 patches.

In 2/3:
- Implement bridge connector operations .get_edid() and .detect().
- Make connector creation optional based on DRM_BRIDGE_ATTACH_NO_CONNECTOR
  flag.
- Fix other comments given for v7 patches.

In 3/3
- Fix comments given for v7 patches.

v7:

In 1/3
- No change

In 2/3
- Switch to atomic versions of bridge operations
- Implement atomic_check() handler to perform all validation checks
- Add struct cdns_mhdp_bridge_state with subclassed bridge state
- Use PHY API[1] to get PHY attributes instead of reading from PHY DT node
- Updated HPD handling and link configuration in IRQ handler
- Add "link_mutex" protecting the access to all the link parameters
- Add support to check and print FW version information
- Add separate function to initialize host parameters to simplify probe
- Use waitqueue instead of manual loop in cdns_mhdp_remove
- Add forward declarations and header files in cdns-mhdp-core.h file
- Use bool instead of single bit values in struct cdns_mhdp_device
- Fix for other minor comments given for v6 patches

In 3/3
- Use of_device_is_compatible() to set compatible string specific values
- Move mhdp_ti_j721e_ops structure to cdns-mhdp-j721e.c
- Remove duplicate Copyright message
- Remove CONFIG_DRM_CDNS_MHDP_J721E check
- Add Reviewed-by: Laurent Pinchart 

v6:
- Added minor fixes in YAML file.
- Added Reviewed-by: Laurent Pinchart 
  to the YAML patch.
- Removed all the FIXME comments which are invalid in drm driver.
- Reduced the mailbox timeout from 5s to 2s.
- Added Reviewed-by: Tomi Valkeinen 
  to the 003-drm-mhdp-add-j721e-wrapper patch.
- Added Signed-off all the module authors.
- Fixed the compiler error Reported-by: kbuild test robot .

v5:
- Added Signed-off-by: Jyri Sarha  tag to
  the code patches.

v4:
- Added SPDX dual license tag to YAML bindings.
- Corrected indentation of the child node properties.
- Removed the maxItems in the conditional statement.
- Add Reviewed-by: Rob Herring  tag to the
  Document Cadence MHDP bridge bindings patch.
- Renamed the DRM driver executable name from mhdp8546 to cdns-mhdp in
  Makefile.
- Renamed the DRM driver and header file from cdns-mhdp to cdns-mhdp-core.

v3:
- Added if / then clause to validate that the reg length is proper
  based on the value of the compatible property.
- Updated phy property description in YAML to a generic one.
- Renamed num_lanes and max_bit_rate property strings to cdns,num-lanes
  and cdns,max-bit-rate.

v2:
- Use enum in compatible property of YAML file.
- Add reg-names property to YAML file
- Add minItems and maxItems to reg property in YAML.
- Remove cdns_mhdp_link_probe function to remove
  duplication of reading dpcd capabilities.

Swapnil Jakhade (2):
  drm: bridge: Add support for Cadence MHDP8

[PATCH v2 08/13] phy: cadence-torrent: Add PHY link configuration sequences for single link

2020-08-27 Thread Swapnil Jakhade
Add support to configure link_cmn_vals and xcvr_diag_vals in case of single
link PHY configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 44 +++
 1 file changed, 44 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 9a87ee39a15a..eda3839762cb 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1809,6 +1809,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
const struct cdns_torrent_data *init_data = cdns_phy->init_data;
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
+   struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
enum cdns_torrent_ssc_mode ssc = inst->ssc_mode;
@@ -1823,6 +1824,29 @@ static int cdns_torrent_phy_init(struct phy *phy)
if (phy_type == TYPE_DP)
return cdns_torrent_dp_init(phy);
 
+   /* PHY configuration specific registers for single link */
+   link_cmn_vals = init_data->link_cmn_vals[phy_type][TYPE_NONE][ssc];
+   if (link_cmn_vals) {
+   reg_pairs = link_cmn_vals->reg_pairs;
+   num_regs = link_cmn_vals->num_regs;
+   regmap = cdns_phy->regmap_common_cdb;
+   for (i = 0; i < num_regs; i++)
+   regmap_write(regmap, reg_pairs[i].off,
+reg_pairs[i].val);
+   }
+
+   xcvr_diag_vals = init_data->xcvr_diag_vals[phy_type][TYPE_NONE][ssc];
+   if (xcvr_diag_vals) {
+   reg_pairs = xcvr_diag_vals->reg_pairs;
+   num_regs = xcvr_diag_vals->num_regs;
+   for (i = 0; i < inst->num_lanes; i++) {
+   regmap = cdns_phy->regmap_tx_lane_cdb[i + inst->mlane];
+   for (j = 0; j < num_regs; j++)
+   regmap_write(regmap, reg_pairs[j].off,
+reg_pairs[j].val);
+   }
+   }
+
/* PMA common registers configurations */
cmn_vals = init_data->cmn_vals[phy_type][TYPE_NONE][ssc];
if (cmn_vals) {
@@ -2646,6 +2670,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
.reg_offset_shift = 0x2,
.link_cmn_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2674,6 +2703,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
},
.xcvr_diag_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _sgmii_xcvr_diag_ln_vals,
@@ -2806,6 +2840,11 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
.reg_offset_shift = 0x1,
.link_cmn_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2834,6 +2873,11 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
},
.xcvr_diag_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _sgmii_xcvr_diag_ln_vals,
-- 
2.26.1



[PATCH v2 09/13] phy: cadence-torrent: Configure PHY_PLL_CFG as part of link_cmn_vals

2020-08-27 Thread Swapnil Jakhade
Include PHY_PLL_CFG as a first register value to configure in
link_cmn_vals array values.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index eda3839762cb..d678e9b37409 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1830,7 +1830,14 @@ static int cdns_torrent_phy_init(struct phy *phy)
reg_pairs = link_cmn_vals->reg_pairs;
num_regs = link_cmn_vals->num_regs;
regmap = cdns_phy->regmap_common_cdb;
-   for (i = 0; i < num_regs; i++)
+
+   /**
+* First array value in link_cmn_vals must be of
+* PHY_PLL_CFG register
+*/
+   regmap_field_write(cdns_phy->phy_pll_cfg, reg_pairs[0].val);
+
+   for (i = 1; i < num_regs; i++)
regmap_write(regmap, reg_pairs[i].off,
 reg_pairs[i].val);
}
@@ -1907,8 +1914,6 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
phy_t1 = cdns_phy->phys[0].phy_type;
phy_t2 = cdns_phy->phys[1].phy_type;
 
-   regmap_field_write(cdns_phy->phy_pll_cfg, 0x0003);
-
/**
 * First configure the PHY for first link with phy_t1. Get the array
 * values as [phy_t1][phy_t2][ssc].
@@ -1944,7 +1949,15 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
reg_pairs = link_cmn_vals->reg_pairs;
num_regs = link_cmn_vals->num_regs;
regmap = cdns_phy->regmap_common_cdb;
-   for (i = 0; i < num_regs; i++)
+
+   /**
+* First array value in link_cmn_vals must be of
+* PHY_PLL_CFG register
+*/
+   regmap_field_write(cdns_phy->phy_pll_cfg,
+  reg_pairs[0].val);
+
+   for (i = 1; i < num_regs; i++)
regmap_write(regmap, reg_pairs[i].off,
 reg_pairs[i].val);
}
@@ -2283,6 +2296,7 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
 
 /* PCIe and SGMII/QSGMII Unique SSC link configuration */
 static struct cdns_reg_pairs pcie_sgmii_link_cmn_regs[] = {
+   {0x0003, PHY_PLL_CFG},
{0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0},
{0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1},
{0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0}
-- 
2.26.1



[PATCH v2 07/13] phy: cadence-torrent: Add clk changes for multilink configuration

2020-08-27 Thread Swapnil Jakhade
Prepare and enable clock in probe instead of phy_init.
Also, remove phy_exit callback.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 41 ++-
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 56673806812f..9a87ee39a15a 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -273,7 +273,6 @@ enum phy_powerstate {
 };
 
 static int cdns_torrent_phy_init(struct phy *phy);
-static int cdns_torrent_phy_exit(struct phy *phy);
 static int cdns_torrent_dp_init(struct phy *phy);
 static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
   u32 num_lanes);
@@ -305,7 +304,6 @@ static int cdns_torrent_phy_off(struct phy *phy);
 
 static const struct phy_ops cdns_torrent_phy_ops = {
.init   = cdns_torrent_phy_init,
-   .exit   = cdns_torrent_phy_exit,
.configure  = cdns_torrent_dp_configure,
.power_on   = cdns_torrent_phy_on,
.power_off  = cdns_torrent_phy_off,
@@ -977,14 +975,6 @@ static int cdns_torrent_dp_init(struct phy *phy)
return ret;
 }
 
-static int cdns_torrent_phy_exit(struct phy *phy)
-{
-   struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
-
-   clk_disable_unprepare(cdns_phy->clk);
-   return 0;
-}
-
 static
 int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
 {
@@ -1825,20 +1815,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_reg_pairs *reg_pairs;
struct regmap *regmap;
u32 num_regs;
-   int ret, i, j;
-
-   ret = clk_prepare_enable(cdns_phy->clk);
-   if (ret) {
-   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
-   return ret;
-   }
-
-   cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
-   if (!(cdns_phy->ref_clk_rate)) {
-   dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
-   clk_disable_unprepare(cdns_phy->clk);
-   return -EINVAL;
-   }
+   int i, j;
 
if (cdns_phy->nsubnodes > 1)
return 0;
@@ -2072,6 +2049,19 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
if (ret)
return ret;
 
+   ret = clk_prepare_enable(cdns_phy->clk);
+   if (ret) {
+   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+   return ret;
+   }
+
+   cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
+   if (!(cdns_phy->ref_clk_rate)) {
+   dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+   clk_disable_unprepare(cdns_phy->clk);
+   return -EINVAL;
+   }
+
/* Enable APB */
reset_control_deassert(cdns_phy->apb_rst);
 
@@ -2246,6 +2236,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
reset_control_put(cdns_phy->phys[i].lnk_rst);
of_node_put(child);
reset_control_assert(cdns_phy->apb_rst);
+   clk_disable_unprepare(cdns_phy->clk);
return ret;
 }
 
@@ -2261,6 +2252,8 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
reset_control_put(cdns_phy->phys[i].lnk_rst);
}
 
+   clk_disable_unprepare(cdns_phy->clk);
+
return 0;
 }
 
-- 
2.26.1



[PATCH v2 12/13] phy: cadence-torrent: Add PCIe + USB multilink configuration

2020-08-27 Thread Swapnil Jakhade
Add PCIe + USB Unique SSC multilink configuration sequences.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 216 ++
 1 file changed, 216 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index a444184acca3..d2b9d1396be6 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1938,6 +1938,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type;
+   struct cdns_torrent_vals *pcs_cmn_vals;
int i, j, node, mlane, num_lanes, ret;
struct cdns_reg_pairs *reg_pairs;
enum cdns_torrent_ssc_mode ssc;
@@ -2011,6 +2012,17 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
}
}
 
+   /* 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 = cdns_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 */
cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc];
if (cmn_vals) {
@@ -2334,6 +2346,100 @@ static int cdns_torrent_phy_remove(struct 
platform_device *pdev)
return 0;
 }
 
+/* PCIe and USB Unique SSC link configuration */
+static struct cdns_reg_pairs pcie_usb_link_cmn_regs[] = {
+   {0x0003, PHY_PLL_CFG},
+   {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0},
+   {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1},
+   {0x8600, CMN_PDIAG_PLL1_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs pcie_usb_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x0012, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs usb_pcie_xcvr_diag_ln_regs[] = {
+   {0x0011, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x00C9, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals pcie_usb_link_cmn_vals = {
+   .reg_pairs = pcie_usb_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(pcie_usb_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals pcie_usb_xcvr_diag_ln_vals = {
+   .reg_pairs = pcie_usb_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(pcie_usb_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals usb_pcie_xcvr_diag_ln_vals = {
+   .reg_pairs = usb_pcie_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(usb_pcie_xcvr_diag_ln_regs),
+};
+
+/* USB 100 MHz Ref clk, internal SSC */
+static struct cdns_reg_pairs usb_100_int_ssc_cmn_regs[] = {
+   {0x0004, CMN_PLL0_DSM_DIAG_M0},
+   {0x0004, CMN_PLL0_DSM_DIAG_M1},
+   {0x0004, CMN_PLL1_DSM_DIAG_M0},
+   {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0},
+   {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M1},
+   {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0},
+   {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0},
+   {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M1},
+   {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0},
+   {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0},
+   {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M1},
+   {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0},
+   {0x0064, CMN_PLL0_INTDIV_M0},
+   {0x0050, CMN_PLL0_INTDIV_M1},
+   {0x0064, CMN_PLL1_INTDIV_M0},
+   {0x0002, CMN_PLL0_FRACDIVH_M0},
+   {0x0002, CMN_PLL0_FRACDIVH_M1},
+   {0x0002, CMN_PLL1_FRACDIVH_M0},
+   {0x0044, CMN_PLL0_HIGH_THR_M0},
+   {0x0036, CMN_PLL0_HIGH_THR_M1},
+   {0x0044, CMN_PLL1_HIGH_THR_M0},
+   {0x0002, CMN_PDIAG_PLL0_CTRL_M0},
+   {0x0002, CMN_PDIAG_PLL0_CTRL_M1},
+   {0x0002, CMN_PDIAG_PLL1_CTRL_M0},
+   {0x0001, CMN_PLL0_SS_CTRL1_M0},
+   {0x0001, CMN_PLL0_SS_CTRL1_M1},
+   {0x0001, CMN_PLL1_SS_CTRL1_M0},
+   {0x011B, CMN_PLL0_SS_CTRL2_M0},
+   {0x011B, CMN_PLL0_SS_CTRL2_M1},
+   {0x011B, CMN_PLL1_SS_CTRL2_M0},
+   {0x006E, CMN_PLL0_SS_CTRL3_M0},
+   {0x0058, CMN_PLL0_SS_CTRL3_M1},
+   {0x006E, CMN_PLL1_SS_CTRL3_M0},
+   {0x000E, CMN_PLL0_SS_CTRL4_M0},
+   {0x0012, CMN_PLL0_SS_CTRL4_M1},
+   {0x000E, CMN_PLL1_SS_CTRL4_M0},
+   {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START},
+   {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
+   {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
+   {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
+   {0x0003, CMN_PLL0_VCOCAL_TCTRL},
+   {0x0003, CMN_PLL1_VCOCAL_TCTRL

[PATCH v2 13/13] phy: cadence-torrent: Add USB + SGMII/QSGMII multilink configuration

2020-08-27 Thread Swapnil Jakhade
Add USB + SGMII/QSGMII multilink configuration sequences.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 254 ++
 1 file changed, 254 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index d2b9d1396be6..c22594a26c40 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -2346,6 +2346,40 @@ static int cdns_torrent_phy_remove(struct 
platform_device *pdev)
return 0;
 }
 
+/* USB and SGMII/QSGMII link configuration */
+static struct cdns_reg_pairs usb_sgmii_link_cmn_regs[] = {
+   {0x0002, PHY_PLL_CFG},
+   {0x8600, CMN_PDIAG_PLL0_CLK_SEL_M0},
+   {0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs usb_sgmii_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x0041, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs sgmii_usb_xcvr_diag_ln_regs[] = {
+   {0x0011, XCVR_DIAG_HSCLK_SEL},
+   {0x0003, XCVR_DIAG_HSCLK_DIV},
+   {0x009B, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals usb_sgmii_link_cmn_vals = {
+   .reg_pairs = usb_sgmii_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(usb_sgmii_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals usb_sgmii_xcvr_diag_ln_vals = {
+   .reg_pairs = usb_sgmii_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(usb_sgmii_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals sgmii_usb_xcvr_diag_ln_vals = {
+   .reg_pairs = sgmii_usb_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(sgmii_usb_xcvr_diag_ln_regs),
+};
+
 /* PCIe and USB Unique SSC link configuration */
 static struct cdns_reg_pairs pcie_usb_link_cmn_regs[] = {
{0x0003, PHY_PLL_CFG},
@@ -3019,6 +3053,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
[INTERNAL_SSC] = _sgmii_link_cmn_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
@@ -3029,6 +3068,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
[INTERNAL_SSC] = _sgmii_link_cmn_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
[TYPE_USB] = {
[TYPE_NONE] = {
@@ -3041,6 +3085,16 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _usb_link_cmn_vals,
[INTERNAL_SSC] = _usb_link_cmn_vals,
},
+   [TYPE_SGMII] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
+   [TYPE_QSGMII] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
},
.xcvr_diag_vals = {
@@ -3075,6 +3129,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
[INTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _usb_xcvr_diag_ln_vals,
+   [EXTERNAL_SSC] = _usb_xcvr_diag_ln_vals,
+   [INTERNAL_SSC] = _usb_xcvr_diag_ln_vals,
+   },
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
@@ -3085,6 +3144,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
[INTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _usb_xcvr_diag_ln_vals,
+   [EXTERNAL_SSC] = _usb_xcvr_diag_ln_vals

[PATCH v2 11/13] phy: cadence-torrent: Add single link USB register sequences

2020-08-27 Thread Swapnil Jakhade
Add support for single link USB configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 260 +-
 1 file changed, 259 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 5bc9bbddcc9c..a444184acca3 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -29,7 +29,7 @@
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
 #define NUM_SSC_MODE   3
-#define NUM_PHY_TYPE   5
+#define NUM_PHY_TYPE   6
 
 #define POLL_TIMEOUT_US5000
 #define PLL_LOCK_TIMEOUT   10
@@ -82,6 +82,8 @@
 #define CMN_PLLSM0_PLLLOCK_TMR 0x002CU
 #define CMN_PLLSM1_PLLPRE_TMR  0x0032U
 #define CMN_PLLSM1_PLLLOCK_TMR 0x0034U
+#define CMN_CDIAG_CDB_PWRI_OVRD0x0041U
+#define CMN_CDIAG_XCVRC_PWRI_OVRD  0x0047U
 #define CMN_BGCAL_INIT_TMR 0x0064U
 #define CMN_BGCAL_ITER_TMR 0x0065U
 #define CMN_IBCAL_INIT_TMR 0x0074U
@@ -159,13 +161,16 @@
 /* PMA TX Lane registers */
 #define TX_TXCC_CTRL   0x0040U
 #define TX_TXCC_CPOST_MULT_00  0x004CU
+#define TX_TXCC_CPOST_MULT_01  0x004DU
 #define TX_TXCC_MGNFS_MULT_000 0x0050U
 #define DRV_DIAG_TX_DRV0x00C6U
 #define XCVR_DIAG_PLLDRC_CTRL  0x00E5U
 #define XCVR_DIAG_HSCLK_SEL0x00E6U
 #define XCVR_DIAG_HSCLK_DIV0x00E7U
 #define XCVR_DIAG_BIDI_CTRL0x00EAU
+#define XCVR_DIAG_PSC_OVRD 0x00EBU
 #define TX_PSC_A0  0x0100U
+#define TX_PSC_A1  0x0101U
 #define TX_PSC_A2  0x0102U
 #define TX_PSC_A3  0x0103U
 #define TX_RCVDET_ST_TMR   0x0123U
@@ -174,27 +179,37 @@
 
 /* PMA RX Lane registers */
 #define RX_PSC_A0  0xU
+#define RX_PSC_A1  0x0001U
 #define RX_PSC_A2  0x0002U
 #define RX_PSC_A3  0x0003U
 #define RX_PSC_CAL 0x0006U
 #define RX_CDRLF_CNFG  0x0080U
+#define RX_CDRLF_CNFG3 0x0082U
+#define RX_SIGDET_HL_FILT_TMR  0x0090U
 #define RX_REE_GCSM1_CTRL  0x0108U
 #define RX_REE_GCSM1_EQENM_PH1 0x0109U
 #define RX_REE_GCSM1_EQENM_PH2 0x010AU
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
+#define RX_REE_ATTEN_THR   0x0149U
 #define RX_REE_TAP1_CLIP   0x0171U
 #define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_REE_SMGM_CTRL1  0x0177U
+#define RX_REE_SMGM_CTRL2  0x0178U
 #define RX_DIAG_DFE_CTRL   0x01E0U
 #define RX_DIAG_DFE_AMP_TUNE_2 0x01E2U
 #define RX_DIAG_DFE_AMP_TUNE_3 0x01E3U
 #define RX_DIAG_NQST_CTRL  0x01E5U
+#define RX_DIAG_SIGDET_TUNE0x01E8U
 #define RX_DIAG_PI_RATE0x01F4U
 #define RX_DIAG_PI_CAP 0x01F5U
 #define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
 #define PHY_PLL_CFG0x000EU
+#define PHY_PIPE_USB3_GEN2_PRE_CFG00x0020U
+#define PHY_PIPE_USB3_GEN2_POST_CFG0   0x0022U
+#define PHY_PIPE_USB3_GEN2_POST_CFG1   0x0023U
 
 /* PHY PMA common registers */
 #define PHY_PMA_CMN_CTRL1  0xU
@@ -222,6 +237,7 @@ enum cdns_torrent_phy_type {
TYPE_PCIE,
TYPE_SGMII,
TYPE_QSGMII,
+   TYPE_USB,
 };
 
 enum cdns_torrent_ssc_mode {
@@ -327,6 +343,8 @@ struct cdns_torrent_data {
   [NUM_SSC_MODE];
struct cdns_torrent_vals *xcvr_diag_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
[NUM_SSC_MODE];
+   struct cdns_torrent_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
  [NUM_SSC_MODE];
struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
@@ -1813,6 +1831,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
enum cdns_torrent_ssc_mode ssc = inst->ssc_mode;
+   struct cdns_torrent_vals *pcs_cmn_vals;
struct cdns_reg_pairs *reg_pairs;
struct regmap *regmap;
u32 num_regs;
@@ -1861,6 +1880,17 @@ static int cdns_torrent_phy_init(struct phy *phy)
}
}
 
+   /* 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;
+   

[PATCH v2 00/13] PHY: Add support for multilink configurations in Cadence Torrent PHY driver

2020-08-27 Thread Swapnil Jakhade
Cadence Torrent PHY is a multiprotocol PHY supporting different multilink
PHY configurations including DisplayPort, PCIe, USB, SGMII, QSGMII etc.
This patch series extends functionality of Torrent PHY driver to support
following configurations:
- Single link PCIe configuration
- PCIe + SGMII/QSGMII Unique SSC multilink configuration
- Single link SGMII/QSGMII configuration
- Single link USB configuration
- PCIe + USB Unique SSC multilink configuration
- USB + SGMII/QSGMII multilink configuration

The changes have been validated on TI J7200 platform.

This patch series is dependent on [1] and [2] and should be applied on
top of these.

[1] https://lkml.org/lkml/2020/8/24/1586

[2] https://lkml.org/lkml/2020/8/27/667

Version History:

v2:
   - Rebased on latest PHY next and new PHY patch series [1] and [2]

Swapnil Jakhade (13):
  phy: cadence-torrent: Add single link PCIe support
  phy: cadence-torrent: Check cmn_ready assertion during PHY power on
  phy: cadence-torrent: Add PHY APB reset support
  dt-bindings: phy: Add PHY_TYPE_QSGMII definition
  phy: cadence-torrent: Add support for PHY multilink configuration
  phy: cadence-torrent: Update PHY reset for multilink configuration
  phy: cadence-torrent: Add clk changes for multilink configuration
  phy: cadence-torrent: Add PHY link configuration sequences for single
link
  phy: cadence-torrent: Configure PHY_PLL_CFG as part of link_cmn_vals
  phy: cadence-torrent: Add single link SGMII/QSGMII register sequences
  phy: cadence-torrent: Add single link USB register sequences
  phy: cadence-torrent: Add PCIe + USB multilink configuration
  phy: cadence-torrent: Add USB + SGMII/QSGMII multilink configuration

 drivers/phy/cadence/phy-cadence-torrent.c | 1975 -
 include/dt-bindings/phy/phy.h |1 +
 2 files changed, 1934 insertions(+), 42 deletions(-)

-- 
2.26.1



[PATCH v2 02/13] phy: cadence-torrent: Check cmn_ready assertion during PHY power on

2020-08-27 Thread Swapnil Jakhade
Check if cmn_ready is set after both PLL0 and PLL1 are locked.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 31 ++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index fcd1a2617f0a..af307af2f221 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -32,6 +32,7 @@
 #define NUM_PHY_TYPE   2
 
 #define POLL_TIMEOUT_US5000
+#define PLL_LOCK_TIMEOUT   10
 
 #define TORRENT_COMMON_CDB_OFFSET  0x0
 
@@ -183,12 +184,16 @@
 #define PHY_PLL_CFG0x000EU
 
 /* PHY PMA common registers */
+#define PHY_PMA_CMN_CTRL1  0xU
 #define PHY_PMA_CMN_CTRL2  0x0001U
 #define PHY_PMA_PLL_RAW_CTRL   0x0003U
 
 static const struct reg_field phy_pll_cfg =
REG_FIELD(PHY_PLL_CFG, 0, 1);
 
+static const struct reg_field phy_pma_cmn_ctrl_1 =
+   REG_FIELD(PHY_PMA_CMN_CTRL1, 0, 0);
+
 static const struct reg_field phy_pma_cmn_ctrl_2 =
REG_FIELD(PHY_PMA_CMN_CTRL2, 0, 7);
 
@@ -237,6 +242,7 @@ struct cdns_torrent_phy {
struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES];
struct regmap *regmap_dptx_phy_reg;
struct regmap_field *phy_pll_cfg;
+   struct regmap_field *phy_pma_cmn_ctrl_1;
struct regmap_field *phy_pma_cmn_ctrl_2;
struct regmap_field *phy_pma_pll_raw_ctrl;
struct regmap_field *phy_reset_ctrl;
@@ -1570,6 +1576,7 @@ static int cdns_torrent_phy_on(struct phy *phy)
 {
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+   u32 read_val;
int ret;
 
/* Take the PHY out of reset */
@@ -1578,7 +1585,21 @@ static int cdns_torrent_phy_on(struct phy *phy)
return ret;
 
/* Take the PHY lane group out of reset */
-   return reset_control_deassert(inst->lnk_rst);
+   reset_control_deassert(inst->lnk_rst);
+
+   /*
+* Wait for cmn_ready assertion
+* PHY_PMA_CMN_CTRL1[0] == 1
+*/
+   ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_1,
+read_val, read_val, 1000,
+PLL_LOCK_TIMEOUT);
+   if (ret) {
+   dev_err(cdns_phy->dev, "Timeout waiting for CMN ready\n");
+   return ret;
+   }
+
+   return 0;
 }
 
 static int cdns_torrent_phy_off(struct phy *phy)
@@ -1643,6 +1664,14 @@ static int cdns_torrent_regfield_init(struct 
cdns_torrent_phy *cdns_phy)
}
cdns_phy->phy_pll_cfg = field;
 
+   regmap = cdns_phy->regmap_phy_pma_common_cdb;
+   field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_1);
+   if (IS_ERR(field)) {
+   dev_err(dev, "PHY_PMA_CMN_CTRL1 reg field init failed\n");
+   return PTR_ERR(field);
+   }
+   cdns_phy->phy_pma_cmn_ctrl_1 = field;
+
regmap = cdns_phy->regmap_phy_pma_common_cdb;
field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_2);
if (IS_ERR(field)) {
-- 
2.26.1



[PATCH v2 10/13] phy: cadence-torrent: Add single link SGMII/QSGMII register sequences

2020-08-27 Thread Swapnil Jakhade
Add support for single link SGMII/QSGMII configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 89 +++
 1 file changed, 89 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index d678e9b37409..5bc9bbddcc9c 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1824,6 +1824,13 @@ static int cdns_torrent_phy_init(struct phy *phy)
if (phy_type == TYPE_DP)
return cdns_torrent_dp_init(phy);
 
+   /**
+* Spread spectrum generation is not required or supported
+* for SGMII/QSGMII
+*/
+   if (phy_type == TYPE_SGMII || phy_type == TYPE_QSGMII)
+   ssc = NO_SSC;
+
/* PHY configuration specific registers for single link */
link_cmn_vals = init_data->link_cmn_vals[phy_type][TYPE_NONE][ssc];
if (link_cmn_vals) {
@@ -2543,6 +2550,28 @@ static struct cdns_torrent_vals 
qsgmii_100_int_ssc_cmn_vals = {
.num_regs = ARRAY_SIZE(qsgmii_100_int_ssc_cmn_regs),
 };
 
+/* Single SGMII/QSGMII link configuration */
+static struct cdns_reg_pairs sl_sgmii_link_cmn_regs[] = {
+   {0x, PHY_PLL_CFG},
+   {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs sl_sgmii_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0003, XCVR_DIAG_HSCLK_DIV},
+   {0x0013, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals sl_sgmii_link_cmn_vals = {
+   .reg_pairs = sl_sgmii_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(sl_sgmii_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals sl_sgmii_xcvr_diag_ln_vals = {
+   .reg_pairs = sl_sgmii_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(sl_sgmii_xcvr_diag_ln_regs),
+};
+
 /* Multi link PCIe, 100 MHz Ref clk, internal SSC */
 static struct cdns_reg_pairs pcie_100_int_ssc_cmn_regs[] = {
{0x0004, CMN_PLL0_DSM_DIAG_M0},
@@ -2701,6 +2730,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2708,6 +2740,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2734,6 +2769,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_xcvr_diag_ln_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _pcie_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
@@ -2741,6 +2779,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_xcvr_diag_ln_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _pcie_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
@@ -2767,6 +2808,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _100_no_ssc_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _100_no_ssc_cmn_vals,
[EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
@@ -2774,6 +2818,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _100_no_ssc_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _100_no_ssc_cmn_vals,
[EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
@@ -2800,6 +2847,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SG

[PATCH v2 01/13] phy: cadence-torrent: Add single link PCIe support

2020-08-27 Thread Swapnil Jakhade
Add single link PCIe register sequences in Torrent PHY driver.
Also, add support for getting SSC type from DT.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 296 +++---
 1 file changed, 266 insertions(+), 30 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index ed2140691077..fcd1a2617f0a 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -28,6 +28,9 @@
 #define MAX_NUM_LANES  4
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
+#define NUM_SSC_MODE   3
+#define NUM_PHY_TYPE   2
+
 #define POLL_TIMEOUT_US5000
 
 #define TORRENT_COMMON_CDB_OFFSET  0x0
@@ -98,6 +101,14 @@
 #define CMN_PLL0_LOCK_REFCNT_START  0x009CU
 #define CMN_PLL0_LOCK_PLLCNT_START 0x009EU
 #define CMN_PLL0_LOCK_PLLCNT_THR0x009FU
+#define CMN_PLL0_INTDIV_M1 0x00A0U
+#define CMN_PLL0_FRACDIVH_M1   0x00A2U
+#define CMN_PLL0_HIGH_THR_M1   0x00A3U
+#define CMN_PLL0_DSM_DIAG_M1   0x00A4U
+#define CMN_PLL0_SS_CTRL1_M1   0x00A8U
+#define CMN_PLL0_SS_CTRL2_M1   0x00A9U
+#define CMN_PLL0_SS_CTRL3_M1   0x00AAU
+#define CMN_PLL0_SS_CTRL4_M1   0x00ABU
 #define CMN_PLL1_VCOCAL_TCTRL  0x00C2U
 #define CMN_PLL1_VCOCAL_INIT_TMR   0x00C4U
 #define CMN_PLL1_VCOCAL_ITER_TMR   0x00C5U
@@ -130,8 +141,10 @@
 #define CMN_PDIAG_PLL0_CP_PADJ_M0  0x01A4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M0  0x01A5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M00x01A6U
+#define CMN_PDIAG_PLL0_CTRL_M1 0x01B0U
 #define CMN_PDIAG_PLL0_CP_PADJ_M1  0x01B4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M1  0x01B5U
+#define CMN_PDIAG_PLL0_FILT_PADJ_M10x01B6U
 #define CMN_PDIAG_PLL1_CTRL_M0 0x01C0U
 #define CMN_PDIAG_PLL1_CLK_SEL_M0  0x01C1U
 #define CMN_PDIAG_PLL1_CP_PADJ_M0  0x01C4U
@@ -162,6 +175,9 @@
 #define RX_REE_GCSM1_CTRL  0x0108U
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
+#define RX_REE_TAP1_CLIP   0x0171U
+#define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
 #define PHY_PLL_CFG0x000EU
@@ -182,12 +198,24 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
 static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
+enum cdns_torrent_phy_type {
+   TYPE_DP,
+   TYPE_PCIE
+};
+
+enum cdns_torrent_ssc_mode {
+   NO_SSC,
+   EXTERNAL_SSC,
+   INTERNAL_SSC
+};
+
 struct cdns_torrent_inst {
struct phy *phy;
u32 mlane;
-   u32 phy_type;
+   enum cdns_torrent_phy_type phy_type;
u32 num_lanes;
struct reset_control *lnk_rst;
+   enum cdns_torrent_ssc_mode ssc_mode;
 };
 
 struct cdns_torrent_phy {
@@ -221,8 +249,9 @@ enum phy_powerstate {
POWERSTATE_A3 = 3,
 };
 
+static int cdns_torrent_phy_init(struct phy *phy);
+static int cdns_torrent_phy_exit(struct phy *phy);
 static int cdns_torrent_dp_init(struct phy *phy);
-static int cdns_torrent_dp_exit(struct phy *phy);
 static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
   u32 num_lanes);
 static
@@ -252,17 +281,30 @@ static int cdns_torrent_phy_on(struct phy *phy);
 static int cdns_torrent_phy_off(struct phy *phy);
 
 static const struct phy_ops cdns_torrent_phy_ops = {
-   .init   = cdns_torrent_dp_init,
-   .exit   = cdns_torrent_dp_exit,
+   .init   = cdns_torrent_phy_init,
+   .exit   = cdns_torrent_phy_exit,
.configure  = cdns_torrent_dp_configure,
.power_on   = cdns_torrent_phy_on,
.power_off  = cdns_torrent_phy_off,
.owner  = THIS_MODULE,
 };
 
+struct cdns_reg_pairs {
+   u32 val;
+   u32 off;
+};
+
+struct cdns_torrent_vals {
+   struct cdns_reg_pairs *reg_pairs;
+   u32 num_regs;
+};
+
 struct cdns_torrent_data {
-   u8 block_offset_shift;
-   u8 reg_offset_shift;
+   u8 block_offset_shift;
+   u8 reg_offset_shift;
+   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
 };
 
 struct cdns_regmap_cdb_context {
@@ -846,19 +888,6 @@ static int cdns_torrent_dp_init(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
 
-   ret = clk_prepare_enable(cdns_phy->clk);
-   if (ret) {
-   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
-   return ret;
-   }
-
-   cdns_phy->ref_clk_rate = c

[PATCH v2 06/13] phy: cadence-torrent: Update PHY reset for multilink configuration

2020-08-27 Thread Swapnil Jakhade
For multilink configuration, deassert PHY and link reset after PHY
registers are configured in probe and only check link status in
power_on callback.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 28 +--
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index fb49abc05445..56673806812f 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1603,13 +1603,15 @@ static int cdns_torrent_phy_on(struct phy *phy)
u32 read_val;
int ret;
 
-   /* Take the PHY out of reset */
-   ret = reset_control_deassert(cdns_phy->phy_rst);
-   if (ret)
-   return ret;
+   if (cdns_phy->nsubnodes == 1) {
+   /* Take the PHY lane group out of reset */
+   reset_control_deassert(inst->lnk_rst);
 
-   /* Take the PHY lane group out of reset */
-   reset_control_deassert(inst->lnk_rst);
+   /* Take the PHY out of reset */
+   ret = reset_control_deassert(cdns_phy->phy_rst);
+   if (ret)
+   return ret;
+   }
 
/*
 * Wait for cmn_ready assertion
@@ -1623,6 +1625,8 @@ static int cdns_torrent_phy_on(struct phy *phy)
return ret;
}
 
+   mdelay(10);
+
return 0;
 }
 
@@ -1632,6 +1636,9 @@ static int cdns_torrent_phy_off(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
int ret;
 
+   if (cdns_phy->nsubnodes != 1)
+   return 0;
+
ret = reset_control_assert(cdns_phy->phy_rst);
if (ret)
return ret;
@@ -1886,7 +1893,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type;
-   int i, j, node, mlane, num_lanes;
+   int i, j, node, mlane, num_lanes, ret;
struct cdns_reg_pairs *reg_pairs;
enum cdns_torrent_ssc_mode ssc;
struct regmap *regmap;
@@ -1989,8 +1996,15 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
 reg_pairs[j].val);
}
}
+
+   reset_control_deassert(cdns_phy->phys[node].lnk_rst);
}
 
+   /* Take the PHY out of reset */
+   ret = reset_control_deassert(cdns_phy->phy_rst);
+   if (ret)
+   return ret;
+
return 0;
 }
 
-- 
2.26.1



[PATCH v2 05/13] phy: cadence-torrent: Add support for PHY multilink configuration

2020-08-27 Thread Swapnil Jakhade
Added support for multilink configuration of Torrent PHY. Currently,
maximum two links are supported. In case of multilink configuration,
PHY needs to be configured for both the protocols simultaneously at
the beginning as per the requirement of Torrent PHY.
Also, register sequences for PCIe + SGMII/QSGMII Unique SSC PHY multilink
configurations are added.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 783 +-
 1 file changed, 757 insertions(+), 26 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 3038b50c7b12..fb49abc05445 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -29,7 +29,7 @@
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
 #define NUM_SSC_MODE   3
-#define NUM_PHY_TYPE   2
+#define NUM_PHY_TYPE   5
 
 #define POLL_TIMEOUT_US5000
 #define PLL_LOCK_TIMEOUT   10
@@ -127,8 +127,10 @@
 #define CMN_PLL1_LOCK_REFCNT_START  0x00DCU
 #define CMN_PLL1_LOCK_PLLCNT_START 0x00DEU
 #define CMN_PLL1_LOCK_PLLCNT_THR0x00DFU
+#define CMN_TXPUCAL_TUNE   0x0103U
 #define CMN_TXPUCAL_INIT_TMR   0x0104U
 #define CMN_TXPUCAL_ITER_TMR   0x0105U
+#define CMN_TXPDCAL_TUNE   0x010BU
 #define CMN_TXPDCAL_INIT_TMR   0x010CU
 #define CMN_TXPDCAL_ITER_TMR   0x010DU
 #define CMN_RXCAL_INIT_TMR 0x0114U
@@ -143,6 +145,7 @@
 #define CMN_PDIAG_PLL0_CP_IADJ_M0  0x01A5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M00x01A6U
 #define CMN_PDIAG_PLL0_CTRL_M1 0x01B0U
+#define CMN_PDIAG_PLL0_CLK_SEL_M1  0x01B1U
 #define CMN_PDIAG_PLL0_CP_PADJ_M1  0x01B4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M1  0x01B5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M10x01B6U
@@ -151,6 +154,7 @@
 #define CMN_PDIAG_PLL1_CP_PADJ_M0  0x01C4U
 #define CMN_PDIAG_PLL1_CP_IADJ_M0  0x01C5U
 #define CMN_PDIAG_PLL1_FILT_PADJ_M00x01C6U
+#define CMN_DIAG_BIAS_OVRD10x01E1U
 
 /* PMA TX Lane registers */
 #define TX_TXCC_CTRL   0x0040U
@@ -173,11 +177,20 @@
 #define RX_PSC_A2  0x0002U
 #define RX_PSC_A3  0x0003U
 #define RX_PSC_CAL 0x0006U
+#define RX_CDRLF_CNFG  0x0080U
 #define RX_REE_GCSM1_CTRL  0x0108U
+#define RX_REE_GCSM1_EQENM_PH1 0x0109U
+#define RX_REE_GCSM1_EQENM_PH2 0x010AU
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
 #define RX_REE_TAP1_CLIP   0x0171U
 #define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_DIAG_DFE_CTRL   0x01E0U
+#define RX_DIAG_DFE_AMP_TUNE_2 0x01E2U
+#define RX_DIAG_DFE_AMP_TUNE_3 0x01E3U
+#define RX_DIAG_NQST_CTRL  0x01E5U
+#define RX_DIAG_PI_RATE0x01F4U
+#define RX_DIAG_PI_CAP 0x01F5U
 #define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
@@ -204,8 +217,11 @@ static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
 enum cdns_torrent_phy_type {
+   TYPE_NONE,
TYPE_DP,
-   TYPE_PCIE
+   TYPE_PCIE,
+   TYPE_SGMII,
+   TYPE_QSGMII,
 };
 
 enum cdns_torrent_ssc_mode {
@@ -309,9 +325,16 @@ struct cdns_torrent_vals {
 struct cdns_torrent_data {
u8 block_offset_shift;
u8 reg_offset_shift;
-   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
-   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
-   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *link_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+  [NUM_SSC_MODE];
+   struct cdns_torrent_vals *xcvr_diag_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
+   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
+   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
+   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
 };
 
 struct cdns_regmap_cdb_context {
@@ -1787,6 +1810,7 @@ static int cdns_torrent_regmap_init(struct 
cdns_torrent_phy *cdns_phy)
 static int cdns_torrent_phy_init(struct phy *phy)
 {
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+   const struct cdns_torrent_data *init_data = cdns_phy->init_data;
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
@@ -1809,11

[PATCH v2 04/13] dt-bindings: phy: Add PHY_TYPE_QSGMII definition

2020-08-27 Thread Swapnil Jakhade
Add definition for QSGMII phy type.

Signed-off-by: Swapnil Jakhade 
Acked-by: Rob Herring 
---
 include/dt-bindings/phy/phy.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
index 36e8c241cf48..887a31b250a8 100644
--- a/include/dt-bindings/phy/phy.h
+++ b/include/dt-bindings/phy/phy.h
@@ -19,5 +19,6 @@
 #define PHY_TYPE_DP6
 #define PHY_TYPE_XPCS  7
 #define PHY_TYPE_SGMII 8
+#define PHY_TYPE_QSGMII9
 
 #endif /* _DT_BINDINGS_PHY */
-- 
2.26.1



[PATCH v2 03/13] phy: cadence-torrent: Add PHY APB reset support

2020-08-27 Thread Swapnil Jakhade
Add support for PHY APB reset and make it optional.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index af307af2f221..3038b50c7b12 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -228,6 +228,7 @@ struct cdns_torrent_phy {
void __iomem *sd_base; /* SD0801 registers base */
u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */
struct reset_control *phy_rst;
+   struct reset_control *apb_rst;
struct device *dev;
struct clk *clk;
unsigned long ref_clk_rate;
@@ -1884,6 +1885,13 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
return PTR_ERR(cdns_phy->phy_rst);
}
 
+   cdns_phy->apb_rst = devm_reset_control_get_optional(dev, "torrent_apb");
+   if (IS_ERR(cdns_phy->apb_rst)) {
+   dev_err(dev, "%s: failed to get apb reset\n",
+   dev->of_node->full_name);
+   return PTR_ERR(cdns_phy->apb_rst);
+   }
+
cdns_phy->clk = devm_clk_get(dev, "refclk");
if (IS_ERR(cdns_phy->clk)) {
dev_err(dev, "phy ref clock not found\n");
@@ -1908,6 +1916,9 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
if (ret)
return ret;
 
+   /* Enable APB */
+   reset_control_deassert(cdns_phy->apb_rst);
+
for_each_available_child_of_node(dev->of_node, child) {
struct phy *gphy;
 
@@ -2062,6 +2073,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
for (i = 0; i < node; i++)
reset_control_put(cdns_phy->phys[i].lnk_rst);
of_node_put(child);
+   reset_control_assert(cdns_phy->apb_rst);
return ret;
 }
 
@@ -2071,6 +2083,7 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
int i;
 
reset_control_assert(cdns_phy->phy_rst);
+   reset_control_assert(cdns_phy->apb_rst);
for (i = 0; i < cdns_phy->nsubnodes; i++) {
reset_control_assert(cdns_phy->phys[i].lnk_rst);
reset_control_put(cdns_phy->phys[i].lnk_rst);
-- 
2.26.1



[PATCH v2 1/7] phy: cadence-torrent: Use of_device_get_match_data() to get driver data

2020-08-27 Thread Swapnil Jakhade
Use of_device_get_match_data() to get driver data instead of boilerplate
code.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index eca71467c4a8..98f644ae0a07 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -183,8 +183,6 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
 static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
-static const struct of_device_id cdns_torrent_phy_of_match[];
-
 struct cdns_torrent_inst {
struct phy *phy;
u32 mlane;
@@ -203,6 +201,7 @@ struct cdns_torrent_phy {
unsigned long ref_clk_rate;
struct cdns_torrent_inst phys[MAX_NUM_LANES];
int nsubnodes;
+   const struct cdns_torrent_data *init_data;
struct regmap *regmap;
struct regmap *regmap_common_cdb;
struct regmap *regmap_phy_pcs_common_cdb;
@@ -1711,24 +1710,22 @@ static int cdns_torrent_phy_probe(struct 
platform_device *pdev)
struct device *dev = >dev;
struct phy_provider *phy_provider;
struct phy_attrs torrent_attr;
-   const struct of_device_id *match;
-   struct cdns_torrent_data *data;
+   const struct cdns_torrent_data *data;
struct device_node *child;
int ret, subnodes, node = 0, i;
 
/* Get init data for this PHY */
-   match = of_match_device(cdns_torrent_phy_of_match, dev);
-   if (!match)
+   data = of_device_get_match_data(dev);
+   if (!data)
return -EINVAL;
 
-   data = (struct cdns_torrent_data *)match->data;
-
cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
if (!cdns_phy)
return -ENOMEM;
 
dev_set_drvdata(dev, cdns_phy);
cdns_phy->dev = dev;
+   cdns_phy->init_data = data;
 
cdns_phy->phy_rst = devm_reset_control_get_exclusive_by_index(dev, 0);
if (IS_ERR(cdns_phy->phy_rst)) {
-- 
2.26.1



[PATCH v2 6/7] dt-bindings: phy: cadence-torrent: Add binding to specify SSC mode

2020-08-27 Thread Swapnil Jakhade
Add binding to specify Spread Spectrum Clocking mode used.

Signed-off-by: Swapnil Jakhade 
Reviewed-by: Rob Herring 
---
 .../bindings/phy/phy-cadence-torrent.yaml   |  9 +
 include/dt-bindings/phy/phy-cadence-torrent.h   | 13 +
 2 files changed, 22 insertions(+)
 create mode 100644 include/dt-bindings/phy/phy-cadence-torrent.h

diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml 
b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
index 4071438be2ba..a7ee19d27c19 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
@@ -87,6 +87,15 @@ patternProperties:
 enum: [1, 2, 4]
 default: 4
 
+  cdns,ssc-mode:
+description:
+  Specifies the Spread Spectrum Clocking mode used. It can be NO_SSC,
+  EXTERNAL_SSC or INTERNAL_SSC.
+  Refer include/dt-bindings/phy/phy-cadence-torrent.h for the 
constants to be used.
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [0, 1, 2]
+default: 0
+
   cdns,max-bit-rate:
 description:
   Maximum DisplayPort link bit rate to use, in Mbps
diff --git a/include/dt-bindings/phy/phy-cadence-torrent.h 
b/include/dt-bindings/phy/phy-cadence-torrent.h
new file mode 100644
index ..e387b6a95741
--- /dev/null
+++ b/include/dt-bindings/phy/phy-cadence-torrent.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides constants for Cadence Torrent SERDES.
+ */
+
+#ifndef _DT_BINDINGS_TORRENT_SERDES_H
+#define _DT_BINDINGS_TORRENT_SERDES_H
+
+#define TORRENT_SERDES_NO_SSC  0
+#define TORRENT_SERDES_EXTERNAL_SSC1
+#define TORRENT_SERDES_INTERNAL_SSC2
+
+#endif /* _DT_BINDINGS_TORRENT_SERDES_H */
-- 
2.26.1



[PATCH v2 2/7] phy: cadence-torrent: Use devm_platform_ioremap_resource() to get reg addresses

2020-08-27 Thread Swapnil Jakhade
Use devm_platform_ioremap_resource() to get register addresses instead of
boilerplate code.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 98f644ae0a07..566edf0e7937 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1705,7 +1705,6 @@ static int cdns_regmap_init_torrent_dp(struct 
cdns_torrent_phy *cdns_phy,
 
 static int cdns_torrent_phy_probe(struct platform_device *pdev)
 {
-   struct resource *regs;
struct cdns_torrent_phy *cdns_phy;
struct device *dev = >dev;
struct phy_provider *phy_provider;
@@ -1740,8 +1739,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
return PTR_ERR(cdns_phy->clk);
}
 
-   regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   cdns_phy->sd_base = devm_ioremap_resource(>dev, regs);
+   cdns_phy->sd_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(cdns_phy->sd_base))
return PTR_ERR(cdns_phy->sd_base);
 
@@ -1831,9 +1829,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
}
 
/* DPTX registers */
-   regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-   cdns_phy->base = devm_ioremap_resource(>dev,
-  regs);
+   cdns_phy->base = devm_platform_ioremap_resource(pdev, 
1);
if (IS_ERR(cdns_phy->base)) {
ret = PTR_ERR(cdns_phy->base);
goto put_child;
-- 
2.26.1



[PATCH v2 3/7] phy: cadence-torrent: Enable support for multiple subnodes

2020-08-27 Thread Swapnil Jakhade
Enable support for multiple subnodes in torrent PHY to
include multi-link combinations.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 566edf0e7937..ee633c8bf2d8 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1747,9 +1747,6 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
if (subnodes == 0) {
dev_err(dev, "No available link subnodes found\n");
return -EINVAL;
-   } else if (subnodes != 1) {
-   dev_err(dev, "Driver supports only one link subnode.\n");
-   return -EINVAL;
}
 
for_each_available_child_of_node(dev->of_node, child) {
@@ -1772,14 +1769,6 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
goto put_child;
}
 
-   if (cdns_phy->phys[node].mlane != 0) {
-   dev_err(dev,
-   "%s: Driver supports only lane-0 as master 
lane.\n",
-   child->full_name);
-   ret = -EINVAL;
-   goto put_child;
-   }
-
if (of_property_read_u32(child, "cdns,phy-type",
 _phy->phys[node].phy_type)) {
dev_err(dev, "%s: No \"cdns,phy-type\"-property.\n",
@@ -1852,10 +1841,6 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
torrent_attr.mode = PHY_MODE_DP;
 
phy_set_attrs(gphy, _attr);
-   } else {
-   dev_err(dev, "Driver supports only PHY_TYPE_DP\n");
-   ret = -ENOTSUPP;
-   goto put_child;
}
cdns_phy->phys[node].phy = gphy;
phy_set_drvdata(gphy, _phy->phys[node]);
-- 
2.26.1



[PATCH v2 5/7] phy: cadence-torrent: Check total lane count for all subnodes is within limit

2020-08-27 Thread Swapnil Jakhade
Add checking if total number of lanes for all subnodes is not greater than
number of lanes supported by PHY.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 66ae5b749385..ed2140691077 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -25,7 +25,6 @@
 #define REF_CLK_19_2MHz1920
 #define REF_CLK_25MHz  2500
 
-#define DEFAULT_NUM_LANES  4
 #define MAX_NUM_LANES  4
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
@@ -1735,6 +1734,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
const struct cdns_torrent_data *data;
struct device_node *child;
int ret, subnodes, node = 0, i;
+   u32 total_num_lanes = 0;
u8 init_dp_regmap = 0;
 
/* Get init data for this PHY */
@@ -1809,9 +1809,15 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
goto put_child;
}
 
-   cdns_phy->phys[node].num_lanes = DEFAULT_NUM_LANES;
-   of_property_read_u32(child, "cdns,num-lanes",
-_phy->phys[node].num_lanes);
+   if (of_property_read_u32(child, "cdns,num-lanes",
+_phy->phys[node].num_lanes)) {
+   dev_err(dev, "%s: No \"cdns,num-lanes\"-property.\n",
+   child->full_name);
+   ret = -EINVAL;
+   goto put_child;
+   }
+
+   total_num_lanes += cdns_phy->phys[node].num_lanes;
 
if (cdns_phy->phys[node].phy_type == PHY_TYPE_DP) {
switch (cdns_phy->phys[node].num_lanes) {
@@ -1893,6 +1899,11 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
}
cdns_phy->nsubnodes = node;
 
+   if (total_num_lanes > MAX_NUM_LANES) {
+   dev_err(dev, "Invalid lane configuration\n");
+   goto put_lnk_rst;
+   }
+
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (IS_ERR(phy_provider)) {
ret = PTR_ERR(phy_provider);
-- 
2.26.1



[PATCH v2 0/7] PHY: Prepare Cadence Torrent PHY driver to support multilink configurations

2020-08-27 Thread Swapnil Jakhade
Cadence Torrent PHY is a multiprotocol PHY supporting different multilink
PHY configurations including DisplayPort, PCIe, USB, SGMII, QSGMII etc.
Existing Torrent PHY driver supports only DisplayPort. This patch series
prepares Torrent PHY driver so that different multilink configurations can
be supported. It also updates DT bindings accordingly. This doesn't affect
ABI as Torrent PHY driver has never been functional, and therefore do not
exist in any active use case.

Support for different multilink configurations with register sequences for
protocols above will be added in a separate patch series.

This patch series is dependent on PHY attributes patch series [1].

[1] https://lkml.org/lkml/2020/8/24/1586

Version History:

v2:
   - Rebased on latest PHY next and new PHY attributes patch series [1]

Swapnil Jakhade (7):
  phy: cadence-torrent: Use of_device_get_match_data() to get driver
data
  phy: cadence-torrent: Use devm_platform_ioremap_resource() to get reg
addresses
  phy: cadence-torrent: Enable support for multiple subnodes
  phy: cadence-torrent: Add separate regmap functions for torrent and DP
  phy: cadence-torrent: Check total lane count for all subnodes is
within limit
  dt-bindings: phy: cadence-torrent: Add binding to specify SSC mode
  dt-bindings: phy: cadence-torrent: Update Torrent PHY bindings for
generic use

 .../bindings/phy/phy-cadence-torrent.yaml |  85 +++---
 drivers/phy/cadence/phy-cadence-torrent.c | 146 ++
 include/dt-bindings/phy/phy-cadence-torrent.h |  13 ++
 3 files changed, 164 insertions(+), 80 deletions(-)
 create mode 100644 include/dt-bindings/phy/phy-cadence-torrent.h

-- 
2.26.1



[PATCH v2 4/7] phy: cadence-torrent: Add separate regmap functions for torrent and DP

2020-08-27 Thread Swapnil Jakhade
Added separate functions for regmap initialization of torrent PHY
generic registers and DP specific registers.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 99 +++
 1 file changed, 66 insertions(+), 33 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index ee633c8bf2d8..66ae5b749385 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1584,7 +1584,24 @@ static struct regmap *cdns_regmap_init(struct device 
*dev, void __iomem *base,
return devm_regmap_init(dev, NULL, ctx, config);
 }
 
-static int cdns_regfield_init(struct cdns_torrent_phy *cdns_phy)
+static int cdns_torrent_dp_regfield_init(struct cdns_torrent_phy *cdns_phy)
+{
+   struct device *dev = cdns_phy->dev;
+   struct regmap_field *field;
+   struct regmap *regmap;
+
+   regmap = cdns_phy->regmap_dptx_phy_reg;
+   field = devm_regmap_field_alloc(dev, regmap, phy_reset_ctrl);
+   if (IS_ERR(field)) {
+   dev_err(dev, "PHY_RESET reg field init failed\n");
+   return PTR_ERR(field);
+   }
+   cdns_phy->phy_reset_ctrl = field;
+
+   return 0;
+}
+
+static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy)
 {
struct device *dev = cdns_phy->dev;
struct regmap_field *field;
@@ -1614,28 +1631,44 @@ static int cdns_regfield_init(struct cdns_torrent_phy 
*cdns_phy)
}
cdns_phy->phy_pma_pll_raw_ctrl = field;
 
-   regmap = cdns_phy->regmap_dptx_phy_reg;
-   field = devm_regmap_field_alloc(dev, regmap, phy_reset_ctrl);
-   if (IS_ERR(field)) {
-   dev_err(dev, "PHY_RESET reg field init failed\n");
-   return PTR_ERR(field);
+   return 0;
+}
+
+static int cdns_torrent_dp_regmap_init(struct cdns_torrent_phy *cdns_phy)
+{
+   void __iomem *base = cdns_phy->base;
+   struct device *dev = cdns_phy->dev;
+   struct regmap *regmap;
+   u8 reg_offset_shift;
+   u32 block_offset;
+
+   reg_offset_shift = cdns_phy->init_data->reg_offset_shift;
+
+   block_offset = TORRENT_DPTX_PHY_OFFSET;
+   regmap = cdns_regmap_init(dev, base, block_offset,
+ reg_offset_shift,
+ _torrent_dptx_phy_config);
+   if (IS_ERR(regmap)) {
+   dev_err(dev, "Failed to init DPTX PHY regmap\n");
+   return PTR_ERR(regmap);
}
-   cdns_phy->phy_reset_ctrl = field;
+   cdns_phy->regmap_dptx_phy_reg = regmap;
 
return 0;
 }
 
-static int cdns_regmap_init_torrent_dp(struct cdns_torrent_phy *cdns_phy,
-  void __iomem *sd_base,
-  void __iomem *base,
-  u8 block_offset_shift,
-  u8 reg_offset_shift)
+static int cdns_torrent_regmap_init(struct cdns_torrent_phy *cdns_phy)
 {
+   void __iomem *sd_base = cdns_phy->sd_base;
+   u8 block_offset_shift, reg_offset_shift;
struct device *dev = cdns_phy->dev;
struct regmap *regmap;
u32 block_offset;
int i;
 
+   block_offset_shift = cdns_phy->init_data->block_offset_shift;
+   reg_offset_shift = cdns_phy->init_data->reg_offset_shift;
+
for (i = 0; i < MAX_NUM_LANES; i++) {
block_offset = TORRENT_TX_LANE_CDB_OFFSET(i, block_offset_shift,
  reg_offset_shift);
@@ -1690,16 +1723,6 @@ static int cdns_regmap_init_torrent_dp(struct 
cdns_torrent_phy *cdns_phy,
}
cdns_phy->regmap_phy_pma_common_cdb = regmap;
 
-   block_offset = TORRENT_DPTX_PHY_OFFSET;
-   regmap = cdns_regmap_init(dev, base, block_offset,
- reg_offset_shift,
- _torrent_dptx_phy_config);
-   if (IS_ERR(regmap)) {
-   dev_err(dev, "Failed to init DPTX PHY regmap\n");
-   return PTR_ERR(regmap);
-   }
-   cdns_phy->regmap_dptx_phy_reg = regmap;
-
return 0;
 }
 
@@ -1712,6 +1735,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
const struct cdns_torrent_data *data;
struct device_node *child;
int ret, subnodes, node = 0, i;
+   u8 init_dp_regmap = 0;
 
/* Get init data for this PHY */
data = of_device_get_match_data(dev);
@@ -1749,6 +1773,14 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
return -EINVAL;
}
 
+   ret = cdns_torrent_regmap_init(cdns_phy);
+   if (ret)
+   return ret;
+
+   ret = cdns_torrent_regfield_init(cdns_phy);
+   if (ret)
+   return ret;
+
for_each_available_chi

[PATCH v2 7/7] dt-bindings: phy: cadence-torrent: Update Torrent PHY bindings for generic use

2020-08-27 Thread Swapnil Jakhade
Torrent PHY can be used in different multi-link multi-protocol
configurations including protocols other than DisplayPort also,
such as PCIe, USB, SGMII, QSGMII etc. Update the bindings to have
support for these configurations.

Signed-off-by: Swapnil Jakhade 
---
 .../bindings/phy/phy-cadence-torrent.yaml | 76 ++-
 1 file changed, 58 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml 
b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
index a7ee19d27c19..1b9e1231f8d8 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
@@ -4,11 +4,13 @@
 $id: "http://devicetree.org/schemas/phy/phy-cadence-torrent.yaml#;
 $schema: "http://devicetree.org/meta-schemas/core.yaml#;
 
-title: Cadence Torrent SD0801 PHY binding for DisplayPort
+title: Cadence Torrent SD0801 PHY binding
 
 description:
   This binding describes the Cadence SD0801 PHY (also known as Torrent PHY)
-  hardware included with the Cadence MHDP DisplayPort controller.
+  hardware included with the Cadence MHDP DisplayPort controller. Torrent
+  PHY also supports multilink multiprotocol combinations including protocols
+  such as PCIe, USB, SGMII, QSGMII etc.
 
 maintainers:
   - Swapnil Jakhade 
@@ -49,13 +51,14 @@ properties:
   - const: dptx_phy
 
   resets:
-maxItems: 1
-description:
-  Torrent PHY reset.
-  See Documentation/devicetree/bindings/reset/reset.txt
+minItems: 1
+maxItems: 2
+items:
+  - description: Torrent PHY reset.
+  - description: Torrent APB reset. This is optional.
 
 patternProperties:
-  '^phy@[0-7]+$':
+  '^link@[0-7]+$':
 type: object
 description:
   Each group of PHY lanes with a single master lane should be represented 
as a sub-node.
@@ -78,13 +81,13 @@ patternProperties:
   Specifies the type of PHY for which the group of PHY lanes is used.
   Refer include/dt-bindings/phy/phy.h. Constants from the header 
should be used.
 $ref: /schemas/types.yaml#/definitions/uint32
-enum: [1, 2, 3, 4, 5, 6]
+enum: [1, 2, 3, 4, 5, 6, 7, 8, 9]
 
   cdns,num-lanes:
 description:
-  Number of DisplayPort lanes.
+  Number of lanes.
 $ref: /schemas/types.yaml#/definitions/uint32
-enum: [1, 2, 4]
+enum: [1, 2, 3, 4]
 default: 4
 
   cdns,ssc-mode:
@@ -108,6 +111,7 @@ patternProperties:
   - resets
   - "#phy-cells"
   - cdns,phy-type
+  - cdns,num-lanes
 
 additionalProperties: false
 
@@ -141,14 +145,50 @@ examples:
 clock-names = "refclk";
 #address-cells = <1>;
 #size-cells = <0>;
-phy@0 {
-  reg = <0>;
-  resets = < 1>, < 2>,
-   < 3>, < 4>;
-  #phy-cells = <0>;
-  cdns,phy-type = ;
-  cdns,num-lanes = <4>;
-  cdns,max-bit-rate = <8100>;
+link@0 {
+reg = <0>;
+resets = < 1>, < 2>,
+ < 3>, < 4>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <4>;
+cdns,max-bit-rate = <8100>;
+};
+};
+};
+  - |
+#include 
+#include 
+
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+
+torrent-phy@f0fb50 {
+compatible = "cdns,torrent-phy";
+reg = <0xf0 0xfb50 0x0 0x0010>;
+reg-names = "torrent_phy";
+resets = < 0>, < 1>;
+clocks = <_clk>;
+clock-names = "refclk";
+#address-cells = <1>;
+#size-cells = <0>;
+link@0 {
+reg = <0>;
+resets = < 2>, < 3>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <2>;
+cdns,ssc-mode = ;
+};
+
+link@2 {
+reg = <2>;
+resets = < 4>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <1>;
+cdns,ssc-mode = ;
 };
 };
 };
-- 
2.26.1



[PATCH v5 0/2] Add new PHY APIs to framework to get/set PHY attributes

2020-08-24 Thread Swapnil Jakhade
This patch series adds a new pair of PHY APIs that can be used to get/set
all the PHY attributes. It also adds a new PHY attribute max_link_rate.

It includes following patches:

1. v5-0001-phy-Add-new-PHY-attribute-max_link_rate-and-APIs-.patch
This patch adds max_link_rate as a new PHY attribute along with a pair of
APIs that allow using the generic PHY subsystem to get/set PHY attributes
supported by the PHY.

2. v5-0002-phy-cadence-torrent-Use-kernel-PHY-API-to-set-PHY.patch
This patch uses PHY API phy_set_attrs() to set corresponding PHY properties
in Cadence Torrent PHY driver. This will enable drivers using this PHY to
read these properties using PHY framework.

The phy_get_attrs() API will be used in the DRM bridge driver [1] which is
in the process of upstreaming.

[1]

https://lkml.org/lkml/2020/8/6/649

Version History:

v5:
- Add kernel-doc comments for phy_get_attrs/phy_set_attrs APIs
- Pass second parameter of phy_set_attrs() as const struct *
- Add Acked-by: Kishon Vijay Abraham I 

v4:
- Protect phy_get_attrs/phy_set_attrs APIs with mutex

v3:
- Add comment describing new PHY attribute max_link_rate
- Use of memcpy to copy structure members
- Change commit log a bit

v2:
- Implemented single pair of functions to get/set all PHY attributes

Swapnil Jakhade (2):
  phy: Add new PHY attribute max_link_rate and APIs to get/set PHY
attributes
  phy: cadence-torrent: Use kernel PHY API to set PHY attributes

 drivers/phy/cadence/phy-cadence-torrent.c |  7 
 include/linux/phy/phy.h   | 43 +++
 2 files changed, 50 insertions(+)

-- 
2.26.1



[PATCH v5 1/2] phy: Add new PHY attribute max_link_rate and APIs to get/set PHY attributes

2020-08-24 Thread Swapnil Jakhade
Add new PHY attribute max_link_rate to struct phy_attrs.
Add a pair of PHY APIs to get/set all the PHY attributes.
Use phy_get_attrs() to get attribute values and phy_set_attrs()
to set attribute values.

Signed-off-by: Yuti Amonkar 
Signed-off-by: Swapnil Jakhade 
Acked-by: Kishon Vijay Abraham I 
---
 include/linux/phy/phy.h | 43 +
 1 file changed, 43 insertions(+)

diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index bcee8eba62b3..924cd1a3deea 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -115,10 +115,12 @@ struct phy_ops {
 /**
  * struct phy_attrs - represents phy attributes
  * @bus_width: Data path width implemented by PHY
+ * @max_link_rate: Maximum link rate supported by PHY (in Mbps)
  * @mode: PHY mode
  */
 struct phy_attrs {
u32 bus_width;
+   u32 max_link_rate;
enum phy_mode   mode;
 };
 
@@ -231,6 +233,37 @@ static inline void phy_set_bus_width(struct phy *phy, int 
bus_width)
 {
phy->attrs.bus_width = bus_width;
 }
+
+/**
+ * phy_get_attrs() - get the values for PHY attributes.
+ * @phy: the phy for which to get the attributes
+ * @attrs: current PHY attributes that will be returned
+ *
+ * Intended to be used by phy consumers to get the current PHY attributes
+ * stored in struct phy_attrs.
+ */
+static inline void phy_get_attrs(struct phy *phy, struct phy_attrs *attrs)
+{
+   mutex_lock(>mutex);
+   memcpy(attrs, >attrs, sizeof(struct phy_attrs));
+   mutex_unlock(>mutex);
+}
+
+/**
+ * phy_set_attrs() - set PHY attributes with new values.
+ * @phy: the phy for which to set the attributes
+ * @attrs: the  phy_attrs containing new PHY attributes to be set
+ *
+ * This can be used by PHY providers or PHY consumers to set the PHY
+ * attributes. The locking is used to protect updating attributes when
+ * PHY consumer is doing some PHY ops.
+ */
+static inline void phy_set_attrs(struct phy *phy, const struct phy_attrs 
*attrs)
+{
+   mutex_lock(>mutex);
+   memcpy(>attrs, attrs, sizeof(struct phy_attrs));
+   mutex_unlock(>mutex);
+}
 struct phy *phy_get(struct device *dev, const char *string);
 struct phy *phy_optional_get(struct device *dev, const char *string);
 struct phy *devm_phy_get(struct device *dev, const char *string);
@@ -389,6 +422,16 @@ static inline void phy_set_bus_width(struct phy *phy, int 
bus_width)
return;
 }
 
+static inline void phy_get_attrs(struct phy *phy, struct phy_attrs *attrs)
+{
+   return;
+}
+
+static inline void phy_set_attrs(struct phy *phy, const struct phy_attrs 
*attrs)
+{
+   return;
+}
+
 static inline struct phy *phy_get(struct device *dev, const char *string)
 {
return ERR_PTR(-ENOSYS);
-- 
2.26.1



[PATCH v5 2/2] phy: cadence-torrent: Use kernel PHY API to set PHY attributes

2020-08-24 Thread Swapnil Jakhade
Use generic PHY framework function phy_set_attrs() to set number
of lanes and maximum link rate supported by PHY.

Signed-off-by: Swapnil Jakhade 
Acked-by: Kishon Vijay Abraham I 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 7116127358ee..eca71467c4a8 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1710,6 +1710,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
struct cdns_torrent_phy *cdns_phy;
struct device *dev = >dev;
struct phy_provider *phy_provider;
+   struct phy_attrs torrent_attr;
const struct of_device_id *match;
struct cdns_torrent_data *data;
struct device_node *child;
@@ -1852,6 +1853,12 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
 cdns_phy->phys[node].num_lanes,
 cdns_phy->max_bit_rate / 1000,
 cdns_phy->max_bit_rate % 1000);
+
+   torrent_attr.bus_width = cdns_phy->phys[node].num_lanes;
+   torrent_attr.max_link_rate = cdns_phy->max_bit_rate;
+   torrent_attr.mode = PHY_MODE_DP;
+
+   phy_set_attrs(gphy, _attr);
} else {
dev_err(dev, "Driver supports only PHY_TYPE_DP\n");
ret = -ENOTSUPP;
-- 
2.26.1



[PATCH v1 05/13] phy: cadence-torrent: Add support for PHY multilink configuration

2020-08-07 Thread Swapnil Jakhade
Added support for multilink configuration of Torrent PHY. Currently,
maximum two links are supported. In case of multilink configuration,
PHY needs to be configured for both the protocols simultaneously at
the beginning as per the requirement of Torrent PHY.
Also, register sequences for PCIe + SGMII/QSGMII Unique SSC PHY multilink
configurations are added.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 783 +-
 1 file changed, 757 insertions(+), 26 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 7ccdb3105783..c55f8bde52f1 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -29,7 +29,7 @@
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
 #define NUM_SSC_MODE   3
-#define NUM_PHY_TYPE   2
+#define NUM_PHY_TYPE   5
 
 #define POLL_TIMEOUT_US5000
 #define PLL_LOCK_TIMEOUT   10
@@ -127,8 +127,10 @@
 #define CMN_PLL1_LOCK_REFCNT_START  0x00DCU
 #define CMN_PLL1_LOCK_PLLCNT_START 0x00DEU
 #define CMN_PLL1_LOCK_PLLCNT_THR0x00DFU
+#define CMN_TXPUCAL_TUNE   0x0103U
 #define CMN_TXPUCAL_INIT_TMR   0x0104U
 #define CMN_TXPUCAL_ITER_TMR   0x0105U
+#define CMN_TXPDCAL_TUNE   0x010BU
 #define CMN_TXPDCAL_INIT_TMR   0x010CU
 #define CMN_TXPDCAL_ITER_TMR   0x010DU
 #define CMN_RXCAL_INIT_TMR 0x0114U
@@ -143,6 +145,7 @@
 #define CMN_PDIAG_PLL0_CP_IADJ_M0  0x01A5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M00x01A6U
 #define CMN_PDIAG_PLL0_CTRL_M1 0x01B0U
+#define CMN_PDIAG_PLL0_CLK_SEL_M1  0x01B1U
 #define CMN_PDIAG_PLL0_CP_PADJ_M1  0x01B4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M1  0x01B5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M10x01B6U
@@ -151,6 +154,7 @@
 #define CMN_PDIAG_PLL1_CP_PADJ_M0  0x01C4U
 #define CMN_PDIAG_PLL1_CP_IADJ_M0  0x01C5U
 #define CMN_PDIAG_PLL1_FILT_PADJ_M00x01C6U
+#define CMN_DIAG_BIAS_OVRD10x01E1U
 
 /* PMA TX Lane registers */
 #define TX_TXCC_CTRL   0x0040U
@@ -173,11 +177,20 @@
 #define RX_PSC_A2  0x0002U
 #define RX_PSC_A3  0x0003U
 #define RX_PSC_CAL 0x0006U
+#define RX_CDRLF_CNFG  0x0080U
 #define RX_REE_GCSM1_CTRL  0x0108U
+#define RX_REE_GCSM1_EQENM_PH1 0x0109U
+#define RX_REE_GCSM1_EQENM_PH2 0x010AU
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
 #define RX_REE_TAP1_CLIP   0x0171U
 #define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_DIAG_DFE_CTRL   0x01E0U
+#define RX_DIAG_DFE_AMP_TUNE_2 0x01E2U
+#define RX_DIAG_DFE_AMP_TUNE_3 0x01E3U
+#define RX_DIAG_NQST_CTRL  0x01E5U
+#define RX_DIAG_PI_RATE0x01F4U
+#define RX_DIAG_PI_CAP 0x01F5U
 #define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
@@ -204,8 +217,11 @@ static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
 enum cdns_torrent_phy_type {
+   TYPE_NONE,
TYPE_DP,
-   TYPE_PCIE
+   TYPE_PCIE,
+   TYPE_SGMII,
+   TYPE_QSGMII,
 };
 
 enum cdns_torrent_ssc_mode {
@@ -309,9 +325,16 @@ struct cdns_torrent_vals {
 struct cdns_torrent_data {
u8 block_offset_shift;
u8 reg_offset_shift;
-   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
-   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
-   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *link_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+  [NUM_SSC_MODE];
+   struct cdns_torrent_vals *xcvr_diag_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
+   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
+   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
+   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+   [NUM_SSC_MODE];
 };
 
 struct cdns_regmap_cdb_context {
@@ -1787,6 +1810,7 @@ static int cdns_torrent_regmap_init(struct 
cdns_torrent_phy *cdns_phy)
 static int cdns_torrent_phy_init(struct phy *phy)
 {
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+   const struct cdns_torrent_data *init_data = cdns_phy->init_data;
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
@@ -1809,11

[PATCH v1 07/13] phy: cadence-torrent: Add clk changes for multilink configuration

2020-08-07 Thread Swapnil Jakhade
Prepare and enable clock in probe instead of phy_init.
Also, remove phy_exit callback.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 41 ++-
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index fc5720845ec7..691d4aa5b2ed 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -273,7 +273,6 @@ enum phy_powerstate {
 };
 
 static int cdns_torrent_phy_init(struct phy *phy);
-static int cdns_torrent_phy_exit(struct phy *phy);
 static int cdns_torrent_dp_init(struct phy *phy);
 static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
   u32 num_lanes);
@@ -305,7 +304,6 @@ static int cdns_torrent_phy_off(struct phy *phy);
 
 static const struct phy_ops cdns_torrent_phy_ops = {
.init   = cdns_torrent_phy_init,
-   .exit   = cdns_torrent_phy_exit,
.configure  = cdns_torrent_dp_configure,
.power_on   = cdns_torrent_phy_on,
.power_off  = cdns_torrent_phy_off,
@@ -977,14 +975,6 @@ static int cdns_torrent_dp_init(struct phy *phy)
return ret;
 }
 
-static int cdns_torrent_phy_exit(struct phy *phy)
-{
-   struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
-
-   clk_disable_unprepare(cdns_phy->clk);
-   return 0;
-}
-
 static
 int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
 {
@@ -1825,20 +1815,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_reg_pairs *reg_pairs;
struct regmap *regmap;
u32 num_regs;
-   int ret, i, j;
-
-   ret = clk_prepare_enable(cdns_phy->clk);
-   if (ret) {
-   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
-   return ret;
-   }
-
-   cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
-   if (!(cdns_phy->ref_clk_rate)) {
-   dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
-   clk_disable_unprepare(cdns_phy->clk);
-   return -EINVAL;
-   }
+   int i, j;
 
if (cdns_phy->nsubnodes > 1)
return 0;
@@ -2072,6 +2049,19 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
if (ret)
return ret;
 
+   ret = clk_prepare_enable(cdns_phy->clk);
+   if (ret) {
+   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+   return ret;
+   }
+
+   cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
+   if (!(cdns_phy->ref_clk_rate)) {
+   dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+   clk_disable_unprepare(cdns_phy->clk);
+   return -EINVAL;
+   }
+
/* Enable APB */
reset_control_deassert(cdns_phy->apb_rst);
 
@@ -2246,6 +2236,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
reset_control_put(cdns_phy->phys[i].lnk_rst);
of_node_put(child);
reset_control_assert(cdns_phy->apb_rst);
+   clk_disable_unprepare(cdns_phy->clk);
return ret;
 }
 
@@ -2261,6 +2252,8 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
reset_control_put(cdns_phy->phys[i].lnk_rst);
}
 
+   clk_disable_unprepare(cdns_phy->clk);
+
return 0;
 }
 
-- 
2.26.1



[PATCH v1 09/13] phy: cadence-torrent: Configure PHY_PLL_CFG as part of link_cmn_vals

2020-08-07 Thread Swapnil Jakhade
Include PHY_PLL_CFG as a first register value to configure in
link_cmn_vals array values.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index d01a44b93e99..216b25512a08 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1830,7 +1830,14 @@ static int cdns_torrent_phy_init(struct phy *phy)
reg_pairs = link_cmn_vals->reg_pairs;
num_regs = link_cmn_vals->num_regs;
regmap = cdns_phy->regmap_common_cdb;
-   for (i = 0; i < num_regs; i++)
+
+   /**
+* First array value in link_cmn_vals must be of
+* PHY_PLL_CFG register
+*/
+   regmap_field_write(cdns_phy->phy_pll_cfg, reg_pairs[0].val);
+
+   for (i = 1; i < num_regs; i++)
regmap_write(regmap, reg_pairs[i].off,
 reg_pairs[i].val);
}
@@ -1907,8 +1914,6 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
phy_t1 = cdns_phy->phys[0].phy_type;
phy_t2 = cdns_phy->phys[1].phy_type;
 
-   regmap_field_write(cdns_phy->phy_pll_cfg, 0x0003);
-
/**
 * First configure the PHY for first link with phy_t1. Get the array
 * values as [phy_t1][phy_t2][ssc].
@@ -1944,7 +1949,15 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
reg_pairs = link_cmn_vals->reg_pairs;
num_regs = link_cmn_vals->num_regs;
regmap = cdns_phy->regmap_common_cdb;
-   for (i = 0; i < num_regs; i++)
+
+   /**
+* First array value in link_cmn_vals must be of
+* PHY_PLL_CFG register
+*/
+   regmap_field_write(cdns_phy->phy_pll_cfg,
+  reg_pairs[0].val);
+
+   for (i = 1; i < num_regs; i++)
regmap_write(regmap, reg_pairs[i].off,
 reg_pairs[i].val);
}
@@ -2283,6 +2296,7 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
 
 /* PCIe and SGMII/QSGMII Unique SSC link configuration */
 static struct cdns_reg_pairs pcie_sgmii_link_cmn_regs[] = {
+   {0x0003, PHY_PLL_CFG},
{0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0},
{0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1},
{0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0}
-- 
2.26.1



[PATCH v1 10/13] phy: cadence-torrent: Add single link SGMII/QSGMII register sequences

2020-08-07 Thread Swapnil Jakhade
Add support for single link SGMII/QSGMII configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 89 +++
 1 file changed, 89 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 216b25512a08..b291b63afba8 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1824,6 +1824,13 @@ static int cdns_torrent_phy_init(struct phy *phy)
if (phy_type == TYPE_DP)
return cdns_torrent_dp_init(phy);
 
+   /**
+* Spread spectrum generation is not required or supported
+* for SGMII/QSGMII
+*/
+   if (phy_type == TYPE_SGMII || phy_type == TYPE_QSGMII)
+   ssc = NO_SSC;
+
/* PHY configuration specific registers for single link */
link_cmn_vals = init_data->link_cmn_vals[phy_type][TYPE_NONE][ssc];
if (link_cmn_vals) {
@@ -2543,6 +2550,28 @@ static struct cdns_torrent_vals 
qsgmii_100_int_ssc_cmn_vals = {
.num_regs = ARRAY_SIZE(qsgmii_100_int_ssc_cmn_regs),
 };
 
+/* Single SGMII/QSGMII link configuration */
+static struct cdns_reg_pairs sl_sgmii_link_cmn_regs[] = {
+   {0x, PHY_PLL_CFG},
+   {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs sl_sgmii_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0003, XCVR_DIAG_HSCLK_DIV},
+   {0x0013, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals sl_sgmii_link_cmn_vals = {
+   .reg_pairs = sl_sgmii_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(sl_sgmii_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals sl_sgmii_xcvr_diag_ln_vals = {
+   .reg_pairs = sl_sgmii_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(sl_sgmii_xcvr_diag_ln_regs),
+};
+
 /* Multi link PCIe, 100 MHz Ref clk, internal SSC */
 static struct cdns_reg_pairs pcie_100_int_ssc_cmn_regs[] = {
{0x0004, CMN_PLL0_DSM_DIAG_M0},
@@ -2701,6 +2730,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2708,6 +2740,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2734,6 +2769,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_xcvr_diag_ln_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _pcie_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
@@ -2741,6 +2779,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _sgmii_xcvr_diag_ln_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _pcie_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
@@ -2767,6 +2808,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _100_no_ssc_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _100_no_ssc_cmn_vals,
[EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
@@ -2774,6 +2818,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_QSGMII] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = _100_no_ssc_cmn_vals,
+   },
[TYPE_PCIE] = {
[NO_SSC] = _100_no_ssc_cmn_vals,
[EXTERNAL_SSC] = _100_no_ssc_cmn_vals,
@@ -2800,6 +2847,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
},
[TYPE_SG

[PATCH v1 03/13] phy: cadence-torrent: Add PHY APB reset support

2020-08-07 Thread Swapnil Jakhade
Add support for PHY APB reset and make it optional.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 8c6e1aa93b64..7ccdb3105783 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -228,6 +228,7 @@ struct cdns_torrent_phy {
void __iomem *sd_base; /* SD0801 registers base */
u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */
struct reset_control *phy_rst;
+   struct reset_control *apb_rst;
struct device *dev;
struct clk *clk;
unsigned long ref_clk_rate;
@@ -1884,6 +1885,13 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
return PTR_ERR(cdns_phy->phy_rst);
}
 
+   cdns_phy->apb_rst = devm_reset_control_get_optional(dev, "torrent_apb");
+   if (IS_ERR(cdns_phy->apb_rst)) {
+   dev_err(dev, "%s: failed to get apb reset\n",
+   dev->of_node->full_name);
+   return PTR_ERR(cdns_phy->apb_rst);
+   }
+
cdns_phy->clk = devm_clk_get(dev, "refclk");
if (IS_ERR(cdns_phy->clk)) {
dev_err(dev, "phy ref clock not found\n");
@@ -1908,6 +1916,9 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
if (ret)
return ret;
 
+   /* Enable APB */
+   reset_control_deassert(cdns_phy->apb_rst);
+
for_each_available_child_of_node(dev->of_node, child) {
struct phy *gphy;
 
@@ -2062,6 +2073,7 @@ static int cdns_torrent_phy_probe(struct platform_device 
*pdev)
for (i = 0; i < node; i++)
reset_control_put(cdns_phy->phys[i].lnk_rst);
of_node_put(child);
+   reset_control_assert(cdns_phy->apb_rst);
return ret;
 }
 
@@ -2071,6 +2083,7 @@ static int cdns_torrent_phy_remove(struct platform_device 
*pdev)
int i;
 
reset_control_assert(cdns_phy->phy_rst);
+   reset_control_assert(cdns_phy->apb_rst);
for (i = 0; i < cdns_phy->nsubnodes; i++) {
reset_control_assert(cdns_phy->phys[i].lnk_rst);
reset_control_put(cdns_phy->phys[i].lnk_rst);
-- 
2.26.1



[PATCH v1 12/13] phy: cadence-torrent: Add PCIe + USB multilink configuration

2020-08-07 Thread Swapnil Jakhade
Add PCIe + USB Unique SSC multilink configuration sequences.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 216 ++
 1 file changed, 216 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 9b4eb4647401..3eafb72014fa 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1938,6 +1938,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type;
+   struct cdns_torrent_vals *pcs_cmn_vals;
int i, j, node, mlane, num_lanes, ret;
struct cdns_reg_pairs *reg_pairs;
enum cdns_torrent_ssc_mode ssc;
@@ -2011,6 +2012,17 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
}
}
 
+   /* 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 = cdns_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 */
cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc];
if (cmn_vals) {
@@ -2334,6 +2346,100 @@ static int cdns_torrent_phy_remove(struct 
platform_device *pdev)
return 0;
 }
 
+/* PCIe and USB Unique SSC link configuration */
+static struct cdns_reg_pairs pcie_usb_link_cmn_regs[] = {
+   {0x0003, PHY_PLL_CFG},
+   {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0},
+   {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1},
+   {0x8600, CMN_PDIAG_PLL1_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs pcie_usb_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x0012, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs usb_pcie_xcvr_diag_ln_regs[] = {
+   {0x0011, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x00C9, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals pcie_usb_link_cmn_vals = {
+   .reg_pairs = pcie_usb_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(pcie_usb_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals pcie_usb_xcvr_diag_ln_vals = {
+   .reg_pairs = pcie_usb_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(pcie_usb_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals usb_pcie_xcvr_diag_ln_vals = {
+   .reg_pairs = usb_pcie_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(usb_pcie_xcvr_diag_ln_regs),
+};
+
+/* USB 100 MHz Ref clk, internal SSC */
+static struct cdns_reg_pairs usb_100_int_ssc_cmn_regs[] = {
+   {0x0004, CMN_PLL0_DSM_DIAG_M0},
+   {0x0004, CMN_PLL0_DSM_DIAG_M1},
+   {0x0004, CMN_PLL1_DSM_DIAG_M0},
+   {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0},
+   {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M1},
+   {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0},
+   {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0},
+   {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M1},
+   {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0},
+   {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0},
+   {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M1},
+   {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0},
+   {0x0064, CMN_PLL0_INTDIV_M0},
+   {0x0050, CMN_PLL0_INTDIV_M1},
+   {0x0064, CMN_PLL1_INTDIV_M0},
+   {0x0002, CMN_PLL0_FRACDIVH_M0},
+   {0x0002, CMN_PLL0_FRACDIVH_M1},
+   {0x0002, CMN_PLL1_FRACDIVH_M0},
+   {0x0044, CMN_PLL0_HIGH_THR_M0},
+   {0x0036, CMN_PLL0_HIGH_THR_M1},
+   {0x0044, CMN_PLL1_HIGH_THR_M0},
+   {0x0002, CMN_PDIAG_PLL0_CTRL_M0},
+   {0x0002, CMN_PDIAG_PLL0_CTRL_M1},
+   {0x0002, CMN_PDIAG_PLL1_CTRL_M0},
+   {0x0001, CMN_PLL0_SS_CTRL1_M0},
+   {0x0001, CMN_PLL0_SS_CTRL1_M1},
+   {0x0001, CMN_PLL1_SS_CTRL1_M0},
+   {0x011B, CMN_PLL0_SS_CTRL2_M0},
+   {0x011B, CMN_PLL0_SS_CTRL2_M1},
+   {0x011B, CMN_PLL1_SS_CTRL2_M0},
+   {0x006E, CMN_PLL0_SS_CTRL3_M0},
+   {0x0058, CMN_PLL0_SS_CTRL3_M1},
+   {0x006E, CMN_PLL1_SS_CTRL3_M0},
+   {0x000E, CMN_PLL0_SS_CTRL4_M0},
+   {0x0012, CMN_PLL0_SS_CTRL4_M1},
+   {0x000E, CMN_PLL1_SS_CTRL4_M0},
+   {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START},
+   {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
+   {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
+   {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
+   {0x0003, CMN_PLL0_VCOCAL_TCTRL},
+   {0x0003, CMN_PLL1_VCOCAL_TCTRL

[PATCH v1 00/13] PHY: Add support for multilink configurations in Cadence Torrent PHY driver

2020-08-07 Thread Swapnil Jakhade
Cadence Torrent PHY is a multiprotocol PHY supporting different multilink
PHY configurations including DisplayPort, PCIe, USB, SGMII, QSGMII etc.
This patch series extends functionality of Torrent PHY driver to support
following configurations:
- Single link PCIe configuration
- PCIe + SGMII/QSGMII Unique SSC multilink configuration
- Single link SGMII/QSGMII configuration
- Single link USB configuration
- PCIe + USB Unique SSC multilink configuration
- USB + SGMII/QSGMII multilink configuration

The changes have been validated on TI J7200 platform.

This patch series is dependent on [1] and [2] and should be applied on
top of these.

[1] https://lkml.org/lkml/2020/7/17/158

[2] https://lkml.org/lkml/2020/8/7/338

Swapnil Jakhade (13):
  phy: cadence-torrent: Add single link PCIe support
  phy: cadence-torrent: Check cmn_ready assertion during PHY power on
  phy: cadence-torrent: Add PHY APB reset support
  dt-bindings: phy: Add PHY_TYPE_QSGMII definition
  phy: cadence-torrent: Add support for PHY multilink configuration
  phy: cadence-torrent: Update PHY reset for multilink configuration
  phy: cadence-torrent: Add clk changes for multilink configuration
  phy: cadence-torrent: Add PHY link configuration sequences for single
link
  phy: cadence-torrent: Configure PHY_PLL_CFG as part of link_cmn_vals
  phy: cadence-torrent: Add single link SGMII/QSGMII register sequences
  phy: cadence-torrent: Add single link USB register sequences
  phy: cadence-torrent: Add PCIe + USB multilink configuration
  phy: cadence-torrent: Add USB + SGMII/QSGMII multilink configuration

 drivers/phy/cadence/phy-cadence-torrent.c | 1975 -
 include/dt-bindings/phy/phy.h |1 +
 2 files changed, 1934 insertions(+), 42 deletions(-)

-- 
2.26.1



[PATCH v1 13/13] phy: cadence-torrent: Add USB + SGMII/QSGMII multilink configuration

2020-08-07 Thread Swapnil Jakhade
Add USB + SGMII/QSGMII multilink configuration sequences.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 254 ++
 1 file changed, 254 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 3eafb72014fa..124d00e07f85 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -2346,6 +2346,40 @@ static int cdns_torrent_phy_remove(struct 
platform_device *pdev)
return 0;
 }
 
+/* USB and SGMII/QSGMII link configuration */
+static struct cdns_reg_pairs usb_sgmii_link_cmn_regs[] = {
+   {0x0002, PHY_PLL_CFG},
+   {0x8600, CMN_PDIAG_PLL0_CLK_SEL_M0},
+   {0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0}
+};
+
+static struct cdns_reg_pairs usb_sgmii_xcvr_diag_ln_regs[] = {
+   {0x, XCVR_DIAG_HSCLK_SEL},
+   {0x0001, XCVR_DIAG_HSCLK_DIV},
+   {0x0041, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_reg_pairs sgmii_usb_xcvr_diag_ln_regs[] = {
+   {0x0011, XCVR_DIAG_HSCLK_SEL},
+   {0x0003, XCVR_DIAG_HSCLK_DIV},
+   {0x009B, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static struct cdns_torrent_vals usb_sgmii_link_cmn_vals = {
+   .reg_pairs = usb_sgmii_link_cmn_regs,
+   .num_regs = ARRAY_SIZE(usb_sgmii_link_cmn_regs),
+};
+
+static struct cdns_torrent_vals usb_sgmii_xcvr_diag_ln_vals = {
+   .reg_pairs = usb_sgmii_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(usb_sgmii_xcvr_diag_ln_regs),
+};
+
+static struct cdns_torrent_vals sgmii_usb_xcvr_diag_ln_vals = {
+   .reg_pairs = sgmii_usb_xcvr_diag_ln_regs,
+   .num_regs = ARRAY_SIZE(sgmii_usb_xcvr_diag_ln_regs),
+};
+
 /* PCIe and USB Unique SSC link configuration */
 static struct cdns_reg_pairs pcie_usb_link_cmn_regs[] = {
{0x0003, PHY_PLL_CFG},
@@ -3019,6 +3053,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
[INTERNAL_SSC] = _sgmii_link_cmn_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
@@ -3029,6 +3068,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
[INTERNAL_SSC] = _sgmii_link_cmn_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
[TYPE_USB] = {
[TYPE_NONE] = {
@@ -3041,6 +3085,16 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _usb_link_cmn_vals,
[INTERNAL_SSC] = _usb_link_cmn_vals,
},
+   [TYPE_SGMII] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
+   [TYPE_QSGMII] = {
+   [NO_SSC] = _sgmii_link_cmn_vals,
+   [EXTERNAL_SSC] = _sgmii_link_cmn_vals,
+   [INTERNAL_SSC] = _sgmii_link_cmn_vals,
+   },
},
},
.xcvr_diag_vals = {
@@ -3075,6 +3129,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
[INTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _usb_xcvr_diag_ln_vals,
+   [EXTERNAL_SSC] = _usb_xcvr_diag_ln_vals,
+   [INTERNAL_SSC] = _usb_xcvr_diag_ln_vals,
+   },
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
@@ -3085,6 +3144,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
[EXTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
[INTERNAL_SSC] = _pcie_xcvr_diag_ln_vals,
},
+   [TYPE_USB] = {
+   [NO_SSC] = _usb_xcvr_diag_ln_vals,
+   [EXTERNAL_SSC] = _usb_xcvr_diag_ln_vals

[PATCH v1 06/13] phy: cadence-torrent: Update PHY reset for multilink configuration

2020-08-07 Thread Swapnil Jakhade
For multilink configuration, deassert PHY and link reset after PHY
registers are configured in probe and only check link status in
power_on callback.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 28 +--
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index c55f8bde52f1..fc5720845ec7 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1603,13 +1603,15 @@ static int cdns_torrent_phy_on(struct phy *phy)
u32 read_val;
int ret;
 
-   /* Take the PHY out of reset */
-   ret = reset_control_deassert(cdns_phy->phy_rst);
-   if (ret)
-   return ret;
+   if (cdns_phy->nsubnodes == 1) {
+   /* Take the PHY lane group out of reset */
+   reset_control_deassert(inst->lnk_rst);
 
-   /* Take the PHY lane group out of reset */
-   reset_control_deassert(inst->lnk_rst);
+   /* Take the PHY out of reset */
+   ret = reset_control_deassert(cdns_phy->phy_rst);
+   if (ret)
+   return ret;
+   }
 
/*
 * Wait for cmn_ready assertion
@@ -1623,6 +1625,8 @@ static int cdns_torrent_phy_on(struct phy *phy)
return ret;
}
 
+   mdelay(10);
+
return 0;
 }
 
@@ -1632,6 +1636,9 @@ static int cdns_torrent_phy_off(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
int ret;
 
+   if (cdns_phy->nsubnodes != 1)
+   return 0;
+
ret = reset_control_assert(cdns_phy->phy_rst);
if (ret)
return ret;
@@ -1886,7 +1893,7 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type;
-   int i, j, node, mlane, num_lanes;
+   int i, j, node, mlane, num_lanes, ret;
struct cdns_reg_pairs *reg_pairs;
enum cdns_torrent_ssc_mode ssc;
struct regmap *regmap;
@@ -1989,8 +1996,15 @@ int cdns_torrent_phy_configure_multilink(struct 
cdns_torrent_phy *cdns_phy)
 reg_pairs[j].val);
}
}
+
+   reset_control_deassert(cdns_phy->phys[node].lnk_rst);
}
 
+   /* Take the PHY out of reset */
+   ret = reset_control_deassert(cdns_phy->phy_rst);
+   if (ret)
+   return ret;
+
return 0;
 }
 
-- 
2.26.1



[PATCH v1 11/13] phy: cadence-torrent: Add single link USB register sequences

2020-08-07 Thread Swapnil Jakhade
Add support for single link USB configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 260 +-
 1 file changed, 259 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index b291b63afba8..9b4eb4647401 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -29,7 +29,7 @@
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
 #define NUM_SSC_MODE   3
-#define NUM_PHY_TYPE   5
+#define NUM_PHY_TYPE   6
 
 #define POLL_TIMEOUT_US5000
 #define PLL_LOCK_TIMEOUT   10
@@ -82,6 +82,8 @@
 #define CMN_PLLSM0_PLLLOCK_TMR 0x002CU
 #define CMN_PLLSM1_PLLPRE_TMR  0x0032U
 #define CMN_PLLSM1_PLLLOCK_TMR 0x0034U
+#define CMN_CDIAG_CDB_PWRI_OVRD0x0041U
+#define CMN_CDIAG_XCVRC_PWRI_OVRD  0x0047U
 #define CMN_BGCAL_INIT_TMR 0x0064U
 #define CMN_BGCAL_ITER_TMR 0x0065U
 #define CMN_IBCAL_INIT_TMR 0x0074U
@@ -159,13 +161,16 @@
 /* PMA TX Lane registers */
 #define TX_TXCC_CTRL   0x0040U
 #define TX_TXCC_CPOST_MULT_00  0x004CU
+#define TX_TXCC_CPOST_MULT_01  0x004DU
 #define TX_TXCC_MGNFS_MULT_000 0x0050U
 #define DRV_DIAG_TX_DRV0x00C6U
 #define XCVR_DIAG_PLLDRC_CTRL  0x00E5U
 #define XCVR_DIAG_HSCLK_SEL0x00E6U
 #define XCVR_DIAG_HSCLK_DIV0x00E7U
 #define XCVR_DIAG_BIDI_CTRL0x00EAU
+#define XCVR_DIAG_PSC_OVRD 0x00EBU
 #define TX_PSC_A0  0x0100U
+#define TX_PSC_A1  0x0101U
 #define TX_PSC_A2  0x0102U
 #define TX_PSC_A3  0x0103U
 #define TX_RCVDET_ST_TMR   0x0123U
@@ -174,27 +179,37 @@
 
 /* PMA RX Lane registers */
 #define RX_PSC_A0  0xU
+#define RX_PSC_A1  0x0001U
 #define RX_PSC_A2  0x0002U
 #define RX_PSC_A3  0x0003U
 #define RX_PSC_CAL 0x0006U
 #define RX_CDRLF_CNFG  0x0080U
+#define RX_CDRLF_CNFG3 0x0082U
+#define RX_SIGDET_HL_FILT_TMR  0x0090U
 #define RX_REE_GCSM1_CTRL  0x0108U
 #define RX_REE_GCSM1_EQENM_PH1 0x0109U
 #define RX_REE_GCSM1_EQENM_PH2 0x010AU
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
+#define RX_REE_ATTEN_THR   0x0149U
 #define RX_REE_TAP1_CLIP   0x0171U
 #define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_REE_SMGM_CTRL1  0x0177U
+#define RX_REE_SMGM_CTRL2  0x0178U
 #define RX_DIAG_DFE_CTRL   0x01E0U
 #define RX_DIAG_DFE_AMP_TUNE_2 0x01E2U
 #define RX_DIAG_DFE_AMP_TUNE_3 0x01E3U
 #define RX_DIAG_NQST_CTRL  0x01E5U
+#define RX_DIAG_SIGDET_TUNE0x01E8U
 #define RX_DIAG_PI_RATE0x01F4U
 #define RX_DIAG_PI_CAP 0x01F5U
 #define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
 #define PHY_PLL_CFG0x000EU
+#define PHY_PIPE_USB3_GEN2_PRE_CFG00x0020U
+#define PHY_PIPE_USB3_GEN2_POST_CFG0   0x0022U
+#define PHY_PIPE_USB3_GEN2_POST_CFG1   0x0023U
 
 /* PHY PMA common registers */
 #define PHY_PMA_CMN_CTRL1  0xU
@@ -222,6 +237,7 @@ enum cdns_torrent_phy_type {
TYPE_PCIE,
TYPE_SGMII,
TYPE_QSGMII,
+   TYPE_USB,
 };
 
 enum cdns_torrent_ssc_mode {
@@ -327,6 +343,8 @@ struct cdns_torrent_data {
   [NUM_SSC_MODE];
struct cdns_torrent_vals *xcvr_diag_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
[NUM_SSC_MODE];
+   struct cdns_torrent_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
+ [NUM_SSC_MODE];
struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
  [NUM_SSC_MODE];
struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
@@ -1813,6 +1831,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
enum cdns_torrent_ssc_mode ssc = inst->ssc_mode;
+   struct cdns_torrent_vals *pcs_cmn_vals;
struct cdns_reg_pairs *reg_pairs;
struct regmap *regmap;
u32 num_regs;
@@ -1861,6 +1880,17 @@ static int cdns_torrent_phy_init(struct phy *phy)
}
}
 
+   /* 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;
+   

[PATCH v1 02/13] phy: cadence-torrent: Check cmn_ready assertion during PHY power on

2020-08-07 Thread Swapnil Jakhade
Check if cmn_ready is set after both PLL0 and PLL1 are locked.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 31 ++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index a703fcb355a8..8c6e1aa93b64 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -32,6 +32,7 @@
 #define NUM_PHY_TYPE   2
 
 #define POLL_TIMEOUT_US5000
+#define PLL_LOCK_TIMEOUT   10
 
 #define TORRENT_COMMON_CDB_OFFSET  0x0
 
@@ -183,12 +184,16 @@
 #define PHY_PLL_CFG0x000EU
 
 /* PHY PMA common registers */
+#define PHY_PMA_CMN_CTRL1  0xU
 #define PHY_PMA_CMN_CTRL2  0x0001U
 #define PHY_PMA_PLL_RAW_CTRL   0x0003U
 
 static const struct reg_field phy_pll_cfg =
REG_FIELD(PHY_PLL_CFG, 0, 1);
 
+static const struct reg_field phy_pma_cmn_ctrl_1 =
+   REG_FIELD(PHY_PMA_CMN_CTRL1, 0, 0);
+
 static const struct reg_field phy_pma_cmn_ctrl_2 =
REG_FIELD(PHY_PMA_CMN_CTRL2, 0, 7);
 
@@ -237,6 +242,7 @@ struct cdns_torrent_phy {
struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES];
struct regmap *regmap_dptx_phy_reg;
struct regmap_field *phy_pll_cfg;
+   struct regmap_field *phy_pma_cmn_ctrl_1;
struct regmap_field *phy_pma_cmn_ctrl_2;
struct regmap_field *phy_pma_pll_raw_ctrl;
struct regmap_field *phy_reset_ctrl;
@@ -1570,6 +1576,7 @@ static int cdns_torrent_phy_on(struct phy *phy)
 {
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
+   u32 read_val;
int ret;
 
/* Take the PHY out of reset */
@@ -1578,7 +1585,21 @@ static int cdns_torrent_phy_on(struct phy *phy)
return ret;
 
/* Take the PHY lane group out of reset */
-   return reset_control_deassert(inst->lnk_rst);
+   reset_control_deassert(inst->lnk_rst);
+
+   /*
+* Wait for cmn_ready assertion
+* PHY_PMA_CMN_CTRL1[0] == 1
+*/
+   ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_1,
+read_val, read_val, 1000,
+PLL_LOCK_TIMEOUT);
+   if (ret) {
+   dev_err(cdns_phy->dev, "Timeout waiting for CMN ready\n");
+   return ret;
+   }
+
+   return 0;
 }
 
 static int cdns_torrent_phy_off(struct phy *phy)
@@ -1643,6 +1664,14 @@ static int cdns_torrent_regfield_init(struct 
cdns_torrent_phy *cdns_phy)
}
cdns_phy->phy_pll_cfg = field;
 
+   regmap = cdns_phy->regmap_phy_pma_common_cdb;
+   field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_1);
+   if (IS_ERR(field)) {
+   dev_err(dev, "PHY_PMA_CMN_CTRL1 reg field init failed\n");
+   return PTR_ERR(field);
+   }
+   cdns_phy->phy_pma_cmn_ctrl_1 = field;
+
regmap = cdns_phy->regmap_phy_pma_common_cdb;
field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_2);
if (IS_ERR(field)) {
-- 
2.26.1



[PATCH v1 08/13] phy: cadence-torrent: Add PHY link configuration sequences for single link

2020-08-07 Thread Swapnil Jakhade
Add support to configure link_cmn_vals and xcvr_diag_vals in case of single
link PHY configuration.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 44 +++
 1 file changed, 44 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 691d4aa5b2ed..d01a44b93e99 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1809,6 +1809,7 @@ static int cdns_torrent_phy_init(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
const struct cdns_torrent_data *init_data = cdns_phy->init_data;
struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals;
+   struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals;
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
enum cdns_torrent_phy_type phy_type = inst->phy_type;
enum cdns_torrent_ssc_mode ssc = inst->ssc_mode;
@@ -1823,6 +1824,29 @@ static int cdns_torrent_phy_init(struct phy *phy)
if (phy_type == TYPE_DP)
return cdns_torrent_dp_init(phy);
 
+   /* PHY configuration specific registers for single link */
+   link_cmn_vals = init_data->link_cmn_vals[phy_type][TYPE_NONE][ssc];
+   if (link_cmn_vals) {
+   reg_pairs = link_cmn_vals->reg_pairs;
+   num_regs = link_cmn_vals->num_regs;
+   regmap = cdns_phy->regmap_common_cdb;
+   for (i = 0; i < num_regs; i++)
+   regmap_write(regmap, reg_pairs[i].off,
+reg_pairs[i].val);
+   }
+
+   xcvr_diag_vals = init_data->xcvr_diag_vals[phy_type][TYPE_NONE][ssc];
+   if (xcvr_diag_vals) {
+   reg_pairs = xcvr_diag_vals->reg_pairs;
+   num_regs = xcvr_diag_vals->num_regs;
+   for (i = 0; i < inst->num_lanes; i++) {
+   regmap = cdns_phy->regmap_tx_lane_cdb[i + inst->mlane];
+   for (j = 0; j < num_regs; j++)
+   regmap_write(regmap, reg_pairs[j].off,
+reg_pairs[j].val);
+   }
+   }
+
/* PMA common registers configurations */
cmn_vals = init_data->cmn_vals[phy_type][TYPE_NONE][ssc];
if (cmn_vals) {
@@ -2646,6 +2670,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
.reg_offset_shift = 0x2,
.link_cmn_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2674,6 +2703,11 @@ static const struct cdns_torrent_data cdns_map_torrent = 
{
},
.xcvr_diag_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _sgmii_xcvr_diag_ln_vals,
@@ -2806,6 +2840,11 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
.reg_offset_shift = 0x1,
.link_cmn_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_link_cmn_vals,
[EXTERNAL_SSC] = _sgmii_link_cmn_vals,
@@ -2834,6 +2873,11 @@ static const struct cdns_torrent_data 
ti_j721e_map_torrent = {
},
.xcvr_diag_vals = {
[TYPE_PCIE] = {
+   [TYPE_NONE] = {
+   [NO_SSC] = NULL,
+   [EXTERNAL_SSC] = NULL,
+   [INTERNAL_SSC] = NULL,
+   },
[TYPE_SGMII] = {
[NO_SSC] = _sgmii_xcvr_diag_ln_vals,
[EXTERNAL_SSC] = _sgmii_xcvr_diag_ln_vals,
-- 
2.26.1



[PATCH v1 04/13] dt-bindings: phy: Add PHY_TYPE_QSGMII definition

2020-08-07 Thread Swapnil Jakhade
Add definition for QSGMII phy type.

Signed-off-by: Swapnil Jakhade 
---
 include/dt-bindings/phy/phy.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
index 36e8c241cf48..887a31b250a8 100644
--- a/include/dt-bindings/phy/phy.h
+++ b/include/dt-bindings/phy/phy.h
@@ -19,5 +19,6 @@
 #define PHY_TYPE_DP6
 #define PHY_TYPE_XPCS  7
 #define PHY_TYPE_SGMII 8
+#define PHY_TYPE_QSGMII9
 
 #endif /* _DT_BINDINGS_PHY */
-- 
2.26.1



[PATCH v1 01/13] phy: cadence-torrent: Add single link PCIe support

2020-08-07 Thread Swapnil Jakhade
Add single link PCIe register sequences in Torrent PHY driver.
Also, add support for getting SSC type from DT.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 296 +++---
 1 file changed, 266 insertions(+), 30 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index 82f48ca5dcc6..a703fcb355a8 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -28,6 +28,9 @@
 #define MAX_NUM_LANES  4
 #define DEFAULT_MAX_BIT_RATE   8100 /* in Mbps */
 
+#define NUM_SSC_MODE   3
+#define NUM_PHY_TYPE   2
+
 #define POLL_TIMEOUT_US5000
 
 #define TORRENT_COMMON_CDB_OFFSET  0x0
@@ -98,6 +101,14 @@
 #define CMN_PLL0_LOCK_REFCNT_START  0x009CU
 #define CMN_PLL0_LOCK_PLLCNT_START 0x009EU
 #define CMN_PLL0_LOCK_PLLCNT_THR0x009FU
+#define CMN_PLL0_INTDIV_M1 0x00A0U
+#define CMN_PLL0_FRACDIVH_M1   0x00A2U
+#define CMN_PLL0_HIGH_THR_M1   0x00A3U
+#define CMN_PLL0_DSM_DIAG_M1   0x00A4U
+#define CMN_PLL0_SS_CTRL1_M1   0x00A8U
+#define CMN_PLL0_SS_CTRL2_M1   0x00A9U
+#define CMN_PLL0_SS_CTRL3_M1   0x00AAU
+#define CMN_PLL0_SS_CTRL4_M1   0x00ABU
 #define CMN_PLL1_VCOCAL_TCTRL  0x00C2U
 #define CMN_PLL1_VCOCAL_INIT_TMR   0x00C4U
 #define CMN_PLL1_VCOCAL_ITER_TMR   0x00C5U
@@ -130,8 +141,10 @@
 #define CMN_PDIAG_PLL0_CP_PADJ_M0  0x01A4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M0  0x01A5U
 #define CMN_PDIAG_PLL0_FILT_PADJ_M00x01A6U
+#define CMN_PDIAG_PLL0_CTRL_M1 0x01B0U
 #define CMN_PDIAG_PLL0_CP_PADJ_M1  0x01B4U
 #define CMN_PDIAG_PLL0_CP_IADJ_M1  0x01B5U
+#define CMN_PDIAG_PLL0_FILT_PADJ_M10x01B6U
 #define CMN_PDIAG_PLL1_CTRL_M0 0x01C0U
 #define CMN_PDIAG_PLL1_CLK_SEL_M0  0x01C1U
 #define CMN_PDIAG_PLL1_CP_PADJ_M0  0x01C4U
@@ -162,6 +175,9 @@
 #define RX_REE_GCSM1_CTRL  0x0108U
 #define RX_REE_GCSM2_CTRL  0x0110U
 #define RX_REE_PERGCSM_CTRL0x0118U
+#define RX_REE_TAP1_CLIP   0x0171U
+#define RX_REE_TAP2TON_CLIP0x0172U
+#define RX_DIAG_ACYA   0x01FFU
 
 /* PHY PCS common registers */
 #define PHY_PLL_CFG0x000EU
@@ -182,12 +198,24 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
 static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
+enum cdns_torrent_phy_type {
+   TYPE_DP,
+   TYPE_PCIE
+};
+
+enum cdns_torrent_ssc_mode {
+   NO_SSC,
+   EXTERNAL_SSC,
+   INTERNAL_SSC
+};
+
 struct cdns_torrent_inst {
struct phy *phy;
u32 mlane;
-   u32 phy_type;
+   enum cdns_torrent_phy_type phy_type;
u32 num_lanes;
struct reset_control *lnk_rst;
+   enum cdns_torrent_ssc_mode ssc_mode;
 };
 
 struct cdns_torrent_phy {
@@ -221,8 +249,9 @@ enum phy_powerstate {
POWERSTATE_A3 = 3,
 };
 
+static int cdns_torrent_phy_init(struct phy *phy);
+static int cdns_torrent_phy_exit(struct phy *phy);
 static int cdns_torrent_dp_init(struct phy *phy);
-static int cdns_torrent_dp_exit(struct phy *phy);
 static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
   u32 num_lanes);
 static
@@ -252,17 +281,30 @@ static int cdns_torrent_phy_on(struct phy *phy);
 static int cdns_torrent_phy_off(struct phy *phy);
 
 static const struct phy_ops cdns_torrent_phy_ops = {
-   .init   = cdns_torrent_dp_init,
-   .exit   = cdns_torrent_dp_exit,
+   .init   = cdns_torrent_phy_init,
+   .exit   = cdns_torrent_phy_exit,
.configure  = cdns_torrent_dp_configure,
.power_on   = cdns_torrent_phy_on,
.power_off  = cdns_torrent_phy_off,
.owner  = THIS_MODULE,
 };
 
+struct cdns_reg_pairs {
+   u32 val;
+   u32 off;
+};
+
+struct cdns_torrent_vals {
+   struct cdns_reg_pairs *reg_pairs;
+   u32 num_regs;
+};
+
 struct cdns_torrent_data {
-   u8 block_offset_shift;
-   u8 reg_offset_shift;
+   u8 block_offset_shift;
+   u8 reg_offset_shift;
+   struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
+   struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_SSC_MODE];
 };
 
 struct cdns_regmap_cdb_context {
@@ -846,19 +888,6 @@ static int cdns_torrent_dp_init(struct phy *phy)
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
 
-   ret = clk_prepare_enable(cdns_phy->clk);
-   if (ret) {
-   dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
-   return ret;
-   }
-
-   cdns_phy->ref_clk_rate = c

[PATCH v1 1/7] phy: cadence-torrent: Use of_device_get_match_data() to get driver data

2020-08-07 Thread Swapnil Jakhade
Use of_device_get_match_data() to get driver data instead of boilerplate
code.

Signed-off-by: Swapnil Jakhade 
---
 drivers/phy/cadence/phy-cadence-torrent.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c 
b/drivers/phy/cadence/phy-cadence-torrent.c
index af81707ff0c6..50c30d49300e 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -183,8 +183,6 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
 static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
 
-static const struct of_device_id cdns_torrent_phy_of_match[];
-
 struct cdns_torrent_inst {
struct phy *phy;
u32 mlane;
@@ -203,6 +201,7 @@ struct cdns_torrent_phy {
unsigned long ref_clk_rate;
struct cdns_torrent_inst phys[MAX_NUM_LANES];
int nsubnodes;
+   const struct cdns_torrent_data *init_data;
struct regmap *regmap;
struct regmap *regmap_common_cdb;
struct regmap *regmap_phy_pcs_common_cdb;
@@ -1711,24 +1710,22 @@ static int cdns_torrent_phy_probe(struct 
platform_device *pdev)
struct device *dev = >dev;
struct phy_provider *phy_provider;
struct phy_attrs torrent_attr;
-   const struct of_device_id *match;
-   struct cdns_torrent_data *data;
+   const struct cdns_torrent_data *data;
struct device_node *child;
int ret, subnodes, node = 0, i;
 
/* Get init data for this PHY */
-   match = of_match_device(cdns_torrent_phy_of_match, dev);
-   if (!match)
+   data = of_device_get_match_data(dev);
+   if (!data)
return -EINVAL;
 
-   data = (struct cdns_torrent_data *)match->data;
-
cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
if (!cdns_phy)
return -ENOMEM;
 
dev_set_drvdata(dev, cdns_phy);
cdns_phy->dev = dev;
+   cdns_phy->init_data = data;
 
cdns_phy->phy_rst = devm_reset_control_get_exclusive_by_index(dev, 0);
if (IS_ERR(cdns_phy->phy_rst)) {
-- 
2.26.1



[PATCH v1 7/7] dt-bindings: phy: cadence-torrent: Update Torrent PHY bindings for generic use

2020-08-07 Thread Swapnil Jakhade
Torrent PHY can be used in different multi-link multi-protocol
configurations including protocols other than DisplayPort also,
such as PCIe, USB, SGMII, QSGMII etc. Update the bindings to have
support for these configurations.

Signed-off-by: Swapnil Jakhade 
---
 .../bindings/phy/phy-cadence-torrent.yaml | 76 ++-
 1 file changed, 58 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml 
b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
index a7ee19d27c19..b2275712363d 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
@@ -4,11 +4,13 @@
 $id: "http://devicetree.org/schemas/phy/phy-cadence-torrent.yaml#;
 $schema: "http://devicetree.org/meta-schemas/core.yaml#;
 
-title: Cadence Torrent SD0801 PHY binding for DisplayPort
+title: Cadence Torrent SD0801 PHY binding
 
 description:
   This binding describes the Cadence SD0801 PHY (also known as Torrent PHY)
-  hardware included with the Cadence MHDP DisplayPort controller.
+  hardware included with the Cadence MHDP DisplayPort controller. Torrent
+  PHY also supports multilink multiprotocol combinations including protocols
+  such as PCIe, USB, SGMII, QSGMII etc.
 
 maintainers:
   - Swapnil Jakhade 
@@ -49,13 +51,14 @@ properties:
   - const: dptx_phy
 
   resets:
-maxItems: 1
-description:
-  Torrent PHY reset.
-  See Documentation/devicetree/bindings/reset/reset.txt
+minItems: 1
+maxItems: 2
+items:
+  - description: Torrent PHY reset.
+  - description: Torrent APB reset. This is optional.
 
 patternProperties:
-  '^phy@[0-7]+$':
+  '^link@[0-7]+$':
 type: object
 description:
   Each group of PHY lanes with a single master lane should be represented 
as a sub-node.
@@ -78,13 +81,13 @@ patternProperties:
   Specifies the type of PHY for which the group of PHY lanes is used.
   Refer include/dt-bindings/phy/phy.h. Constants from the header 
should be used.
 $ref: /schemas/types.yaml#/definitions/uint32
-enum: [1, 2, 3, 4, 5, 6]
+enum: [1, 2, 3, 4, 5, 6, 7, 8, 9]
 
   cdns,num-lanes:
 description:
-  Number of DisplayPort lanes.
+  Number of lanes.
 $ref: /schemas/types.yaml#/definitions/uint32
-enum: [1, 2, 4]
+enum: [1, 2, 3, 4]
 default: 4
 
   cdns,ssc-mode:
@@ -108,6 +111,7 @@ patternProperties:
   - resets
   - "#phy-cells"
   - cdns,phy-type
+  - cdns,num-lanes
 
 additionalProperties: false
 
@@ -141,15 +145,51 @@ examples:
 clock-names = "refclk";
 #address-cells = <1>;
 #size-cells = <0>;
-phy@0 {
-  reg = <0>;
-  resets = < 1>, < 2>,
-   < 3>, < 4>;
-  #phy-cells = <0>;
-  cdns,phy-type = ;
-  cdns,num-lanes = <4>;
-  cdns,max-bit-rate = <8100>;
+link@0 {
+reg = <0>;
+resets = < 1>, < 2>,
+ < 3>, < 4>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <4>;
+cdns,max-bit-rate = <8100>;
+};
+};
+};
+  - |
+#include 
+#include 
+
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+
+torrent-phy@f0fb50 {
+compatible = "cdns,torrent-phy";
+reg = <0xf0 0xfb50 0x0 0x0010>;
+reg-names = "torrent_phy";
+resets = < 0>, < 1>;
+clocks = <_clk>;
+clock-names = "refclk";
+#address-cells = <1>;
+#size-cells = <0>;
+link@0 {
+reg = <0>;
+resets = < 2>, < 3>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <2>;
+cdns,ssc-mode = ;
 };
+
+link@2 {
+reg = <2>;
+resets = < 4>;
+#phy-cells = <0>;
+cdns,phy-type = ;
+cdns,num-lanes = <1>;
+cdns,ssc-mode = ;
+   };
 };
 };
 ...
-- 
2.26.1



[PATCH v1 0/7] PHY: Prepare Cadence Torrent PHY driver to support multilink configurations

2020-08-07 Thread Swapnil Jakhade
Cadence Torrent PHY is a multiprotocol PHY supporting different multilink
PHY configurations including DisplayPort, PCIe, USB, SGMII, QSGMII etc.
Existing Torrent PHY driver supports only DisplayPort. This patch series
prepares Torrent PHY driver so that different multilink configurations can
be supported. It also updates DT bindings accordingly.

Support for different multilink configurations with register sequences for
protocols above will be added in a separate patch series.

This patch series is dependent on PHY patch series [1].

[1] https://lkml.org/lkml/2020/7/17/158

Swapnil Jakhade (7):
  phy: cadence-torrent: Use of_device_get_match_data() to get driver
data
  phy: cadence-torrent: Use devm_platform_ioremap_resource() to get reg
addresses
  phy: cadence-torrent: Enable support for multiple subnodes
  phy: cadence-torrent: Add separate regmap functions for torrent and DP
  phy: cadence-torrent: Check total lane count for all subnodes is
within limit
  dt-bindings: phy: cadence-torrent: Add binding to specify SSC mode
  dt-bindings: phy: cadence-torrent: Update Torrent PHY bindings for
generic use

 .../bindings/phy/phy-cadence-torrent.yaml |  85 +++---
 drivers/phy/cadence/phy-cadence-torrent.c | 146 ++
 include/dt-bindings/phy/phy-cadence-torrent.h |  13 ++
 3 files changed, 164 insertions(+), 80 deletions(-)
 create mode 100644 include/dt-bindings/phy/phy-cadence-torrent.h

-- 
2.26.1



  1   2   >