diff options
Diffstat (limited to 'drivers')
78 files changed, 4249 insertions, 1280 deletions
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index e53a9a9317bc..b0f19e950601 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -683,7 +683,7 @@ static int sun4i_usb_phy0_vbus_notify(struct notifier_block *nb,  }  static struct phy *sun4i_usb_phy_xlate(struct device *dev, -					struct of_phandle_args *args) +					const struct of_phandle_args *args)  {  	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c index 2712c4bd549d..5468831d6ab9 100644 --- a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c +++ b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c @@ -350,7 +350,7 @@ static int phy_g12a_usb3_pcie_exit(struct phy *phy)  }  static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev, -					    struct of_phandle_args *args) +					    const struct of_phandle_args *args)  {  	struct phy_g12a_usb3_pcie_priv *priv = dev_get_drvdata(dev);  	unsigned int mode; diff --git a/drivers/phy/broadcom/phy-bcm-sr-pcie.c b/drivers/phy/broadcom/phy-bcm-sr-pcie.c index 8a4aadf166cf..ff9b3862bf7a 100644 --- a/drivers/phy/broadcom/phy-bcm-sr-pcie.c +++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c @@ -195,7 +195,7 @@ static const struct phy_ops sr_paxc_phy_ops = {  };  static struct phy *sr_pcie_phy_xlate(struct device *dev, -				     struct of_phandle_args *args) +				     const struct of_phandle_args *args)  {  	struct sr_pcie_phy_core *core;  	int phy_idx; diff --git a/drivers/phy/broadcom/phy-bcm-sr-usb.c b/drivers/phy/broadcom/phy-bcm-sr-usb.c index b0bd18a5df87..6bcfe83609c8 100644 --- a/drivers/phy/broadcom/phy-bcm-sr-usb.c +++ b/drivers/phy/broadcom/phy-bcm-sr-usb.c @@ -209,7 +209,7 @@ static const struct phy_ops sr_phy_ops = {  };  static struct phy *bcm_usb_phy_xlate(struct device *dev, -				     struct of_phandle_args *args) +				     const struct of_phandle_args *args)  {  	struct bcm_usb_phy_cfg *phy_cfg;  	int phy_idx; diff --git a/drivers/phy/broadcom/phy-bcm63xx-usbh.c b/drivers/phy/broadcom/phy-bcm63xx-usbh.c index f8183dea774b..647644de041b 100644 --- a/drivers/phy/broadcom/phy-bcm63xx-usbh.c +++ b/drivers/phy/broadcom/phy-bcm63xx-usbh.c @@ -366,7 +366,7 @@ static const struct phy_ops bcm63xx_usbh_phy_ops = {  };  static struct phy *bcm63xx_usbh_phy_xlate(struct device *dev, -					  struct of_phandle_args *args) +					  const struct of_phandle_args *args)  {  	struct bcm63xx_usbh_phy *usbh = dev_get_drvdata(dev); diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c index a16f0b58eb74..ad2eec095601 100644 --- a/drivers/phy/broadcom/phy-brcm-usb.c +++ b/drivers/phy/broadcom/phy-brcm-usb.c @@ -175,7 +175,7 @@ static const struct phy_ops brcm_usb_phy_ops = {  };  static struct phy *brcm_usb_phy_xlate(struct device *dev, -				      struct of_phandle_args *args) +				      const struct of_phandle_args *args)  {  	struct brcm_usb_phy_data *data = dev_get_drvdata(dev); diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index a75c96385c57..95924a09960c 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -355,7 +355,9 @@ struct cdns_torrent_phy {  	struct reset_control *apb_rst;  	struct device *dev;  	struct clk *clk; +	struct clk *clk1;  	enum cdns_torrent_ref_clk ref_clk_rate; +	enum cdns_torrent_ref_clk ref_clk1_rate;  	struct cdns_torrent_inst phys[MAX_NUM_LANES];  	int nsubnodes;  	const struct cdns_torrent_data *init_data; @@ -2460,9 +2462,11 @@ 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_clk1 = cdns_phy->ref_clk1_rate;  	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; +	struct cdns_torrent_vals *phy_pma_cmn_vals;  	struct cdns_torrent_vals *pcs_cmn_vals;  	int i, j, node, mlane, num_lanes, ret;  	struct cdns_reg_pairs *reg_pairs; @@ -2489,6 +2493,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)  			 * Get the array values as [phy_t2][phy_t1][ssc].  			 */  			swap(phy_t1, phy_t2); +			swap(ref_clk, ref_clk1);  		}  		mlane = cdns_phy->phys[node].mlane; @@ -2552,9 +2557,22 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)  					     reg_pairs[i].val);  		} +		/* PHY PMA common registers configurations */ +		phy_pma_cmn_vals = cdns_torrent_get_tbl_vals(&init_data->phy_pma_cmn_vals_tbl, +							     CLK_ANY, CLK_ANY, +							     phy_t1, phy_t2, ANY_SSC); +		if (phy_pma_cmn_vals) { +			reg_pairs = phy_pma_cmn_vals->reg_pairs; +			num_regs = phy_pma_cmn_vals->num_regs; +			regmap = cdns_phy->regmap_phy_pma_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 = cdns_torrent_get_tbl_vals(&init_data->cmn_vals_tbl, -						     ref_clk, ref_clk, +						     ref_clk, ref_clk1,  						     phy_t1, phy_t2, ssc);  		if (cmn_vals) {  			reg_pairs = cmn_vals->reg_pairs; @@ -2567,7 +2585,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)  		/* PMA TX lane registers configurations */  		tx_ln_vals = cdns_torrent_get_tbl_vals(&init_data->tx_ln_vals_tbl, -						       ref_clk, ref_clk, +						       ref_clk, ref_clk1,  						       phy_t1, phy_t2, ssc);  		if (tx_ln_vals) {  			reg_pairs = tx_ln_vals->reg_pairs; @@ -2582,7 +2600,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)  		/* PMA RX lane registers configurations */  		rx_ln_vals = cdns_torrent_get_tbl_vals(&init_data->rx_ln_vals_tbl, -						       ref_clk, ref_clk, +						       ref_clk, ref_clk1,  						       phy_t1, phy_t2, ssc);  		if (rx_ln_vals) {  			reg_pairs = rx_ln_vals->reg_pairs; @@ -2684,9 +2702,11 @@ static int cdns_torrent_reset(struct cdns_torrent_phy *cdns_phy)  static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)  {  	struct device *dev = cdns_phy->dev; +	unsigned long ref_clk1_rate;  	unsigned long ref_clk_rate;  	int ret; +	/* refclk: Input reference clock for PLL0 */  	cdns_phy->clk = devm_clk_get(dev, "refclk");  	if (IS_ERR(cdns_phy->clk)) {  		dev_err(dev, "phy ref clock not found\n"); @@ -2695,15 +2715,15 @@ static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)  	ret = clk_prepare_enable(cdns_phy->clk);  	if (ret) { -		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n"); +		dev_err(cdns_phy->dev, "Failed to prepare ref clock: %d\n", ret);  		return ret;  	}  	ref_clk_rate = clk_get_rate(cdns_phy->clk);  	if (!ref_clk_rate) {  		dev_err(cdns_phy->dev, "Failed to get ref clock rate\n"); -		clk_disable_unprepare(cdns_phy->clk); -		return -EINVAL; +		ret = -EINVAL; +		goto disable_clk;  	}  	switch (ref_clk_rate) { @@ -2720,12 +2740,62 @@ static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)  		cdns_phy->ref_clk_rate = CLK_156_25_MHZ;  		break;  	default: -		dev_err(cdns_phy->dev, "Invalid Ref Clock Rate\n"); -		clk_disable_unprepare(cdns_phy->clk); -		return -EINVAL; +		dev_err(cdns_phy->dev, "Invalid ref clock rate\n"); +		ret = -EINVAL; +		goto disable_clk; +	} + +	/* refclk1: Input reference clock for PLL1 */ +	cdns_phy->clk1 = devm_clk_get_optional(dev, "pll1_refclk"); +	if (IS_ERR(cdns_phy->clk1)) { +		dev_err(dev, "phy PLL1 ref clock not found\n"); +		ret = PTR_ERR(cdns_phy->clk1); +		goto disable_clk; +	} + +	if (cdns_phy->clk1) { +		ret = clk_prepare_enable(cdns_phy->clk1); +		if (ret) { +			dev_err(cdns_phy->dev, "Failed to prepare PLL1 ref clock: %d\n", ret); +			goto disable_clk; +		} + +		ref_clk1_rate = clk_get_rate(cdns_phy->clk1); +		if (!ref_clk1_rate) { +			dev_err(cdns_phy->dev, "Failed to get PLL1 ref clock rate\n"); +			ret = -EINVAL; +			goto disable_clk1; +		} + +		switch (ref_clk1_rate) { +		case REF_CLK_19_2MHZ: +			cdns_phy->ref_clk1_rate = CLK_19_2_MHZ; +			break; +		case REF_CLK_25MHZ: +			cdns_phy->ref_clk1_rate = CLK_25_MHZ; +			break; +		case REF_CLK_100MHZ: +			cdns_phy->ref_clk1_rate = CLK_100_MHZ; +			break; +		case REF_CLK_156_25MHZ: +			cdns_phy->ref_clk1_rate = CLK_156_25_MHZ; +			break; +		default: +			dev_err(cdns_phy->dev, "Invalid PLL1 ref clock rate\n"); +			ret = -EINVAL; +			goto disable_clk1; +		} +	} else { +		cdns_phy->ref_clk1_rate = cdns_phy->ref_clk_rate;  	}  	return 0; + +disable_clk1: +	clk_disable_unprepare(cdns_phy->clk1); +disable_clk: +	clk_disable_unprepare(cdns_phy->clk); +	return ret;  }  static int cdns_torrent_phy_probe(struct platform_device *pdev) @@ -2980,6 +3050,7 @@ put_lnk_rst:  		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->clk1);  	clk_disable_unprepare(cdns_phy->clk);  clk_cleanup:  	cdns_torrent_clk_cleanup(cdns_phy); @@ -2998,6 +3069,7 @@ static void cdns_torrent_phy_remove(struct platform_device *pdev)  		reset_control_put(cdns_phy->phys[i].lnk_rst);  	} +	clk_disable_unprepare(cdns_phy->clk1);  	clk_disable_unprepare(cdns_phy->clk);  	cdns_torrent_clk_cleanup(cdns_phy);  } @@ -3034,6 +3106,216 @@ static struct cdns_torrent_vals dp_usb_xcvr_diag_ln_vals = {  	.num_regs = ARRAY_SIZE(dp_usb_xcvr_diag_ln_regs),  }; +/* USXGMII and SGMII/QSGMII link configuration */ +static struct cdns_reg_pairs usxgmii_sgmii_link_cmn_regs[] = { +	{0x0002, PHY_PLL_CFG}, +	{0x0400, CMN_PDIAG_PLL0_CLK_SEL_M0}, +	{0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0} +}; + +static struct cdns_reg_pairs usxgmii_sgmii_xcvr_diag_ln_regs[] = { +	{0x0000, XCVR_DIAG_HSCLK_SEL}, +	{0x0001, XCVR_DIAG_HSCLK_DIV}, +	{0x0001, XCVR_DIAG_PLLDRC_CTRL} +}; + +static struct cdns_reg_pairs sgmii_usxgmii_xcvr_diag_ln_regs[] = { +	{0x0111, XCVR_DIAG_HSCLK_SEL}, +	{0x0103, XCVR_DIAG_HSCLK_DIV}, +	{0x0A9B, XCVR_DIAG_PLLDRC_CTRL} +}; + +static struct cdns_torrent_vals usxgmii_sgmii_link_cmn_vals = { +	.reg_pairs = usxgmii_sgmii_link_cmn_regs, +	.num_regs = ARRAY_SIZE(usxgmii_sgmii_link_cmn_regs), +}; + +static struct cdns_torrent_vals usxgmii_sgmii_xcvr_diag_ln_vals = { +	.reg_pairs = usxgmii_sgmii_xcvr_diag_ln_regs, +	.num_regs = ARRAY_SIZE(usxgmii_sgmii_xcvr_diag_ln_regs), +}; + +static struct cdns_torrent_vals sgmii_usxgmii_xcvr_diag_ln_vals = { +	.reg_pairs = sgmii_usxgmii_xcvr_diag_ln_regs, +	.num_regs = ARRAY_SIZE(sgmii_usxgmii_xcvr_diag_ln_regs), +}; + +/* Multilink USXGMII, using PLL0, 156.25 MHz Ref clk, no SSC */ +static struct cdns_reg_pairs ml_usxgmii_pll0_156_25_no_ssc_cmn_regs[] = { +	{0x0014, CMN_PLL0_DSM_FBH_OVRD_M0}, +	{0x0005, CMN_PLL0_DSM_FBL_OVRD_M0}, +	{0x061B, CMN_PLL0_VCOCAL_INIT_TMR}, +	{0x0019, CMN_PLL0_VCOCAL_ITER_TMR}, +	{0x1354, CMN_PLL0_VCOCAL_REFTIM_START}, +	{0x1354, CMN_PLL0_VCOCAL_PLLCNT_START}, +	{0x0003, CMN_PLL0_VCOCAL_TCTRL}, +	{0x0138, CMN_PLL0_LOCK_REFCNT_START}, +	{0x0138, CMN_PLL0_LOCK_PLLCNT_START} +}; + +static struct cdns_torrent_vals ml_usxgmii_pll0_156_25_no_ssc_cmn_vals = { +	.reg_pairs = ml_usxgmii_pll0_156_25_no_ssc_cmn_regs, +	.num_regs = ARRAY_SIZE(ml_usxgmii_pll0_156_25_no_ssc_cmn_regs), +}; + +/* Multilink SGMII/QSGMII, using PLL1, 100 MHz Ref clk, no SSC */ +static struct cdns_reg_pairs ml_sgmii_pll1_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_PLL1_VCOCAL_TCTRL}, +	{0x007F, CMN_TXPUCAL_TUNE}, +	{0x007F, CMN_TXPDCAL_TUNE} +}; + +static struct cdns_torrent_vals ml_sgmii_pll1_100_no_ssc_cmn_vals = { +	.reg_pairs = ml_sgmii_pll1_100_no_ssc_cmn_regs, +	.num_regs = ARRAY_SIZE(ml_sgmii_pll1_100_no_ssc_cmn_regs), +}; + +/* TI J7200, Multilink USXGMII, using PLL0, 156.25 MHz Ref clk, no SSC */ +static struct cdns_reg_pairs j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_regs[] = { +	{0x0014, CMN_SSM_BIAS_TMR}, +	{0x0028, CMN_PLLSM0_PLLPRE_TMR}, +	{0x00A4, CMN_PLLSM0_PLLLOCK_TMR}, +	{0x0062, CMN_BGCAL_INIT_TMR}, +	{0x0062, CMN_BGCAL_ITER_TMR}, +	{0x0014, CMN_IBCAL_INIT_TMR}, +	{0x0018, CMN_TXPUCAL_INIT_TMR}, +	{0x0005, CMN_TXPUCAL_ITER_TMR}, +	{0x0018, CMN_TXPDCAL_INIT_TMR}, +	{0x0005, CMN_TXPDCAL_ITER_TMR}, +	{0x024A, CMN_RXCAL_INIT_TMR}, +	{0x0005, CMN_RXCAL_ITER_TMR}, +	{0x000B, CMN_SD_CAL_REFTIM_START}, +	{0x0132, CMN_SD_CAL_PLLCNT_START}, +	{0x0014, CMN_PLL0_DSM_FBH_OVRD_M0}, +	{0x0005, CMN_PLL0_DSM_FBL_OVRD_M0}, +	{0x061B, CMN_PLL0_VCOCAL_INIT_TMR}, +	{0x0019, CMN_PLL0_VCOCAL_ITER_TMR}, +	{0x1354, CMN_PLL0_VCOCAL_REFTIM_START}, +	{0x1354, CMN_PLL0_VCOCAL_PLLCNT_START}, +	{0x0003, CMN_PLL0_VCOCAL_TCTRL}, +	{0x0138, CMN_PLL0_LOCK_REFCNT_START}, +	{0x0138, CMN_PLL0_LOCK_PLLCNT_START} +}; + +static struct cdns_torrent_vals j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_vals = { +	.reg_pairs = j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_regs, +	.num_regs = ARRAY_SIZE(j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_regs), +}; + +/* TI J7200, Multilink SGMII/QSGMII, using PLL1, 100 MHz Ref clk, no SSC */ +static struct cdns_reg_pairs j7200_ml_sgmii_pll1_100_no_ssc_cmn_regs[] = { +	{0x0028, CMN_PLLSM1_PLLPRE_TMR}, +	{0x00A4, CMN_PLLSM1_PLLLOCK_TMR}, +	{0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0}, +	{0x001E, CMN_PLL1_DSM_FBH_OVRD_M0}, +	{0x000C, CMN_PLL1_DSM_FBL_OVRD_M0}, +	{0x0003, CMN_PLL1_VCOCAL_TCTRL}, +	{0x007F, CMN_TXPUCAL_TUNE}, +	{0x007F, CMN_TXPDCAL_TUNE} +}; + +static struct cdns_torrent_vals j7200_ml_sgmii_pll1_100_no_ssc_cmn_vals = { +	.reg_pairs = j7200_ml_sgmii_pll1_100_no_ssc_cmn_regs, +	.num_regs = ARRAY_SIZE(j7200_ml_sgmii_pll1_100_no_ssc_cmn_regs), +}; + +/* PCIe and USXGMII link configuration */ +static struct cdns_reg_pairs pcie_usxgmii_link_cmn_regs[] = { +	{0x0003, PHY_PLL_CFG}, +	{0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0}, +	{0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1}, +	{0x0400, CMN_PDIAG_PLL1_CLK_SEL_M0} +}; + +static struct cdns_reg_pairs pcie_usxgmii_xcvr_diag_ln_regs[] = { +	{0x0000, XCVR_DIAG_HSCLK_SEL}, +	{0x0001, XCVR_DIAG_HSCLK_DIV}, +	{0x0012, XCVR_DIAG_PLLDRC_CTRL} +}; + +static struct cdns_reg_pairs usxgmii_pcie_xcvr_diag_ln_regs[] = { +	{0x0011, XCVR_DIAG_HSCLK_SEL}, +	{0x0001, XCVR_DIAG_HSCLK_DIV}, +	{0x0089, XCVR_DIAG_PLLDRC_CTRL} +}; + +static struct cdns_torrent_vals pcie_usxgmii_link_cmn_vals = { +	.reg_pairs = pcie_usxgmii_link_cmn_regs, +	.num_regs = ARRAY_SIZE(pcie_usxgmii_link_cmn_regs), +}; + +static struct cdns_torrent_vals pcie_usxgmii_xcvr_diag_ln_vals = { +	.reg_pairs = pcie_usxgmii_xcvr_diag_ln_regs, +	.num_regs = ARRAY_SIZE(pcie_usxgmii_xcvr_diag_ln_regs), +}; + +static struct cdns_torrent_vals usxgmii_pcie_xcvr_diag_ln_vals = { +	.reg_pairs = usxgmii_pcie_xcvr_diag_ln_regs, +	.num_regs = ARRAY_SIZE(usxgmii_pcie_xcvr_diag_ln_regs), +}; + +/* + * Multilink USXGMII, using PLL1, 156.25 MHz Ref clk, no SSC + */ +static struct cdns_reg_pairs ml_usxgmii_pll1_156_25_no_ssc_cmn_regs[] = { +	{0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0}, +	{0x0014, CMN_PLL1_DSM_FBH_OVRD_M0}, +	{0x0005, CMN_PLL1_DSM_FBL_OVRD_M0}, +	{0x061B, CMN_PLL1_VCOCAL_INIT_TMR}, +	{0x0019, CMN_PLL1_VCOCAL_ITER_TMR}, +	{0x1354, CMN_PLL1_VCOCAL_REFTIM_START}, +	{0x1354, CMN_PLL1_VCOCAL_PLLCNT_START}, +	{0x0003, CMN_PLL1_VCOCAL_TCTRL}, +	{0x0138, CMN_PLL1_LOCK_REFCNT_START}, +	{0x0138, CMN_PLL1_LOCK_PLLCNT_START}, +	{0x007F, CMN_TXPUCAL_TUNE}, +	{0x007F, CMN_TXPDCAL_TUNE} +}; + +static struct cdns_reg_pairs ml_usxgmii_156_25_no_ssc_tx_ln_regs[] = { +	{0x00F3, TX_PSC_A0}, +	{0x04A2, TX_PSC_A2}, +	{0x04A2, TX_PSC_A3 }, +	{0x0000, TX_TXCC_CPOST_MULT_00}, +	{0x0000, XCVR_DIAG_PSC_OVRD} +}; + +static struct cdns_reg_pairs ml_usxgmii_156_25_no_ssc_rx_ln_regs[] = { +	{0x091D, RX_PSC_A0}, +	{0x0900, RX_PSC_A2}, +	{0x0100, RX_PSC_A3}, +	{0x0030, RX_REE_SMGM_CTRL1}, +	{0x03C7, RX_REE_GCSM1_EQENM_PH1}, +	{0x01C7, RX_REE_GCSM1_EQENM_PH2}, +	{0x0000, RX_DIAG_DFE_CTRL}, +	{0x0019, RX_REE_TAP1_CLIP}, +	{0x0019, RX_REE_TAP2TON_CLIP}, +	{0x00B9, RX_DIAG_NQST_CTRL}, +	{0x0C21, RX_DIAG_DFE_AMP_TUNE_2}, +	{0x0002, RX_DIAG_DFE_AMP_TUNE_3}, +	{0x0033, RX_DIAG_PI_RATE}, +	{0x0001, RX_DIAG_ACYA}, +	{0x018C, RX_CDRLF_CNFG} +}; + +static struct cdns_torrent_vals ml_usxgmii_pll1_156_25_no_ssc_cmn_vals = { +	.reg_pairs = ml_usxgmii_pll1_156_25_no_ssc_cmn_regs, +	.num_regs = ARRAY_SIZE(ml_usxgmii_pll1_156_25_no_ssc_cmn_regs), +}; + +static struct cdns_torrent_vals ml_usxgmii_156_25_no_ssc_tx_ln_vals = { +	.reg_pairs = ml_usxgmii_156_25_no_ssc_tx_ln_regs, +	.num_regs = ARRAY_SIZE(ml_usxgmii_156_25_no_ssc_tx_ln_regs), +}; + +static struct cdns_torrent_vals ml_usxgmii_156_25_no_ssc_rx_ln_vals = { +	.reg_pairs = ml_usxgmii_156_25_no_ssc_rx_ln_regs, +	.num_regs = ARRAY_SIZE(ml_usxgmii_156_25_no_ssc_rx_ln_regs), +}; +  /* TI USXGMII configuration: Enable cmn_refclk_rcv_out_en */  static struct cdns_reg_pairs ti_usxgmii_phy_pma_cmn_regs[] = {  	{0x0040, PHY_PMA_CMN_CTRL1}, @@ -3811,6 +4093,50 @@ static struct cdns_torrent_vals sgmii_100_no_ssc_rx_ln_vals = {  	.num_regs = ARRAY_SIZE(sgmii_100_no_ssc_rx_ln_regs),  }; +/* TI J7200, multilink SGMII */ +static struct cdns_reg_pairs j7200_sgmii_100_no_ssc_tx_ln_regs[] = { +	{0x07A2, TX_RCVDET_ST_TMR}, +	{0x00F3, TX_PSC_A0}, +	{0x04A2, TX_PSC_A2}, +	{0x04A2, TX_PSC_A3 }, +	{0x0000, TX_TXCC_CPOST_MULT_00}, +	{0x00B3, DRV_DIAG_TX_DRV}, +	{0x0002, XCVR_DIAG_PSC_OVRD}, +	{0x4000, XCVR_DIAG_RXCLK_CTRL} +}; + +static struct cdns_torrent_vals j7200_sgmii_100_no_ssc_tx_ln_vals = { +	.reg_pairs = j7200_sgmii_100_no_ssc_tx_ln_regs, +	.num_regs = ARRAY_SIZE(j7200_sgmii_100_no_ssc_tx_ln_regs), +}; + +static struct cdns_reg_pairs j7200_sgmii_100_no_ssc_rx_ln_regs[] = { +	{0x0014, RX_SDCAL0_INIT_TMR}, +	{0x0062, RX_SDCAL0_ITER_TMR}, +	{0x0014, RX_SDCAL1_INIT_TMR}, +	{0x0062, RX_SDCAL1_ITER_TMR}, +	{0x091D, RX_PSC_A0}, +	{0x0900, RX_PSC_A2}, +	{0x0100, RX_PSC_A3}, +	{0x03C7, RX_REE_GCSM1_EQENM_PH1}, +	{0x01C7, RX_REE_GCSM1_EQENM_PH2}, +	{0x0000, RX_DIAG_DFE_CTRL}, +	{0x0019, RX_REE_TAP1_CLIP}, +	{0x0019, RX_REE_TAP2TON_CLIP}, +	{0x0098, RX_DIAG_NQST_CTRL}, +	{0x0C01, RX_DIAG_DFE_AMP_TUNE_2}, +	{0x0000, RX_DIAG_DFE_AMP_TUNE_3}, +	{0x0000, RX_DIAG_PI_CAP}, +	{0x0010, RX_DIAG_PI_RATE}, +	{0x0001, RX_DIAG_ACYA}, +	{0x018C, RX_CDRLF_CNFG} +}; + +static struct cdns_torrent_vals j7200_sgmii_100_no_ssc_rx_ln_vals = { +	.reg_pairs = j7200_sgmii_100_no_ssc_rx_ln_regs, +	.num_regs = ARRAY_SIZE(j7200_sgmii_100_no_ssc_rx_ln_regs), +}; +  /* SGMII 100 MHz Ref clk, internal SSC */  static struct cdns_reg_pairs sgmii_100_int_ssc_cmn_regs[] = {  	{0x0004, CMN_PLL0_DSM_DIAG_M0}, @@ -3944,6 +4270,51 @@ static struct cdns_torrent_vals qsgmii_100_no_ssc_rx_ln_vals = {  	.num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_rx_ln_regs),  }; +/* TI J7200, multilink QSGMII */ +static struct cdns_reg_pairs j7200_qsgmii_100_no_ssc_tx_ln_regs[] = { +	{0x07A2, TX_RCVDET_ST_TMR}, +	{0x00F3, TX_PSC_A0}, +	{0x04A2, TX_PSC_A2}, +	{0x04A2, TX_PSC_A3 }, +	{0x0000, TX_TXCC_CPOST_MULT_00}, +	{0x0011, TX_TXCC_MGNFS_MULT_100}, +	{0x0003, DRV_DIAG_TX_DRV}, +	{0x0002, XCVR_DIAG_PSC_OVRD}, +	{0x4000, XCVR_DIAG_RXCLK_CTRL} +}; + +static struct cdns_torrent_vals j7200_qsgmii_100_no_ssc_tx_ln_vals = { +	.reg_pairs = j7200_qsgmii_100_no_ssc_tx_ln_regs, +	.num_regs = ARRAY_SIZE(j7200_qsgmii_100_no_ssc_tx_ln_regs), +}; + +static struct cdns_reg_pairs j7200_qsgmii_100_no_ssc_rx_ln_regs[] = { +	{0x0014, RX_SDCAL0_INIT_TMR}, +	{0x0062, RX_SDCAL0_ITER_TMR}, +	{0x0014, RX_SDCAL1_INIT_TMR}, +	{0x0062, RX_SDCAL1_ITER_TMR}, +	{0x091D, RX_PSC_A0}, +	{0x0900, RX_PSC_A2}, +	{0x0100, RX_PSC_A3}, +	{0x03C7, RX_REE_GCSM1_EQENM_PH1}, +	{0x01C7, RX_REE_GCSM1_EQENM_PH2}, +	{0x0000, RX_DIAG_DFE_CTRL}, +	{0x0019, RX_REE_TAP1_CLIP}, +	{0x0019, RX_REE_TAP2TON_CLIP}, +	{0x0098, RX_DIAG_NQST_CTRL}, +	{0x0C01, RX_DIAG_DFE_AMP_TUNE_2}, +	{0x0000, RX_DIAG_DFE_AMP_TUNE_3}, +	{0x0000, RX_DIAG_PI_CAP}, +	{0x0010, RX_DIAG_PI_RATE}, +	{0x0001, RX_DIAG_ACYA}, +	{0x018C, RX_CDRLF_CNFG} +}; + +static struct cdns_torrent_vals j7200_qsgmii_100_no_ssc_rx_ln_vals = { +	.reg_pairs = j7200_qsgmii_100_no_ssc_rx_ln_regs, +	.num_regs = ARRAY_SIZE(j7200_qsgmii_100_no_ssc_rx_ln_regs), +}; +  /* QSGMII 100 MHz Ref clk, internal SSC */  static struct cdns_reg_pairs qsgmii_100_int_ssc_cmn_regs[] = {  	{0x0004, CMN_PLL0_DSM_DIAG_M0}, @@ -4166,14 +4537,17 @@ static struct cdns_torrent_vals_entry link_cmn_vals_entries[] = {  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_QSGMII), &pcie_sgmii_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_link_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_NONE), &sl_sgmii_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_PCIE), &pcie_sgmii_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USB), &usb_sgmii_link_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USXGMII), &usxgmii_sgmii_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_NONE), &sl_sgmii_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_PCIE), &pcie_sgmii_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USB), &usb_sgmii_link_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USXGMII), &usxgmii_sgmii_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_NONE), &sl_usb_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE), &pcie_usb_link_cmn_vals}, @@ -4182,6 +4556,9 @@ static struct cdns_torrent_vals_entry link_cmn_vals_entries[] = {  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_DP), &usb_dp_link_cmn_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_NONE), &sl_usxgmii_link_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &pcie_usxgmii_link_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_link_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_link_cmn_vals},  };  static struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = { @@ -4194,14 +4571,17 @@ static struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_QSGMII), &pcie_sgmii_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_xcvr_diag_ln_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_NONE), &sl_sgmii_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_PCIE), &sgmii_pcie_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USB), &sgmii_usb_xcvr_diag_ln_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USXGMII), &sgmii_usxgmii_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_NONE), &sl_sgmii_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_PCIE), &sgmii_pcie_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USB), &sgmii_usb_xcvr_diag_ln_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USXGMII), &sgmii_usxgmii_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_NONE), &sl_usb_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE), &usb_pcie_xcvr_diag_ln_vals}, @@ -4210,6 +4590,9 @@ static struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_DP), &usb_dp_xcvr_diag_ln_vals},  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_NONE), &sl_usxgmii_xcvr_diag_ln_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &usxgmii_pcie_xcvr_diag_ln_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_xcvr_diag_ln_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_xcvr_diag_ln_vals},  };  static struct cdns_torrent_vals_entry pcs_cmn_vals_entries[] = { @@ -4285,6 +4668,17 @@ static struct cdns_torrent_vals_entry cmn_vals_entries[] = {  	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals},  	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals}, + +	/* Dual refclk */ +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &ml_sgmii_pll1_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &ml_sgmii_pll1_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_pll1_156_25_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &ml_usxgmii_pll0_156_25_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &ml_usxgmii_pll0_156_25_no_ssc_cmn_vals},  };  static struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = { @@ -4352,6 +4746,17 @@ static struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = {  	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals},  	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, + +	/* Dual refclk */ +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &sgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &qsgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},  };  static struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = { @@ -4419,6 +4824,17 @@ static struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = {  	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals},  	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals}, + +	/* Dual refclk */ +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_rx_ln_vals},  };  static const struct cdns_torrent_data cdns_map_torrent = { @@ -4452,6 +4868,9 @@ static const struct cdns_torrent_data cdns_map_torrent = {  static struct cdns_torrent_vals_entry j721e_phy_pma_cmn_vals_entries[] = {  	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_NONE), &ti_usxgmii_phy_pma_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &ti_usxgmii_phy_pma_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &ti_usxgmii_phy_pma_cmn_vals}, +	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &ti_usxgmii_phy_pma_cmn_vals},  };  static struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = { @@ -4519,6 +4938,17 @@ static struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = {  	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals},  	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, + +	/* Dual refclk */ +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals},  };  static const struct cdns_torrent_data ti_j721e_map_torrent = { @@ -4554,6 +4984,274 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {  	},  }; +/* TI J7200 (Torrent SD0805) */ +static struct cdns_torrent_vals_entry ti_j7200_cmn_vals_entries[] = { +	{CDNS_TORRENT_KEY(CLK_19_2_MHZ, CLK_19_2_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_19_2_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_25_MHZ, CLK_25_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_25_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_PCIE, NO_SSC), &dp_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_USB, NO_SSC), &sl_dp_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, NO_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), &sl_pcie_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), &pcie_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), &pcie_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, NO_SSC), &pcie_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, EXTERNAL_SSC), &pcie_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, NO_SSC), &pcie_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, EXTERNAL_SSC), &pcie_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sl_sgmii_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_NONE, NO_SSC), &sl_qsgmii_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, NO_SSC), &qsgmii_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, NO_SSC), &sl_usb_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, EXTERNAL_SSC), &sl_usb_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, INTERNAL_SSC), &sl_usb_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, NO_SSC), &usb_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &sl_usb_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &sl_usb_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &sl_usb_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, NO_SSC), &sl_usb_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, EXTERNAL_SSC), &sl_usb_100_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &sl_usb_100_int_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals}, + +	/* Dual refclk */ +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &j7200_ml_sgmii_pll1_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &j7200_ml_sgmii_pll1_100_no_ssc_cmn_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_pll1_156_25_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &j7200_ml_usxgmii_pll0_156_25_no_ssc_cmn_vals}, +}; + +static struct cdns_torrent_vals_entry ti_j7200_tx_ln_vals_entries[] = { +	{CDNS_TORRENT_KEY(CLK_19_2_MHZ, CLK_19_2_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_19_2_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_25_MHZ, CLK_25_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_25_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_PCIE, NO_SSC), &dp_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_USB, NO_SSC), &dp_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, NO_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, NO_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, EXTERNAL_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, INTERNAL_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, NO_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, EXTERNAL_SSC), NULL}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_NONE, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, + +	/* Dual refclk */ +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), NULL}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &j7200_sgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &j7200_qsgmii_100_no_ssc_tx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, +}; + +static struct cdns_torrent_vals_entry ti_j7200_rx_ln_vals_entries[] = { +	{CDNS_TORRENT_KEY(CLK_19_2_MHZ, CLK_19_2_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_19_2_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_25_MHZ, CLK_25_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_25_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_NONE, NO_SSC), &sl_dp_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_PCIE, NO_SSC), &dp_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_DP, TYPE_USB, NO_SSC), &dp_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_QSGMII, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_NONE, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_NONE, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals}, + +	/* Dual refclk */ +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_PCIE, TYPE_USXGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_SGMII, TYPE_USXGMII, NO_SSC), &j7200_sgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_156_25_MHZ, TYPE_QSGMII, TYPE_USXGMII, NO_SSC), &j7200_qsgmii_100_no_ssc_rx_ln_vals}, + +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_PCIE, NO_SSC), &ml_usxgmii_156_25_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_SGMII, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals}, +	{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_100_MHZ, TYPE_USXGMII, TYPE_QSGMII, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals}, +}; + +static const struct cdns_torrent_data ti_j7200_map_torrent = { +	.block_offset_shift = 0x0, +	.reg_offset_shift = 0x1, +	.link_cmn_vals_tbl = { +		.entries = link_cmn_vals_entries, +		.num_entries = ARRAY_SIZE(link_cmn_vals_entries), +	}, +	.xcvr_diag_vals_tbl = { +		.entries = xcvr_diag_vals_entries, +		.num_entries = ARRAY_SIZE(xcvr_diag_vals_entries), +	}, +	.pcs_cmn_vals_tbl = { +		.entries = pcs_cmn_vals_entries, +		.num_entries = ARRAY_SIZE(pcs_cmn_vals_entries), +	}, +	.phy_pma_cmn_vals_tbl = { +		.entries = j721e_phy_pma_cmn_vals_entries, +		.num_entries = ARRAY_SIZE(j721e_phy_pma_cmn_vals_entries), +	}, +	.cmn_vals_tbl = { +		.entries = ti_j7200_cmn_vals_entries, +		.num_entries = ARRAY_SIZE(ti_j7200_cmn_vals_entries), +	}, +	.tx_ln_vals_tbl = { +		.entries = ti_j7200_tx_ln_vals_entries, +		.num_entries = ARRAY_SIZE(ti_j7200_tx_ln_vals_entries), +	}, +	.rx_ln_vals_tbl = { +		.entries = ti_j7200_rx_ln_vals_entries, +		.num_entries = ARRAY_SIZE(ti_j7200_rx_ln_vals_entries), +	}, +}; +  static const struct of_device_id cdns_torrent_phy_of_match[] = {  	{  		.compatible = "cdns,torrent-phy", @@ -4563,6 +5261,10 @@ static const struct of_device_id cdns_torrent_phy_of_match[] = {  		.compatible = "ti,j721e-serdes-10g",  		.data = &ti_j721e_map_torrent,  	}, +	{ +		.compatible = "ti,j7200-serdes-10g", +		.data = &ti_j7200_map_torrent, +	},  	{}  };  MODULE_DEVICE_TABLE(of, cdns_torrent_phy_of_match); diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c index 0ae052df3765..38388dd04bdc 100644 --- a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c +++ b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c @@ -294,7 +294,7 @@ static int mixel_lvds_phy_reset(struct device *dev)  }  static struct phy *mixel_lvds_phy_xlate(struct device *dev, -					struct of_phandle_args *args) +					const struct of_phandle_args *args)  {  	struct mixel_lvds_phy_priv *priv = dev_get_drvdata(dev);  	unsigned int phy_id; diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c index e2187767ce00..b86da8e9daa4 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-28g.c +++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c @@ -556,7 +556,7 @@ static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane)  }  static struct phy *lynx_28g_xlate(struct device *dev, -				  struct of_phandle_args *args) +				  const struct of_phandle_args *args)  {  	struct lynx_28g_priv *priv = dev_get_drvdata(dev);  	int idx = args->args[0]; diff --git a/drivers/phy/hisilicon/phy-histb-combphy.c b/drivers/phy/hisilicon/phy-histb-combphy.c index c44588fd5a53..7436dcae3981 100644 --- a/drivers/phy/hisilicon/phy-histb-combphy.c +++ b/drivers/phy/hisilicon/phy-histb-combphy.c @@ -163,7 +163,7 @@ static const struct phy_ops histb_combphy_ops = {  };  static struct phy *histb_combphy_xlate(struct device *dev, -				       struct of_phandle_args *args) +				       const struct of_phandle_args *args)  {  	struct histb_combphy_priv *priv = dev_get_drvdata(dev);  	struct histb_combphy_mode *mode = &priv->mode; diff --git a/drivers/phy/intel/phy-intel-lgm-combo.c b/drivers/phy/intel/phy-intel-lgm-combo.c index d32e267c0001..f8e3054a9e59 100644 --- a/drivers/phy/intel/phy-intel-lgm-combo.c +++ b/drivers/phy/intel/phy-intel-lgm-combo.c @@ -508,7 +508,7 @@ static const struct phy_ops intel_cbphy_ops = {  };  static struct phy *intel_cbphy_xlate(struct device *dev, -				     struct of_phandle_args *args) +				     const struct of_phandle_args *args)  {  	struct intel_combo_phy *cbphy = dev_get_drvdata(dev);  	u32 iphy_id; diff --git a/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c b/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c index ef93bf2cba10..406a87c8b759 100644 --- a/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c +++ b/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c @@ -358,7 +358,7 @@ static const struct phy_ops ltq_vrx200_pcie_phy_ops = {  };  static struct phy *ltq_vrx200_pcie_phy_xlate(struct device *dev, -					     struct of_phandle_args *args) +					     const struct of_phandle_args *args)  {  	struct ltq_vrx200_pcie_phy_priv *priv = dev_get_drvdata(dev);  	unsigned int mode; diff --git a/drivers/phy/marvell/phy-armada375-usb2.c b/drivers/phy/marvell/phy-armada375-usb2.c index b141e3cd8a94..3731f9b25655 100644 --- a/drivers/phy/marvell/phy-armada375-usb2.c +++ b/drivers/phy/marvell/phy-armada375-usb2.c @@ -61,7 +61,7 @@ static const struct phy_ops armada375_usb_phy_ops = {   * USB3 case it still optional and we use ENODEV.   */  static struct phy *armada375_usb_phy_xlate(struct device *dev, -					struct of_phandle_args *args) +					const struct of_phandle_args *args)  {  	struct armada375_cluster_phy *cluster_phy = dev_get_drvdata(dev); diff --git a/drivers/phy/marvell/phy-armada38x-comphy.c b/drivers/phy/marvell/phy-armada38x-comphy.c index b7d99861526a..5063361b0120 100644 --- a/drivers/phy/marvell/phy-armada38x-comphy.c +++ b/drivers/phy/marvell/phy-armada38x-comphy.c @@ -47,8 +47,13 @@ struct a38x_comphy {  	struct a38x_comphy_lane lane[MAX_A38X_COMPHY];  }; +/* + * Map serdes lanes and gbe ports to serdes mux configuration values: + * row index = serdes lane, + * column index = gbe port number. + */  static const u8 gbe_mux[MAX_A38X_COMPHY][MAX_A38X_PORTS] = { -	{ 0, 0, 0 }, +	{ 3, 0, 0 },  	{ 4, 5, 0 },  	{ 0, 4, 0 },  	{ 0, 0, 4 }, @@ -155,7 +160,7 @@ static const struct phy_ops a38x_comphy_ops = {  };  static struct phy *a38x_comphy_xlate(struct device *dev, -				     struct of_phandle_args *args) +				     const struct of_phandle_args *args)  {  	struct a38x_comphy_lane *lane;  	struct phy *phy; diff --git a/drivers/phy/marvell/phy-berlin-sata.c b/drivers/phy/marvell/phy-berlin-sata.c index f972d78372ea..c90e2867900c 100644 --- a/drivers/phy/marvell/phy-berlin-sata.c +++ b/drivers/phy/marvell/phy-berlin-sata.c @@ -155,7 +155,7 @@ static int phy_berlin_sata_power_off(struct phy *phy)  }  static struct phy *phy_berlin_sata_phy_xlate(struct device *dev, -					     struct of_phandle_args *args) +					     const struct of_phandle_args *args)  {  	struct phy_berlin_priv *priv = dev_get_drvdata(dev);  	int i; diff --git a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c index 24c3371e2bb2..41162d7228c9 100644 --- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c @@ -1213,7 +1213,7 @@ static const struct phy_ops mvebu_a3700_comphy_ops = {  };  static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, -					    struct of_phandle_args *args) +					    const struct of_phandle_args *args)  {  	struct mvebu_a3700_comphy_lane *lane;  	unsigned int port; diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index b0dd13366598..da5e8f405749 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -917,7 +917,7 @@ static const struct phy_ops mvebu_comphy_ops = {  };  static struct phy *mvebu_comphy_xlate(struct device *dev, -				      struct of_phandle_args *args) +				      const struct of_phandle_args *args)  {  	struct mvebu_comphy_lane *lane;  	struct phy *phy; diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig index 3125ecb5d119..3849b7c87d28 100644 --- a/drivers/phy/mediatek/Kconfig +++ b/drivers/phy/mediatek/Kconfig @@ -58,6 +58,18 @@ config PHY_MTK_HDMI  	help  	  Support HDMI PHY for Mediatek SoCs. +config PHY_MTK_MIPI_CSI_0_5 +	tristate "MediaTek MIPI CSI CD-PHY v0.5 Driver" +	depends on ARCH_MEDIATEK || COMPILE_TEST +	depends on OF +	select GENERIC_PHY +	help +	  Enable this to support the MIPI CSI CD-PHY receiver version 0.5. +	  The driver supports multiple CSI cdphy ports simultaneously. + +	  To compile this driver as a module, choose M here: the +	  module will be called phy-mtk-mipi-csi-0-5. +  config PHY_MTK_MIPI_DSI  	tristate "MediaTek MIPI-DSI Driver"  	depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile index c9a50395533e..f6e24a47e081 100644 --- a/drivers/phy/mediatek/Makefile +++ b/drivers/phy/mediatek/Makefile @@ -15,6 +15,8 @@ phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt8173.o  phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt8195.o  obj-$(CONFIG_PHY_MTK_HDMI)		+= phy-mtk-hdmi-drv.o +obj-$(CONFIG_PHY_MTK_MIPI_CSI_0_5)	+= phy-mtk-mipi-csi-0-5.o +  phy-mtk-mipi-dsi-drv-y			:= phy-mtk-mipi-dsi.o  phy-mtk-mipi-dsi-drv-y			+= phy-mtk-mipi-dsi-mt8173.o  phy-mtk-mipi-dsi-drv-y			+= phy-mtk-mipi-dsi-mt8183.o diff --git a/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5-rx-reg.h b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5-rx-reg.h new file mode 100644 index 000000000000..97b4c27a1699 --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5-rx-reg.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023, MediaTek Inc. + * Copyright (c) 2023, BayLibre Inc. + */ + +#ifndef __PHY_MTK_MIPI_CSI_V_0_5_RX_REG_H__ +#define __PHY_MTK_MIPI_CSI_V_0_5_RX_REG_H__ + +/* + * CSI1 and CSI2 are identical, and similar to CSI0. All CSIX macros are + * applicable to the three PHYs. Where differences exist, they are denoted by + * macro names using CSI0 and CSI1, the latter being applicable to CSI1 and + * CSI2 alike. + */ + +#define MIPI_RX_ANA00_CSIXA			0x0000 +#define RG_CSI0A_CPHY_EN			BIT(0) +#define RG_CSIXA_EQ_PROTECT_EN			BIT(1) +#define RG_CSIXA_BG_LPF_EN			BIT(2) +#define RG_CSIXA_BG_CORE_EN			BIT(3) +#define RG_CSIXA_DPHY_L0_CKMODE_EN		BIT(5) +#define RG_CSIXA_DPHY_L0_CKSEL			BIT(6) +#define RG_CSIXA_DPHY_L1_CKMODE_EN		BIT(8) +#define RG_CSIXA_DPHY_L1_CKSEL			BIT(9) +#define RG_CSIXA_DPHY_L2_CKMODE_EN		BIT(11) +#define RG_CSIXA_DPHY_L2_CKSEL			BIT(12) + +#define MIPI_RX_ANA18_CSIXA			0x0018 +#define RG_CSI0A_L0_T0AB_EQ_IS			GENMASK(5, 4) +#define RG_CSI0A_L0_T0AB_EQ_BW			GENMASK(7, 6) +#define RG_CSI0A_L1_T1AB_EQ_IS			GENMASK(21, 20) +#define RG_CSI0A_L1_T1AB_EQ_BW			GENMASK(23, 22) +#define RG_CSI0A_L2_T1BC_EQ_IS			GENMASK(21, 20) +#define RG_CSI0A_L2_T1BC_EQ_BW			GENMASK(23, 22) +#define RG_CSI1A_L0_EQ_IS			GENMASK(5, 4) +#define RG_CSI1A_L0_EQ_BW			GENMASK(7, 6) +#define RG_CSI1A_L1_EQ_IS			GENMASK(21, 20) +#define RG_CSI1A_L1_EQ_BW			GENMASK(23, 22) +#define RG_CSI1A_L2_EQ_IS			GENMASK(5, 4) +#define RG_CSI1A_L2_EQ_BW			GENMASK(7, 6) + +#define MIPI_RX_ANA1C_CSIXA			0x001c +#define MIPI_RX_ANA20_CSI0A			0x0020 + +#define MIPI_RX_ANA24_CSIXA			0x0024 +#define RG_CSIXA_RESERVE			GENMASK(31, 24) + +#define MIPI_RX_ANA40_CSIXA			0x0040 +#define RG_CSIXA_CPHY_FMCK_SEL			GENMASK(1, 0) +#define RG_CSIXA_ASYNC_OPTION			GENMASK(7, 4) +#define RG_CSIXA_CPHY_SPARE			GENMASK(31, 16) + +#define MIPI_RX_WRAPPER80_CSIXA			0x0080 +#define CSR_CSI_RST_MODE			GENMASK(17, 16) + +#define MIPI_RX_ANAA8_CSIXA			0x00a8 +#define RG_CSIXA_CDPHY_L0_T0_BYTECK_INVERT	BIT(0) +#define RG_CSIXA_DPHY_L1_BYTECK_INVERT		BIT(1) +#define RG_CSIXA_CDPHY_L2_T1_BYTECK_INVERT	BIT(2) + +#endif diff --git a/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c new file mode 100644 index 000000000000..058e1d926630 --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek MIPI CSI v0.5 driver + * + * Copyright (c) 2023, MediaTek Inc. + * Copyright (c) 2023, BayLibre Inc. + */ + +#include <dt-bindings/phy/phy.h> +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include "phy-mtk-io.h" +#include "phy-mtk-mipi-csi-0-5-rx-reg.h" + +#define CSIXB_OFFSET		0x1000 + +struct mtk_mipi_cdphy_port { +	struct device *dev; +	void __iomem *base; +	struct phy *phy; +	u32 type; +	u32 mode; +	u32 num_lanes; +}; + +enum PHY_TYPE { +	DPHY = 0, +	CPHY, +	CDPHY, +}; + +static void mtk_phy_csi_cdphy_ana_eq_tune(void __iomem *base) +{ +	mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI0A_L0_T0AB_EQ_IS, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI0A_L0_T0AB_EQ_BW, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA1C_CSIXA, RG_CSI0A_L1_T1AB_EQ_IS, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA1C_CSIXA, RG_CSI0A_L1_T1AB_EQ_BW, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA20_CSI0A, RG_CSI0A_L2_T1BC_EQ_IS, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA20_CSI0A, RG_CSI0A_L2_T1BC_EQ_BW, 1); + +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI0A_L0_T0AB_EQ_IS, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI0A_L0_T0AB_EQ_BW, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA1C_CSIXA, RG_CSI0A_L1_T1AB_EQ_IS, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA1C_CSIXA, RG_CSI0A_L1_T1AB_EQ_BW, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA20_CSI0A, RG_CSI0A_L2_T1BC_EQ_IS, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA20_CSI0A, RG_CSI0A_L2_T1BC_EQ_BW, 1); +} + +static void mtk_phy_csi_dphy_ana_eq_tune(void __iomem *base) +{ +	mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L0_EQ_IS, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L0_EQ_BW, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L1_EQ_IS, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L1_EQ_BW, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA1C_CSIXA, RG_CSI1A_L2_EQ_IS, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA1C_CSIXA, RG_CSI1A_L2_EQ_BW, 1); + +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L0_EQ_IS, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L0_EQ_BW, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L1_EQ_IS, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA18_CSIXA, RG_CSI1A_L1_EQ_BW, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA1C_CSIXA, RG_CSI1A_L2_EQ_IS, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA1C_CSIXA, RG_CSI1A_L2_EQ_BW, 1); +} + +static int mtk_mipi_phy_power_on(struct phy *phy) +{ +	struct mtk_mipi_cdphy_port *port = phy_get_drvdata(phy); +	void __iomem *base = port->base; + +	/* +	 * The driver currently supports DPHY and CD-PHY phys, +	 * but the only mode supported is DPHY, +	 * so CD-PHY capable phys must be configured in DPHY mode +	 */ +	if (port->type == CDPHY) { +		mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSI0A_CPHY_EN, 0); +		mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, +				     RG_CSI0A_CPHY_EN, 0); +	} + +	/* +	 * Lane configuration: +	 * +	 * Only 4 data + 1 clock is supported for now with the following mapping: +	 * +	 * CSIXA_LNR0 --> D2 +	 * CSIXA_LNR1 --> D0 +	 * CSIXA_LNR2 --> C +	 * CSIXB_LNR0 --> D1 +	 * CSIXB_LNR1 --> D3 +	 */ +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L0_CKMODE_EN, 0); +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L0_CKSEL, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L1_CKMODE_EN, 0); +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L1_CKSEL, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L2_CKMODE_EN, 1); +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L2_CKSEL, 1); + +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, +			     RG_CSIXA_DPHY_L0_CKMODE_EN, 0); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L0_CKSEL, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, +			     RG_CSIXA_DPHY_L1_CKMODE_EN, 0); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L1_CKSEL, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, +			     RG_CSIXA_DPHY_L2_CKMODE_EN, 0); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_DPHY_L2_CKSEL, 1); + +	/* Byte clock invert */ +	mtk_phy_update_field(base + MIPI_RX_ANAA8_CSIXA, RG_CSIXA_CDPHY_L0_T0_BYTECK_INVERT, 1); +	mtk_phy_update_field(base + MIPI_RX_ANAA8_CSIXA, RG_CSIXA_DPHY_L1_BYTECK_INVERT, 1); +	mtk_phy_update_field(base + MIPI_RX_ANAA8_CSIXA, RG_CSIXA_CDPHY_L2_T1_BYTECK_INVERT, 1); + +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANAA8_CSIXA, +			     RG_CSIXA_CDPHY_L0_T0_BYTECK_INVERT, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANAA8_CSIXA, +			     RG_CSIXA_DPHY_L1_BYTECK_INVERT, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANAA8_CSIXA, +			     RG_CSIXA_CDPHY_L2_T1_BYTECK_INVERT, 1); + +	/* Start ANA EQ tuning */ +	if (port->type == CDPHY) +		mtk_phy_csi_cdphy_ana_eq_tune(base); +	else +		mtk_phy_csi_dphy_ana_eq_tune(base); + +	/* End ANA EQ tuning */ +	mtk_phy_set_bits(base + MIPI_RX_ANA40_CSIXA, 0x90); + +	mtk_phy_update_field(base + MIPI_RX_ANA24_CSIXA, RG_CSIXA_RESERVE, 0x40); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA24_CSIXA, RG_CSIXA_RESERVE, 0x40); +	mtk_phy_update_field(base + MIPI_RX_WRAPPER80_CSIXA, CSR_CSI_RST_MODE, 0); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_WRAPPER80_CSIXA, CSR_CSI_RST_MODE, 0); +	/* ANA power on */ +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_CORE_EN, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_CORE_EN, 1); +	usleep_range(20, 40); +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_LPF_EN, 1); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_LPF_EN, 1); + +	return 0; +} + +static int mtk_mipi_phy_power_off(struct phy *phy) +{ +	struct mtk_mipi_cdphy_port *port = phy_get_drvdata(phy); +	void __iomem *base = port->base; + +	/* Disable MIPI BG. */ +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_CORE_EN, 0); +	mtk_phy_update_field(base + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_LPF_EN, 0); + +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_CORE_EN, 0); +	mtk_phy_update_field(base + CSIXB_OFFSET + MIPI_RX_ANA00_CSIXA, RG_CSIXA_BG_LPF_EN, 0); + +	return 0; +} + +static struct phy *mtk_mipi_cdphy_xlate(struct device *dev, +					const struct of_phandle_args *args) +{ +	struct mtk_mipi_cdphy_port *priv = dev_get_drvdata(dev); + +	/* +	 * If PHY is CD-PHY then we need to get the operating mode +	 * For now only D-PHY mode is supported +	 */ +	if (priv->type == CDPHY) { +		if (args->args_count != 1) { +			dev_err(dev, "invalid number of arguments\n"); +			return ERR_PTR(-EINVAL); +		} +		switch (args->args[0]) { +		case PHY_TYPE_DPHY: +			priv->mode = DPHY; +			if (priv->num_lanes != 4) { +				dev_err(dev, "Only 4D1C mode is supported for now!\n"); +				return ERR_PTR(-EINVAL); +			} +			break; +		default: +			dev_err(dev, "Unsupported PHY type: %i\n", args->args[0]); +			return ERR_PTR(-EINVAL); +		} +	} else { +		if (args->args_count) { +			dev_err(dev, "invalid number of arguments\n"); +			return ERR_PTR(-EINVAL); +		} +		priv->mode = DPHY; +	} + +	return priv->phy; +} + +static const struct phy_ops mtk_cdphy_ops = { +	.power_on	= mtk_mipi_phy_power_on, +	.power_off	= mtk_mipi_phy_power_off, +	.owner		= THIS_MODULE, +}; + +static int mtk_mipi_cdphy_probe(struct platform_device *pdev) +{ +	struct device *dev = &pdev->dev; +	struct phy_provider *phy_provider; +	struct mtk_mipi_cdphy_port *port; +	struct phy *phy; +	int ret; +	u32 phy_type; + +	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); +	if (!port) +		return -ENOMEM; + +	dev_set_drvdata(dev, port); + +	port->dev = dev; + +	port->base = devm_platform_ioremap_resource(pdev, 0); +	if (IS_ERR(port->base)) +		return PTR_ERR(port->base); + +	ret = of_property_read_u32(dev->of_node, "num-lanes", &port->num_lanes); +	if (ret) { +		dev_err(dev, "Failed to read num-lanes property: %i\n", ret); +		return ret; +	} + +	/* +	 * phy-type is optional, if not present, PHY is considered to be CD-PHY +	 */ +	if (device_property_present(dev, "phy-type")) { +		ret = of_property_read_u32(dev->of_node, "phy-type", &phy_type); +		if (ret) { +			dev_err(dev, "Failed to read phy-type property: %i\n", ret); +			return ret; +		} +		switch (phy_type) { +		case PHY_TYPE_DPHY: +			port->type = DPHY; +			break; +		default: +			dev_err(dev, "Unsupported PHY type: %i\n", phy_type); +			return -EINVAL; +		} +	} else { +		port->type = CDPHY; +	} + +	phy = devm_phy_create(dev, NULL, &mtk_cdphy_ops); +	if (IS_ERR(phy)) { +		dev_err(dev, "Failed to create PHY: %ld\n", PTR_ERR(phy)); +		return PTR_ERR(phy); +	} + +	port->phy = phy; +	phy_set_drvdata(phy, port); + +	phy_provider = devm_of_phy_provider_register(dev, mtk_mipi_cdphy_xlate); +	if (IS_ERR(phy_provider)) { +		dev_err(dev, "Failed to register PHY provider: %ld\n", +			PTR_ERR(phy_provider)); +		return PTR_ERR(phy_provider); +	} + +	return 0; +} + +static const struct of_device_id mtk_mipi_cdphy_of_match[] = { +	{ .compatible = "mediatek,mt8365-csi-rx" }, +	{ /* sentinel */}, +}; +MODULE_DEVICE_TABLE(of, mtk_mipi_cdphy_of_match); + +static struct platform_driver mipi_cdphy_pdrv = { +	.probe = mtk_mipi_cdphy_probe, +	.driver	= { +		.name	= "mtk-mipi-csi-0-5", +		.of_match_table = mtk_mipi_cdphy_of_match, +	}, +}; +module_platform_driver(mipi_cdphy_pdrv); + +MODULE_DESCRIPTION("MediaTek MIPI CSI CD-PHY v0.5 Driver"); +MODULE_AUTHOR("Louis Kuo <louis.kuo@mediatek.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index a4746f6cb8a1..25b86bbb9cec 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -1467,7 +1467,7 @@ static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)  }  static struct phy *mtk_phy_xlate(struct device *dev, -					struct of_phandle_args *args) +					const struct of_phandle_args *args)  {  	struct mtk_tphy *tphy = dev_get_drvdata(dev);  	struct mtk_phy_instance *instance = NULL; diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c index b222fbbd71d1..064fd0941727 100644 --- a/drivers/phy/mediatek/phy-mtk-xsphy.c +++ b/drivers/phy/mediatek/phy-mtk-xsphy.c @@ -378,7 +378,7 @@ static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)  }  static struct phy *mtk_phy_xlate(struct device *dev, -				 struct of_phandle_args *args) +				 const struct of_phandle_args *args)  {  	struct mtk_xsphy *xsphy = dev_get_drvdata(dev);  	struct xsphy_instance *inst = NULL; diff --git a/drivers/phy/microchip/lan966x_serdes.c b/drivers/phy/microchip/lan966x_serdes.c index b5ac2b7995e7..835e369cdfc5 100644 --- a/drivers/phy/microchip/lan966x_serdes.c +++ b/drivers/phy/microchip/lan966x_serdes.c @@ -518,7 +518,7 @@ static const struct phy_ops serdes_ops = {  };  static struct phy *serdes_simple_xlate(struct device *dev, -				       struct of_phandle_args *args) +				       const struct of_phandle_args *args)  {  	struct serdes_ctrl *ctrl = dev_get_drvdata(dev);  	unsigned int port, idx, i; diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c index 01bd5ea620c5..7cb85029fab3 100644 --- a/drivers/phy/microchip/sparx5_serdes.c +++ b/drivers/phy/microchip/sparx5_serdes.c @@ -2509,7 +2509,7 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {  /* Client lookup function, uses serdes index */  static struct phy *sparx5_serdes_xlate(struct device *dev, -				     struct of_phandle_args *args) +				     const struct of_phandle_args *args)  {  	struct sparx5_serdes_private *priv = dev_get_drvdata(dev);  	int idx; diff --git a/drivers/phy/mscc/phy-ocelot-serdes.c b/drivers/phy/mscc/phy-ocelot-serdes.c index d9443e865a78..1cd1b5db2ad7 100644 --- a/drivers/phy/mscc/phy-ocelot-serdes.c +++ b/drivers/phy/mscc/phy-ocelot-serdes.c @@ -441,7 +441,7 @@ static const struct phy_ops serdes_ops = {  };  static struct phy *serdes_simple_xlate(struct device *dev, -				       struct of_phandle_args *args) +				       const struct of_phandle_args *args)  {  	struct serdes_ctrl *ctrl = dev_get_drvdata(dev);  	unsigned int port, idx, i; diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index d9be6a4d5383..7f9b4de772ee 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -700,8 +700,8 @@ EXPORT_SYMBOL_GPL(devm_phy_put);   * should provide a custom of_xlate function that reads the *args* and returns   * the appropriate phy.   */ -struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args -	*args) +struct phy *of_phy_simple_xlate(struct device *dev, +				const struct of_phandle_args *args)  {  	struct phy *phy;  	struct class_dev_iter iter; @@ -1095,7 +1095,7 @@ EXPORT_SYMBOL_GPL(devm_phy_destroy);  struct phy_provider *__of_phy_provider_register(struct device *dev,  	struct device_node *children, struct module *owner,  	struct phy * (*of_xlate)(struct device *dev, -				 struct of_phandle_args *args)) +				 const struct of_phandle_args *args))  {  	struct phy_provider *phy_provider; @@ -1158,7 +1158,7 @@ EXPORT_SYMBOL_GPL(__of_phy_provider_register);  struct phy_provider *__devm_of_phy_provider_register(struct device *dev,  	struct device_node *children, struct module *owner,  	struct phy * (*of_xlate)(struct device *dev, -				 struct of_phandle_args *args)) +				 const struct of_phandle_args *args))  {  	struct phy_provider **ptr, *phy_provider; diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c index 1f0f908323f0..5007dc7a357c 100644 --- a/drivers/phy/phy-xgene.c +++ b/drivers/phy/phy-xgene.c @@ -1611,7 +1611,7 @@ static const struct phy_ops xgene_phy_ops = {  };  static struct phy *xgene_phy_xlate(struct device *dev, -				   struct of_phandle_args *args) +				   const struct of_phandle_args *args)  {  	struct xgene_phy_ctx *ctx = dev_get_drvdata(dev); diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index ffd609ac6233..eb60e950ad53 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -7,7 +7,7 @@ obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)	+= phy-qcom-ipq806x-sata.o  obj-$(CONFIG_PHY_QCOM_M31_USB)		+= phy-qcom-m31.o  obj-$(CONFIG_PHY_QCOM_PCIE2)		+= phy-qcom-pcie2.o -obj-$(CONFIG_PHY_QCOM_QMP_COMBO)	+= phy-qcom-qmp-combo.o +obj-$(CONFIG_PHY_QCOM_QMP_COMBO)	+= phy-qcom-qmp-combo.o phy-qcom-qmp-usbc.o  obj-$(CONFIG_PHY_QCOM_QMP_PCIE)		+= phy-qcom-qmp-pcie.o  obj-$(CONFIG_PHY_QCOM_QMP_PCIE_8996)	+= phy-qcom-qmp-pcie-msm8996.o  obj-$(CONFIG_PHY_QCOM_QMP_UFS)		+= phy-qcom-qmp-ufs.o diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c index 8e5078304646..9818d994c68b 100644 --- a/drivers/phy/qualcomm/phy-qcom-edp.c +++ b/drivers/phy/qualcomm/phy-qcom-edp.c @@ -21,7 +21,8 @@  #include <dt-bindings/phy/phy.h> -#include "phy-qcom-qmp.h" +#include "phy-qcom-qmp-dp-phy.h" +#include "phy-qcom-qmp-qserdes-com-v4.h"  /* EDP_PHY registers */  #define DP_PHY_CFG                              0x0010 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index 17c4ad7553a5..7d585a4bbbba 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -25,21 +25,21 @@  #include <dt-bindings/phy/phy-qcom-qmp.h> +#include "phy-qcom-qmp-common.h" +  #include "phy-qcom-qmp.h"  #include "phy-qcom-qmp-pcs-misc-v3.h"  #include "phy-qcom-qmp-pcs-usb-v4.h"  #include "phy-qcom-qmp-pcs-usb-v5.h"  #include "phy-qcom-qmp-pcs-usb-v6.h" -/* QPHY_SW_RESET bit */ -#define SW_RESET				BIT(0) -/* QPHY_POWER_DOWN_CONTROL */ -#define SW_PWRDN				BIT(0) -/* QPHY_START_CONTROL bits */ -#define SERDES_START				BIT(0) -#define PCS_START				BIT(1) -/* QPHY_PCS_STATUS bit */ -#define PHYSTATUS				BIT(6) +#include "phy-qcom-qmp-dp-com-v3.h" + +#include "phy-qcom-qmp-dp-phy.h" +#include "phy-qcom-qmp-dp-phy-v3.h" +#include "phy-qcom-qmp-dp-phy-v4.h" +#include "phy-qcom-qmp-dp-phy-v5.h" +#include "phy-qcom-qmp-dp-phy-v6.h"  /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */  /* DP PHY soft reset */ @@ -55,47 +55,12 @@  #define USB3_MODE				BIT(0) /* enables USB3 mode */  #define DP_MODE					BIT(1) /* enables DP mode */ -/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */ -#define ARCVR_DTCT_EN				BIT(0) -#define ALFPS_DTCT_EN				BIT(1) -#define ARCVR_DTCT_EVENT_SEL			BIT(4) - -/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */ -#define IRQ_CLEAR				BIT(0) - -/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */ -#define CLAMP_EN				BIT(0) /* enables i/o clamp_n */ -  /* QPHY_V3_DP_COM_TYPEC_CTRL register bits */  #define SW_PORTSELECT_VAL			BIT(0)  #define SW_PORTSELECT_MUX			BIT(1)  #define PHY_INIT_COMPLETE_TIMEOUT		10000 -struct qmp_phy_init_tbl { -	unsigned int offset; -	unsigned int val; -	/* -	 * mask of lanes for which this register is written -	 * for cases when second lane needs different values -	 */ -	u8 lane_mask; -}; - -#define QMP_PHY_INIT_CFG(o, v)		\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = 0xff,	\ -	} - -#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = l,		\ -	} -  /* set of registers with offsets different per-PHY */  enum qphy_reg_layout {  	/* PCS registers */ @@ -2031,55 +1996,29 @@ static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = {  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  }; -static void qmp_combo_configure_lane(void __iomem *base, -					const struct qmp_phy_init_tbl tbl[], -					int num, -					u8 lane_mask) -{ -	int i; -	const struct qmp_phy_init_tbl *t = tbl; - -	if (!t) -		return; - -	for (i = 0; i < num; i++, t++) { -		if (!(t->lane_mask & lane_mask)) -			continue; - -		writel(t->val, base + t->offset); -	} -} - -static void qmp_combo_configure(void __iomem *base, -				   const struct qmp_phy_init_tbl tbl[], -				   int num) -{ -	qmp_combo_configure_lane(base, tbl, num, 0xff); -} -  static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp)  {  	const struct qmp_phy_cfg *cfg = qmp->cfg;  	void __iomem *serdes = qmp->dp_serdes;  	const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; -	qmp_combo_configure(serdes, cfg->dp_serdes_tbl, cfg->dp_serdes_tbl_num); +	qmp_configure(serdes, cfg->dp_serdes_tbl, cfg->dp_serdes_tbl_num);  	switch (dp_opts->link_rate) {  	case 1620: -		qmp_combo_configure(serdes, cfg->serdes_tbl_rbr, +		qmp_configure(serdes, cfg->serdes_tbl_rbr,  				cfg->serdes_tbl_rbr_num);  		break;  	case 2700: -		qmp_combo_configure(serdes, cfg->serdes_tbl_hbr, +		qmp_configure(serdes, cfg->serdes_tbl_hbr,  				cfg->serdes_tbl_hbr_num);  		break;  	case 5400: -		qmp_combo_configure(serdes, cfg->serdes_tbl_hbr2, +		qmp_configure(serdes, cfg->serdes_tbl_hbr2,  				cfg->serdes_tbl_hbr2_num);  		break;  	case 8100: -		qmp_combo_configure(serdes, cfg->serdes_tbl_hbr3, +		qmp_configure(serdes, cfg->serdes_tbl_hbr3,  				cfg->serdes_tbl_hbr3_num);  		break;  	default: @@ -2370,7 +2309,7 @@ static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp)  	u32 status;  	int ret; -	writel(0x0f, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_CFG_1); +	writel(0x0f, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG_1);  	qmp_combo_configure_dp_mode(qmp); @@ -2681,8 +2620,8 @@ static int qmp_combo_dp_power_on(struct phy *phy)  	qmp_combo_dp_serdes_init(qmp); -	qmp_combo_configure_lane(tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1); -	qmp_combo_configure_lane(tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2); +	qmp_configure_lane(tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1); +	qmp_configure_lane(tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2);  	/* Configure special DP tx tunings */  	cfg->configure_dp_tx(qmp); @@ -2724,7 +2663,7 @@ static int qmp_combo_usb_power_on(struct phy *phy)  	unsigned int val;  	int ret; -	qmp_combo_configure(serdes, cfg->serdes_tbl, cfg->serdes_tbl_num); +	qmp_configure(serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);  	ret = clk_prepare_enable(qmp->pipe_clk);  	if (ret) { @@ -2733,16 +2672,16 @@ static int qmp_combo_usb_power_on(struct phy *phy)  	}  	/* Tx, Rx, and PCS configurations */ -	qmp_combo_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); -	qmp_combo_configure_lane(tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); +	qmp_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); +	qmp_configure_lane(tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); -	qmp_combo_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); -	qmp_combo_configure_lane(rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); +	qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); +	qmp_configure_lane(rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); -	qmp_combo_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); +	qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);  	if (pcs_usb) -		qmp_combo_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num); +		qmp_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);  	if (cfg->has_pwrdn_delay)  		usleep_range(10, 20); @@ -3515,7 +3454,7 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp)  	return 0;  } -static struct phy *qmp_combo_phy_xlate(struct device *dev, struct of_phandle_args *args) +static struct phy *qmp_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args)  {  	struct qmp_combo *qmp = dev_get_drvdata(dev); diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-common.h b/drivers/phy/qualcomm/phy-qcom-qmp-common.h new file mode 100644 index 000000000000..799384210509 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-common.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_COMMON_H_ +#define QCOM_PHY_QMP_COMMON_H_ + +struct qmp_phy_init_tbl { +	unsigned int offset; +	unsigned int val; +	/* +	 * mask of lanes for which this register is written +	 * for cases when second lane needs different values +	 */ +	u8 lane_mask; +}; + +#define QMP_PHY_INIT_CFG(o, v)		\ +	{				\ +		.offset = o,		\ +		.val = v,		\ +		.lane_mask = 0xff,	\ +	} + +#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\ +	{				\ +		.offset = o,		\ +		.val = v,		\ +		.lane_mask = l,		\ +	} + +static inline void qmp_configure_lane(void __iomem *base, +					   const struct qmp_phy_init_tbl tbl[], +					   int num, +					   u8 lane_mask) +{ +	int i; +	const struct qmp_phy_init_tbl *t = tbl; + +	if (!t) +		return; + +	for (i = 0; i < num; i++, t++) { +		if (!(t->lane_mask & lane_mask)) +			continue; + +		writel(t->val, base + t->offset); +	} +} + +static inline void qmp_configure(void __iomem *base, +				      const struct qmp_phy_init_tbl tbl[], +				      int num) +{ +	qmp_configure_lane(base, tbl, num, 0xff); +} + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-com-v3.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-com-v3.h new file mode 100644 index 000000000000..396179ef38b0 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-com-v3.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_COM_V3_H_ +#define QCOM_PHY_QMP_DP_COM_V3_H_ + +/* Only for QMP V3 & V4 PHY - DP COM registers */ +#define QPHY_V3_DP_COM_PHY_MODE_CTRL			0x00 +#define QPHY_V3_DP_COM_SW_RESET				0x04 +#define QPHY_V3_DP_COM_POWER_DOWN_CTRL			0x08 +#define QPHY_V3_DP_COM_SWI_CTRL				0x0c +#define QPHY_V3_DP_COM_TYPEC_CTRL			0x10 +#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL			0x14 +#define QPHY_V3_DP_COM_RESET_OVRD_CTRL			0x1c + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v3.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v3.h new file mode 100644 index 000000000000..00a9702abccd --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v3.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_V3_H_ +#define QCOM_PHY_QMP_DP_PHY_V3_H_ + +/* Only for QMP V3 PHY - DP PHY registers */ +#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK		0x048 +#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_CLEAR		0x04c +#define QSERDES_V3_DP_PHY_AUX_BIST_CFG			0x050 + +#define QSERDES_V3_DP_PHY_VCO_DIV			0x064 +#define QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL		0x06c +#define QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL		0x088 + +#define QSERDES_V3_DP_PHY_SPARE0			0x0ac +#define QSERDES_V3_DP_PHY_STATUS			0x0c0 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v4.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v4.h new file mode 100644 index 000000000000..ed6795e1257c --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v4.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_V4_H_ +#define QCOM_PHY_QMP_DP_PHY_V4_H_ + +/* Only for QMP V4 PHY - DP PHY registers */ +#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK		0x054 +#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_CLEAR		0x058 +#define QSERDES_V4_DP_PHY_VCO_DIV			0x070 +#define QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL		0x078 +#define QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL		0x09c +#define QSERDES_V4_DP_PHY_SPARE0			0x0c8 +#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS		0x0d8 +#define QSERDES_V4_DP_PHY_STATUS			0x0dc + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v5.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v5.h new file mode 100644 index 000000000000..f5cfacf9be96 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v5.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_V5_H_ +#define QCOM_PHY_QMP_DP_PHY_V5_H_ + +/* Only for QMP V5 PHY - DP PHY registers */ +#define QSERDES_V5_DP_PHY_AUX_INTERRUPT_STATUS		0x0d8 +#define QSERDES_V5_DP_PHY_STATUS			0x0dc + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v6.h new file mode 100644 index 000000000000..01a20d3be4b8 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v6.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_V6_H_ +#define QCOM_PHY_QMP_DP_PHY_V6_H_ + +/* Only for QMP V6 PHY - DP PHY registers */ +#define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS		0x0e0 +#define QSERDES_V6_DP_PHY_STATUS			0x0e4 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h new file mode 100644 index 000000000000..0ebd405bcaf0 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_H_ +#define QCOM_PHY_QMP_DP_PHY_H_ + +/* QMP PHY - DP PHY registers */ +#define QSERDES_DP_PHY_REVISION_ID0			0x000 +#define QSERDES_DP_PHY_REVISION_ID1			0x004 +#define QSERDES_DP_PHY_REVISION_ID2			0x008 +#define QSERDES_DP_PHY_REVISION_ID3			0x00c +#define QSERDES_DP_PHY_CFG				0x010 +#define QSERDES_DP_PHY_CFG_1				0x014 +#define QSERDES_DP_PHY_PD_CTL				0x018 +#define QSERDES_DP_PHY_MODE				0x01c +#define QSERDES_DP_PHY_AUX_CFG0				0x020 +#define QSERDES_DP_PHY_AUX_CFG1				0x024 +#define QSERDES_DP_PHY_AUX_CFG2				0x028 +#define QSERDES_DP_PHY_AUX_CFG3				0x02c +#define QSERDES_DP_PHY_AUX_CFG4				0x030 +#define QSERDES_DP_PHY_AUX_CFG5				0x034 +#define QSERDES_DP_PHY_AUX_CFG6				0x038 +#define QSERDES_DP_PHY_AUX_CFG7				0x03c +#define QSERDES_DP_PHY_AUX_CFG8				0x040 +#define QSERDES_DP_PHY_AUX_CFG9				0x044 + +/* QSERDES COM_BIAS_EN_CLKBUFLR_EN bits */ +# define QSERDES_V3_COM_BIAS_EN				0x0001 +# define QSERDES_V3_COM_BIAS_EN_MUX			0x0002 +# define QSERDES_V3_COM_CLKBUF_R_EN			0x0004 +# define QSERDES_V3_COM_CLKBUF_L_EN			0x0008 +# define QSERDES_V3_COM_EN_SYSCLK_TX_SEL		0x0010 +# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_L		0x0020 +# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_R		0x0040 + +/* QPHY_TX_TX_EMP_POST1_LVL bits */ +# define DP_PHY_TXn_TX_EMP_POST1_LVL_MASK		0x001f +# define DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN		0x0020 + +/* QPHY_TX_TX_DRV_LVL bits */ +# define DP_PHY_TXn_TX_DRV_LVL_MASK			0x001f +# define DP_PHY_TXn_TX_DRV_LVL_MUX_EN			0x0020 + +/* QSERDES_DP_PHY_PD_CTL bits */ +# define DP_PHY_PD_CTL_PWRDN				0x001 +# define DP_PHY_PD_CTL_PSR_PWRDN			0x002 +# define DP_PHY_PD_CTL_AUX_PWRDN			0x004 +# define DP_PHY_PD_CTL_LANE_0_1_PWRDN			0x008 +# define DP_PHY_PD_CTL_LANE_2_3_PWRDN			0x010 +# define DP_PHY_PD_CTL_PLL_PWRDN			0x020 +# define DP_PHY_PD_CTL_DP_CLAMP_EN			0x040 + +/* QPHY_DP_PHY_AUX_INTERRUPT_STATUS bits */ +# define PHY_AUX_STOP_ERR_MASK				0x01 +# define PHY_AUX_DEC_ERR_MASK				0x02 +# define PHY_AUX_SYNC_ERR_MASK				0x04 +# define PHY_AUX_ALIGN_ERR_MASK				0x08 +# define PHY_AUX_REQ_ERR_MASK				0x10 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c index ab61a9c73b18..0442b3120563 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c @@ -19,19 +19,13 @@  #include <linux/reset.h>  #include <linux/slab.h> +#include "phy-qcom-qmp-common.h" +  #include "phy-qcom-qmp.h" -/* QPHY_SW_RESET bit */ -#define SW_RESET				BIT(0) -/* QPHY_POWER_DOWN_CONTROL */ -#define SW_PWRDN				BIT(0) -#define REFCLK_DRV_DSBL				BIT(1)  /* QPHY_START_CONTROL bits */ -#define SERDES_START				BIT(0) -#define PCS_START				BIT(1)  #define PLL_READY_GATE_EN			BIT(3) -/* QPHY_PCS_STATUS bit */ -#define PHYSTATUS				BIT(6) +  /* QPHY_COM_PCS_READY_STATUS bit */  #define PCS_READY				BIT(0) @@ -39,30 +33,6 @@  #define POWER_DOWN_DELAY_US_MIN			10  #define POWER_DOWN_DELAY_US_MAX			20 -struct qmp_phy_init_tbl { -	unsigned int offset; -	unsigned int val; -	/* -	 * mask of lanes for which this register is written -	 * for cases when second lane needs different values -	 */ -	u8 lane_mask; -}; - -#define QMP_PHY_INIT_CFG(o, v)		\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = 0xff,	\ -	} - -#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = l,		\ -	} -  /* set of registers with offsets different per-PHY */  enum qphy_reg_layout {  	/* Common block control registers */ @@ -307,32 +277,6 @@ static const struct qmp_phy_cfg msm8996_pciephy_cfg = {  	.regs			= pciephy_regs_layout,  }; -static void qmp_pcie_msm8996_configure_lane(void __iomem *base, -					const struct qmp_phy_init_tbl tbl[], -					int num, -					u8 lane_mask) -{ -	int i; -	const struct qmp_phy_init_tbl *t = tbl; - -	if (!t) -		return; - -	for (i = 0; i < num; i++, t++) { -		if (!(t->lane_mask & lane_mask)) -			continue; - -		writel(t->val, base + t->offset); -	} -} - -static void qmp_pcie_msm8996_configure(void __iomem *base, -				   const struct qmp_phy_init_tbl tbl[], -				   int num) -{ -	qmp_pcie_msm8996_configure_lane(base, tbl, num, 0xff); -} -  static int qmp_pcie_msm8996_serdes_init(struct qmp_phy *qphy)  {  	struct qcom_qmp *qmp = qphy->qmp; @@ -344,7 +288,7 @@ static int qmp_pcie_msm8996_serdes_init(struct qmp_phy *qphy)  	unsigned int val;  	int ret; -	qmp_pcie_msm8996_configure(serdes, serdes_tbl, serdes_tbl_num); +	qmp_configure(serdes, serdes_tbl, serdes_tbl_num);  	qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);  	qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL], @@ -487,9 +431,9 @@ static int qmp_pcie_msm8996_power_on(struct phy *phy)  	}  	/* Tx, Rx, and PCS configurations */ -	qmp_pcie_msm8996_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); -	qmp_pcie_msm8996_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); -	qmp_pcie_msm8996_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); +	qmp_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); +	qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); +	qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);  	/*  	 * Pull out PHY from POWER DOWN state. diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 2af7115ef968..8836bb1ff0cc 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -22,6 +22,8 @@  #include <linux/reset.h>  #include <linux/slab.h> +#include "phy-qcom-qmp-common.h" +  #include "phy-qcom-qmp.h"  #include "phy-qcom-qmp-pcs-misc-v3.h"  #include "phy-qcom-qmp-pcs-pcie-v4.h" @@ -32,44 +34,8 @@  #include "phy-qcom-qmp-pcs-pcie-v6_20.h"  #include "phy-qcom-qmp-pcie-qhp.h" -/* QPHY_SW_RESET bit */ -#define SW_RESET				BIT(0) -/* QPHY_POWER_DOWN_CONTROL */ -#define SW_PWRDN				BIT(0) -#define REFCLK_DRV_DSBL				BIT(1) -/* QPHY_START_CONTROL bits */ -#define SERDES_START				BIT(0) -#define PCS_START				BIT(1) -/* QPHY_PCS_STATUS bit */ -#define PHYSTATUS				BIT(6) -#define PHYSTATUS_4_20				BIT(7) -  #define PHY_INIT_COMPLETE_TIMEOUT		10000 -struct qmp_phy_init_tbl { -	unsigned int offset; -	unsigned int val; -	/* -	 * mask of lanes for which this register is written -	 * for cases when second lane needs different values -	 */ -	u8 lane_mask; -}; - -#define QMP_PHY_INIT_CFG(o, v)		\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = 0xff,	\ -	} - -#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = l,		\ -	} -  /* set of registers with offsets different per-PHY */  enum qphy_reg_layout {  	/* PCS registers */ @@ -116,6 +82,13 @@ static const unsigned int pciephy_v5_regs_layout[QPHY_LAYOUT_SIZE] = {  	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V5_PCS_POWER_DOWN_CONTROL,  }; +static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = { +	[QPHY_SW_RESET]			= QPHY_V6_PCS_SW_RESET, +	[QPHY_START_CTRL]		= QPHY_V6_PCS_START_CONTROL, +	[QPHY_PCS_STATUS]		= QPHY_V6_PCS_PCS_STATUS1, +	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V6_PCS_POWER_DOWN_CONTROL, +}; +  static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {  	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),  	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), @@ -982,6 +955,143 @@ static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl[] = {  	QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),  }; +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_serdes_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x26), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x03), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x1a), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x12), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_POST_DIV_MUX, 0x40), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x14), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x46), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x04), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xa0), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MISC_1, 0x88), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x14), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x0f), +}; + +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x88), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0xd4), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B3, 0x9a), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B4, 0x32), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B5, 0xb6), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B6, 0x64), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE210, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE3, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE210, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE3, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE210, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE3, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f), +}; + +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_tx_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1d), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_RX, 0x03), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_1, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_2, 0x10), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_3, 0x51), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_TRAN_DRVR_EMP_EN, 0x34), +}; + +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_rx_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0c), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_GAIN_RATE_2, 0x04), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_BKUP_CTRL1, 0x15), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_1, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_2, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x45), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0b), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_SIGDET_ENABLES, 0x1c), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_PHPRE_CTRL, 0x20), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x39), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B0, 0x14), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B1, 0xb3), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B2, 0x58), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B3, 0x9a), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B4, 0x26), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B5, 0xb6), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B6, 0xee), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B0, 0xe4), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B1, 0xa4), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B2, 0x60), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B3, 0xdf), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x4b), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff), +}; + +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_tbl[] = { +	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_G3S2_PRE_GAIN, 0x2e), +	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_RX_SIGDET_LVL, 0xcc), +	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG4, 0x00), +	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG5, 0x22), +}; + +static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = { +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_OSC_DTCT_ATCIONS, 0x00), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG1, 0x16), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG5, 0x02), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN, 0x2e), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1, 0x03), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG3, 0x28), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_TX_RX_CONFIG, 0xc0), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_POWER_STATE_CONFIG2, 0x1d), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG5, 0x0f), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G3_FOM_EQ_CONFIG5, 0xf2), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0xf2), +}; +  static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {  	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),  	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34), @@ -1747,7 +1857,7 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_rx_tbl[] = {  	QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH2, 0x5b),  	QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH3, 0x1a),  	QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH4, 0x89), -	QMP_PHY_INIT_CFG(QSERDES_V6_RX_TX_ADAPT_POST_THRESH, 0xf0), +	QMP_PHY_INIT_CFG(QSERDES_V6_RX_TX_ADAPT_POST_THRESH, 0x00),  	QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FO_GAIN, 0x09),  	QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_GAIN, 0x05),  	QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH1, 0x08), @@ -1767,6 +1877,8 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_pcs_tbl[] = {  };  static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_pcs_misc_tbl[] = { +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_EQ_CONFIG1, 0x1e), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME, 0x27),  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1), @@ -1823,10 +1935,9 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_serdes_tbl[] = {  static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_ln_shrd_tbl[] = {  	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_Q_EN_RATES, 0xe),  	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x02), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x0d),  	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0x12),  	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12),  	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb), @@ -1843,6 +1954,7 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_ln_shrd_tbl[] = {  	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),  	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),  	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_SUMMER_CAL_SPD_MODE, 0x5b),  };  static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_tx_tbl[] = { @@ -1855,13 +1967,15 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_tx_tbl[] = {  };  static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_rx_tbl[] = { -	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0c),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_GAIN_RATE_2, 0x04),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x7c),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x05), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_TX_ADPT_CTRL, 0x10),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0a),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b), @@ -1883,11 +1997,13 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_rx_tbl[] = {  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x78),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76),  	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff), +	QMP_PHY_INIT_CFG(QSERDES_V6_20_VGA_CAL_CNTRL1, 0x00),  };  static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_pcs_tbl[] = { +	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_G12S1_TXDEEMPH_M6DB, 0x17),  	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_G3S2_PRE_GAIN, 0x2e), -	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_COM_ELECIDLE_DLY_SEL, 0x25), +	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_RX_SIGDET_LVL, 0xcc),  	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG4, 0x00),  	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG5, 0x22),  	QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_TX_RX_CONFIG1, 0x04), @@ -1898,6 +2014,8 @@ static const struct qmp_phy_init_tbl sm8550_qmp_gen4x2_pcie_pcs_misc_tbl[] = {  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_OSC_DTCT_ATCIONS, 0x00),  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG1, 0x16), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G3_RXEQEVAL_TIME, 0x27), +	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_RXEQEVAL_TIME, 0x27),  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_EQ_CONFIG5, 0x02),  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN, 0x2e),  	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1, 0x03), @@ -2936,7 +3054,7 @@ static const struct qmp_phy_cfg sdx65_qmp_pciephy_cfg = {  	.num_resets             = ARRAY_SIZE(sdm845_pciephy_reset_l),  	.vreg_list              = qmp_phy_vreg_l,  	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l), -	.regs                   = pciephy_v5_regs_layout, +	.regs                   = pciephy_v6_regs_layout,  	.pwrdn_ctrl             = SW_PWRDN,  	.phy_status             = PHYSTATUS_4_20, @@ -3069,7 +3187,7 @@ static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = {  	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),  	.vreg_list		= sm8550_qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l), -	.regs			= pciephy_v5_regs_layout, +	.regs			= pciephy_v6_regs_layout,  	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,  	.phy_status		= PHYSTATUS_4_20, @@ -3099,7 +3217,7 @@ static const struct qmp_phy_cfg sm8650_qmp_gen4x2_pciephy_cfg = {  	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),  	.vreg_list		= sm8550_qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l), -	.regs			= pciephy_v5_regs_layout, +	.regs			= pciephy_v6_regs_layout,  	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,  	.phy_status		= PHYSTATUS_4_20, @@ -3183,31 +3301,35 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x4_pciephy_cfg = {  	.phy_status		= PHYSTATUS_4_20,  }; -static void qmp_pcie_configure_lane(void __iomem *base, -					const struct qmp_phy_init_tbl tbl[], -					int num, -					u8 lane_mask) -{ -	int i; -	const struct qmp_phy_init_tbl *t = tbl; - -	if (!t) -		return; +static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = { +	.lanes = 2, -	for (i = 0; i < num; i++, t++) { -		if (!(t->lane_mask & lane_mask)) -			continue; +	.offsets		= &qmp_pcie_offsets_v6_20, -		writel(t->val, base + t->offset); -	} -} +	.tbls = { +		.serdes			= x1e80100_qmp_gen4x2_pcie_serdes_tbl, +		.serdes_num		= ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_serdes_tbl), +		.tx			= x1e80100_qmp_gen4x2_pcie_tx_tbl, +		.tx_num			= ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_tx_tbl), +		.rx			= x1e80100_qmp_gen4x2_pcie_rx_tbl, +		.rx_num			= ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_rx_tbl), +		.pcs			= x1e80100_qmp_gen4x2_pcie_pcs_tbl, +		.pcs_num		= ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_pcs_tbl), +		.pcs_misc		= x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl, +		.pcs_misc_num		= ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl), +		.ln_shrd		= x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl, +		.ln_shrd_num		= ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl), +	}, +	.reset_list		= sdm845_pciephy_reset_l, +	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l), +	.vreg_list		= sm8550_qmp_phy_vreg_l, +	.num_vregs		= ARRAY_SIZE(sm8550_qmp_phy_vreg_l), +	.regs			= pciephy_v6_regs_layout, -static void qmp_pcie_configure(void __iomem *base, -					const struct qmp_phy_init_tbl tbl[], -					int num) -{ -	qmp_pcie_configure_lane(base, tbl, num, 0xff); -} +	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL, +	.phy_status		= PHYSTATUS_4_20, +	.has_nocsr_reset	= true, +};  static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)  { @@ -3220,11 +3342,11 @@ static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_  	tx4 = qmp->port_b + offs->tx2;  	rx4 = qmp->port_b + offs->rx2; -	qmp_pcie_configure_lane(tx3, tbls->tx, tbls->tx_num, 1); -	qmp_pcie_configure_lane(rx3, tbls->rx, tbls->rx_num, 1); +	qmp_configure_lane(tx3, tbls->tx, tbls->tx_num, 1); +	qmp_configure_lane(rx3, tbls->rx, tbls->rx_num, 1); -	qmp_pcie_configure_lane(tx4, tbls->tx, tbls->tx_num, 2); -	qmp_pcie_configure_lane(rx4, tbls->rx, tbls->rx_num, 2); +	qmp_configure_lane(tx4, tbls->tx, tbls->tx_num, 2); +	qmp_configure_lane(rx4, tbls->rx, tbls->rx_num, 2);  }  static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls) @@ -3242,25 +3364,25 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c  	if (!tbls)  		return; -	qmp_pcie_configure(serdes, tbls->serdes, tbls->serdes_num); +	qmp_configure(serdes, tbls->serdes, tbls->serdes_num); -	qmp_pcie_configure_lane(tx, tbls->tx, tbls->tx_num, 1); -	qmp_pcie_configure_lane(rx, tbls->rx, tbls->rx_num, 1); +	qmp_configure_lane(tx, tbls->tx, tbls->tx_num, 1); +	qmp_configure_lane(rx, tbls->rx, tbls->rx_num, 1);  	if (cfg->lanes >= 2) { -		qmp_pcie_configure_lane(tx2, tbls->tx, tbls->tx_num, 2); -		qmp_pcie_configure_lane(rx2, tbls->rx, tbls->rx_num, 2); +		qmp_configure_lane(tx2, tbls->tx, tbls->tx_num, 2); +		qmp_configure_lane(rx2, tbls->rx, tbls->rx_num, 2);  	} -	qmp_pcie_configure(pcs, tbls->pcs, tbls->pcs_num); -	qmp_pcie_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num); +	qmp_configure(pcs, tbls->pcs, tbls->pcs_num); +	qmp_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);  	if (cfg->lanes >= 4 && qmp->tcsr_4ln_config) { -		qmp_pcie_configure(serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num); +		qmp_configure(serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num);  		qmp_pcie_init_port_b(qmp, tbls);  	} -	qmp_pcie_configure(ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num); +	qmp_configure(ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);  }  static int qmp_pcie_init(struct phy *phy) @@ -3885,6 +4007,12 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {  	}, {  		.compatible = "qcom,sm8650-qmp-gen4x2-pcie-phy",  		.data = &sm8650_qmp_gen4x2_pciephy_cfg, +	}, { +		.compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy", +		.data = &sm8550_qmp_gen3x2_pciephy_cfg, +	}, { +		.compatible = "qcom,x1e80100-qmp-gen4x2-pcie-phy", +		.data = &x1e80100_qmp_gen4x2_pciephy_cfg,  	},  	{ },  }; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h index 91e70002eb47..0ca79333d942 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h @@ -7,6 +7,8 @@  #define QCOM_PHY_QMP_PCS_PCIE_V6_H_  /* Only for QMP V6 PHY - PCIE have different offsets than V5 */ +#define QPHY_PCIE_V6_PCS_PCIE_EQ_CONFIG1		0xa4 +#define QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME		0xf4  #define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2	0x0c  #define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4	0x14  #define QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE	0x20 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h index e3eb08776339..dfcecf31a606 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_20.h @@ -12,6 +12,8 @@  #define QPHY_PCIE_V6_20_PCS_ENDPOINT_REFCLK_DRIVE	0x01c  #define QPHY_PCIE_V6_20_PCS_OSC_DTCT_ATCIONS		0x090  #define QPHY_PCIE_V6_20_PCS_EQ_CONFIG1			0x0a0 +#define QPHY_PCIE_V6_20_PCS_G3_RXEQEVAL_TIME		0x0f0 +#define QPHY_PCIE_V6_20_PCS_G4_RXEQEVAL_TIME		0x0f4  #define QPHY_PCIE_V6_20_PCS_EQ_CONFIG5			0x108  #define QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN			0x15c  #define QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1	0x17c diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h new file mode 100644 index 000000000000..4d8c962f5e0f --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef QCOM_PHY_QMP_PCS_SGMII_H_ +#define QCOM_PHY_QMP_PCS_SGMII_H_ + +#define QPHY_PCS_PHY_START				0x000 +#define QPHY_PCS_POWER_DOWN_CONTROL			0x004 +#define QPHY_PCS_SW_RESET				0x008 +#define QPHY_PCS_LINE_RESET_TIME			0x00c +#define QPHY_PCS_TX_LARGE_AMP_DRV_LVL			0x020 +#define QPHY_PCS_TX_SMALL_AMP_DRV_LVL			0x028 +#define QPHY_PCS_PCS_READY_STATUS			0x094 +#define QPHY_PCS_TX_MID_TERM_CTRL1			0x0d8 +#define QPHY_PCS_TX_MID_TERM_CTRL2			0x0dc +#define QPHY_PCS_SGMII_MISC_CTRL8			0x118 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h index fe6c450f6123..970cc0667809 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h @@ -19,6 +19,7 @@  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL		0x060  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY		0x074  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY		0x0bc +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY	0x12c  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL		0x158  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE			0x17c  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME		0x184 @@ -28,5 +29,6 @@  #define QPHY_V6_PCS_UFS_READY_STATUS			0x1a8  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1		0x1f4  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1		0x1fc +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME		0x220  #endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h index 9c3f1e4950e6..4d9615cc0383 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_20.h @@ -7,6 +7,7 @@  #define QCOM_PHY_QMP_PCS_V6_20_H_  /* Only for QMP V6_20 PHY - USB/PCIe PCS registers */ +#define QPHY_V6_20_PCS_G12S1_TXDEEMPH_M6DB		0x170  #define QPHY_V6_20_PCS_G3S2_PRE_GAIN			0x178  #define QPHY_V6_20_PCS_RX_SIGDET_LVL			0x190  #define QPHY_V6_20_PCS_COM_ELECIDLE_DLY_SEL		0x1b8 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h index ec7291424dd1..328c6c0b0b09 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h @@ -60,6 +60,8 @@  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE			0xe8  #define QSERDES_V6_COM_PLL_IVCO					0xf4  #define QSERDES_V6_COM_PLL_IVCO_MODE1				0xf8 +#define QSERDES_V6_COM_CMN_IETRIM				0xfc +#define QSERDES_V6_COM_CMN_IPTRIM				0x100  #define QSERDES_V6_COM_SYSCLK_EN_SEL				0x110  #define QSERDES_V6_COM_RESETSM_CNTRL				0x118  #define QSERDES_V6_COM_LOCK_CMP_EN				0x120 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h index 35d497fd9f9a..d9a87bd95590 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h @@ -15,13 +15,19 @@  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2		0x08  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4		0x10 +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4		0x24  #define QSERDES_UFS_V6_RX_UCDR_SO_SATURATION			0x28 +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4	0x54  #define QSERDES_UFS_V6_RX_UCDR_PI_CTRL1				0x58  #define QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0			0xc4  #define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2			0xd4  #define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4			0xdc +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4			0xf0 +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS			0xf4  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL			0x178 +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1		0x1bc  #define QSERDES_UFS_V6_RX_INTERFACE_MODE			0x1e0 +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3			0x1c4  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0			0x208  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1			0x20c  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3			0x214 @@ -33,6 +39,8 @@  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5				0x264  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8				0x270  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3				0x280 +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4				0x284  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6				0x28c +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL			0x2f8  #endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h index 6ed5339fd2ea..7bac5d5c6c34 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_20.h @@ -23,6 +23,8 @@  #define QSERDES_V6_20_RX_DFE_1					0xac  #define QSERDES_V6_20_RX_DFE_2					0xb0  #define QSERDES_V6_20_RX_DFE_3					0xb4 +#define QSERDES_V6_20_RX_TX_ADPT_CTRL				0xd4 +#define QSERDES_V6_20_VGA_CAL_CNTRL1				0xe0  #define QSERDES_V6_20_RX_VGA_CAL_MAN_VAL			0xe8  #define QSERDES_V6_20_RX_GM_CAL					0x10c  #define QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4			0x120 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c index 3c2e6255e26f..590432d581f9 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c @@ -20,6 +20,9 @@  #include <linux/slab.h>  #include <ufs/unipro.h> + +#include "phy-qcom-qmp-common.h" +  #include "phy-qcom-qmp.h"  #include "phy-qcom-qmp-pcs-ufs-v2.h"  #include "phy-qcom-qmp-pcs-ufs-v3.h" @@ -29,41 +32,12 @@  #include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h" -/* QPHY_SW_RESET bit */ -#define SW_RESET				BIT(0) -/* QPHY_POWER_DOWN_CONTROL */ -#define SW_PWRDN				BIT(0) -/* QPHY_START_CONTROL bits */ -#define SERDES_START				BIT(0) -#define PCS_START				BIT(1)  /* QPHY_PCS_READY_STATUS bit */  #define PCS_READY				BIT(0)  #define PHY_INIT_COMPLETE_TIMEOUT		10000 -struct qmp_phy_init_tbl { -	unsigned int offset; -	unsigned int val; -	/* -	 * mask of lanes for which this register is written -	 * for cases when second lane needs different values -	 */ -	u8 lane_mask; -}; - -#define QMP_PHY_INIT_CFG(o, v)		\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = 0xff,	\ -	} - -#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = l,		\ -	} +#define NUM_OVERLAY				2  /* set of registers with offsets different per-PHY */  enum qphy_reg_layout { @@ -754,15 +728,22 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04), -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41), -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06), +}; + +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = { +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44), +}; + +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = { +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18), @@ -771,19 +752,24 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),  }; -static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = { -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44), +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = { +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c), +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),  };  static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {  	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),  	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07), +}; + +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {  	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),  };  static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {  	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c), -	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),  	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),  	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2), @@ -799,16 +785,45 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {  	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),  }; +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = { +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e), +}; + +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = { +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff), +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30), +}; +  static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {  	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),  	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),  	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), -	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),  	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02), +}; + +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = { +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),  	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),  	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),  }; +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = { +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33), +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f), +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e), +}; +  static const struct qmp_phy_init_tbl sm8650_ufsphy_serdes[] = {  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),  	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16), @@ -889,6 +904,8 @@ struct qmp_phy_cfg_tbls {  	int rx_num;  	const struct qmp_phy_init_tbl *pcs;  	int pcs_num; +	/* Maximum supported Gear of this tbls */ +	u32 max_gear;  };  /* struct qmp_phy_cfg - per-PHY initialization config */ @@ -896,17 +913,16 @@ struct qmp_phy_cfg {  	int lanes;  	const struct qmp_ufs_offsets *offsets; +	/* Maximum supported Gear of this config */ +	u32 max_supported_gear;  	/* Main init sequence for PHY blocks - serdes, tx, rx, pcs */  	const struct qmp_phy_cfg_tbls tbls;  	/* Additional sequence for HS Series B */  	const struct qmp_phy_cfg_tbls tbls_hs_b; -	/* Additional sequence for HS G4 */ -	const struct qmp_phy_cfg_tbls tbls_hs_g4; +	/* Additional sequence for different HS Gears */ +	const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY]; -	/* clock ids to be requested */ -	const char * const *clk_list; -	int num_clks;  	/* regulators to be requested */  	const char * const *vreg_list;  	int num_vregs; @@ -932,6 +948,7 @@ struct qmp_ufs {  	void __iomem *rx2;  	struct clk_bulk_data *clks; +	int num_clks;  	struct regulator_bulk_data *vregs;  	struct reset_control *ufs_reset; @@ -964,20 +981,6 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)  	readl(base + offset);  } -/* list of clocks required by phy */ -static const char * const msm8996_ufs_phy_clk_l[] = { -	"ref", -}; - -/* the primary usb3 phy on sm8250 doesn't have a ref clock */ -static const char * const sm8450_ufs_phy_clk_l[] = { -	"qref", "ref", "ref_aux", -}; - -static const char * const sdm845_ufs_phy_clk_l[] = { -	"ref", "ref_aux", -}; -  /* list of regulators */  static const char * const qmp_phy_vreg_l[] = {  	"vdda-phy", "vdda-pll", @@ -1005,6 +1008,7 @@ static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {  	.lanes			= 1,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G3,  	.tbls = {  		.serdes		= msm8996_ufsphy_serdes, @@ -1015,9 +1019,6 @@ static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {  		.rx_num		= ARRAY_SIZE(msm8996_ufsphy_rx),  	}, -	.clk_list		= msm8996_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(msm8996_ufs_phy_clk_l), -  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l), @@ -1030,6 +1031,7 @@ static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G4,  	.tbls = {  		.serdes		= sm8350_ufsphy_serdes, @@ -1045,16 +1047,15 @@ static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = {  		.serdes		= sm8350_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),  	}, -	.tbls_hs_g4 = { +	.tbls_hs_overlay[0] = {  		.tx		= sm8350_ufsphy_g4_tx,  		.tx_num		= ARRAY_SIZE(sm8350_ufsphy_g4_tx),  		.rx		= sm8350_ufsphy_g4_rx,  		.rx_num		= ARRAY_SIZE(sm8350_ufsphy_g4_rx),  		.pcs		= sm8350_ufsphy_g4_pcs,  		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs), +		.max_gear	= UFS_HS_G4,  	}, -	.clk_list		= sm8450_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sm8450_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v5_regs_layout, @@ -1064,6 +1065,7 @@ static const struct qmp_phy_cfg sc7280_ufsphy_cfg = {  	.lanes                  = 2,  	.offsets                = &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G4,  	.tbls = {  		.serdes         = sm8150_ufsphy_serdes, @@ -1079,16 +1081,15 @@ static const struct qmp_phy_cfg sc7280_ufsphy_cfg = {  		.serdes         = sm8150_ufsphy_hs_b_serdes,  		.serdes_num     = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),  	}, -	.tbls_hs_g4 = { +	.tbls_hs_overlay[0] = {  		.tx             = sm8250_ufsphy_hs_g4_tx,  		.tx_num         = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),  		.rx             = sc7280_ufsphy_hs_g4_rx,  		.rx_num         = ARRAY_SIZE(sc7280_ufsphy_hs_g4_rx),  		.pcs            = sm8150_ufsphy_hs_g4_pcs,  		.pcs_num        = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), +		.max_gear	= UFS_HS_G4,  	}, -	.clk_list               = sm8450_ufs_phy_clk_l, -	.num_clks               = ARRAY_SIZE(sm8450_ufs_phy_clk_l),  	.vreg_list              = qmp_phy_vreg_l,  	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),  	.regs                   = ufsphy_v4_regs_layout, @@ -1098,6 +1099,7 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G4,  	.tbls = {  		.serdes		= sm8350_ufsphy_serdes, @@ -1113,16 +1115,15 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {  		.serdes		= sm8350_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),  	}, -	.tbls_hs_g4 = { +	.tbls_hs_overlay[0] = {  		.tx		= sm8350_ufsphy_g4_tx,  		.tx_num		= ARRAY_SIZE(sm8350_ufsphy_g4_tx),  		.rx		= sm8350_ufsphy_g4_rx,  		.rx_num		= ARRAY_SIZE(sm8350_ufsphy_g4_rx),  		.pcs		= sm8350_ufsphy_g4_pcs,  		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs), +		.max_gear	= UFS_HS_G4,  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v5_regs_layout, @@ -1132,6 +1133,7 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G3,  	.tbls = {  		.serdes		= sdm845_ufsphy_serdes, @@ -1147,8 +1149,6 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {  		.serdes		= sdm845_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v3_regs_layout, @@ -1160,6 +1160,7 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {  	.lanes			= 1,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G3,  	.tbls = {  		.serdes		= sm6115_ufsphy_serdes, @@ -1175,8 +1176,6 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {  		.serdes		= sm6115_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes),  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v2_regs_layout, @@ -1188,6 +1187,7 @@ static const struct qmp_phy_cfg sm7150_ufsphy_cfg = {  	.lanes			= 1,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G3,  	.tbls = {  		.serdes		= sdm845_ufsphy_serdes, @@ -1203,8 +1203,6 @@ static const struct qmp_phy_cfg sm7150_ufsphy_cfg = {  		.serdes		= sdm845_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v3_regs_layout, @@ -1216,6 +1214,7 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G4,  	.tbls = {  		.serdes		= sm8150_ufsphy_serdes, @@ -1231,16 +1230,15 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {  		.serdes		= sm8150_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),  	}, -	.tbls_hs_g4 = { +	.tbls_hs_overlay[0] = {  		.tx		= sm8150_ufsphy_hs_g4_tx,  		.tx_num		= ARRAY_SIZE(sm8150_ufsphy_hs_g4_tx),  		.rx		= sm8150_ufsphy_hs_g4_rx,  		.rx_num		= ARRAY_SIZE(sm8150_ufsphy_hs_g4_rx),  		.pcs		= sm8150_ufsphy_hs_g4_pcs,  		.pcs_num	= ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), +		.max_gear	= UFS_HS_G4,  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v4_regs_layout, @@ -1250,6 +1248,7 @@ static const struct qmp_phy_cfg sm8250_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G4,  	.tbls = {  		.serdes		= sm8150_ufsphy_serdes, @@ -1265,16 +1264,15 @@ static const struct qmp_phy_cfg sm8250_ufsphy_cfg = {  		.serdes		= sm8150_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),  	}, -	.tbls_hs_g4 = { +	.tbls_hs_overlay[0] = {  		.tx		= sm8250_ufsphy_hs_g4_tx,  		.tx_num		= ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),  		.rx		= sm8250_ufsphy_hs_g4_rx,  		.rx_num		= ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx),  		.pcs		= sm8150_ufsphy_hs_g4_pcs,  		.pcs_num	= ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), +		.max_gear	= UFS_HS_G4,  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v4_regs_layout, @@ -1284,6 +1282,7 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G4,  	.tbls = {  		.serdes		= sm8350_ufsphy_serdes, @@ -1299,16 +1298,15 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {  		.serdes		= sm8350_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),  	}, -	.tbls_hs_g4 = { +	.tbls_hs_overlay[0] = {  		.tx		= sm8350_ufsphy_g4_tx,  		.tx_num		= ARRAY_SIZE(sm8350_ufsphy_g4_tx),  		.rx		= sm8350_ufsphy_g4_rx,  		.rx_num		= ARRAY_SIZE(sm8350_ufsphy_g4_rx),  		.pcs		= sm8350_ufsphy_g4_pcs,  		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs), +		.max_gear	= UFS_HS_G4,  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v5_regs_layout, @@ -1318,6 +1316,7 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets, +	.max_supported_gear	= UFS_HS_G4,  	.tbls = {  		.serdes		= sm8350_ufsphy_serdes, @@ -1333,16 +1332,15 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {  		.serdes		= sm8350_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes),  	}, -	.tbls_hs_g4 = { +	.tbls_hs_overlay[0] = {  		.tx		= sm8350_ufsphy_g4_tx,  		.tx_num		= ARRAY_SIZE(sm8350_ufsphy_g4_tx),  		.rx		= sm8350_ufsphy_g4_rx,  		.rx_num		= ARRAY_SIZE(sm8350_ufsphy_g4_rx),  		.pcs		= sm8350_ufsphy_g4_pcs,  		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs), +		.max_gear	= UFS_HS_G4,  	}, -	.clk_list		= sm8450_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sm8450_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v5_regs_layout, @@ -1352,6 +1350,7 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets_v6, +	.max_supported_gear	= UFS_HS_G5,  	.tbls = {  		.serdes		= sm8550_ufsphy_serdes, @@ -1367,8 +1366,26 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {  		.serdes		= sm8550_ufsphy_hs_b_serdes,  		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l), +	.tbls_hs_overlay[0] = { +		.serdes		= sm8550_ufsphy_g4_serdes, +		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_g4_serdes), +		.tx		= sm8550_ufsphy_g4_tx, +		.tx_num		= ARRAY_SIZE(sm8550_ufsphy_g4_tx), +		.rx		= sm8550_ufsphy_g4_rx, +		.rx_num		= ARRAY_SIZE(sm8550_ufsphy_g4_rx), +		.pcs		= sm8550_ufsphy_g4_pcs, +		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_g4_pcs), +		.max_gear	= UFS_HS_G4, +	}, +	.tbls_hs_overlay[1] = { +		.serdes		= sm8550_ufsphy_g5_serdes, +		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_g5_serdes), +		.rx		= sm8550_ufsphy_g5_rx, +		.rx_num		= ARRAY_SIZE(sm8550_ufsphy_g5_rx), +		.pcs		= sm8550_ufsphy_g5_pcs, +		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_g5_pcs), +		.max_gear	= UFS_HS_G5, +	},  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v6_regs_layout, @@ -1378,6 +1395,7 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {  	.lanes			= 2,  	.offsets		= &qmp_ufs_offsets_v6, +	.max_supported_gear	= UFS_HS_G5,  	.tbls = {  		.serdes		= sm8650_ufsphy_serdes, @@ -1389,44 +1407,16 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {  		.pcs		= sm8650_ufsphy_pcs,  		.pcs_num	= ARRAY_SIZE(sm8650_ufsphy_pcs),  	}, -	.clk_list		= sdm845_ufs_phy_clk_l, -	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),  	.vreg_list		= qmp_phy_vreg_l,  	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),  	.regs			= ufsphy_v6_regs_layout,  }; -static void qmp_ufs_configure_lane(void __iomem *base, -					const struct qmp_phy_init_tbl tbl[], -					int num, -					u8 lane_mask) -{ -	int i; -	const struct qmp_phy_init_tbl *t = tbl; - -	if (!t) -		return; - -	for (i = 0; i < num; i++, t++) { -		if (!(t->lane_mask & lane_mask)) -			continue; - -		writel(t->val, base + t->offset); -	} -} - -static void qmp_ufs_configure(void __iomem *base, -				   const struct qmp_phy_init_tbl tbl[], -				   int num) -{ -	qmp_ufs_configure_lane(base, tbl, num, 0xff); -} -  static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)  {  	void __iomem *serdes = qmp->serdes; -	qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num); +	qmp_configure(serdes, tbls->serdes, tbls->serdes_num);  }  static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls) @@ -1435,12 +1425,12 @@ static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbl  	void __iomem *tx = qmp->tx;  	void __iomem *rx = qmp->rx; -	qmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1); -	qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1); +	qmp_configure_lane(tx, tbls->tx, tbls->tx_num, 1); +	qmp_configure_lane(rx, tbls->rx, tbls->rx_num, 1);  	if (cfg->lanes >= 2) { -		qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2); -		qmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2); +		qmp_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2); +		qmp_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);  	}  } @@ -1448,20 +1438,52 @@ static void qmp_ufs_pcs_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls  {  	void __iomem *pcs = qmp->pcs; -	qmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num); +	qmp_configure(pcs, tbls->pcs, tbls->pcs_num); +} + +static int qmp_ufs_get_gear_overlay(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg) +{ +	u32 max_gear, floor_max_gear = cfg->max_supported_gear; +	int idx, ret = -EINVAL; + +	for (idx = NUM_OVERLAY - 1; idx >= 0; idx--) { +		max_gear = cfg->tbls_hs_overlay[idx].max_gear; + +		/* Skip if the table is not available */ +		if (max_gear == 0) +			continue; + +		/* Direct matching, bail */ +		if (qmp->submode == max_gear) +			return idx; + +		/* If no direct matching, the lowest gear is the best matching */ +		if (max_gear < floor_max_gear) { +			ret = idx; +			floor_max_gear = max_gear; +		} +	} + +	return ret;  }  static void qmp_ufs_init_registers(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)  { +	int i; +  	qmp_ufs_serdes_init(qmp, &cfg->tbls); -	if (qmp->mode == PHY_MODE_UFS_HS_B) -		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);  	qmp_ufs_lanes_init(qmp, &cfg->tbls); -	if (qmp->submode == UFS_HS_G4) -		qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g4);  	qmp_ufs_pcs_init(qmp, &cfg->tbls); -	if (qmp->submode == UFS_HS_G4) -		qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g4); + +	i = qmp_ufs_get_gear_overlay(qmp, cfg); +	if (i >= 0) { +		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_overlay[i]); +		qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_overlay[i]); +		qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_overlay[i]); +	} + +	if (qmp->mode == PHY_MODE_UFS_HS_B) +		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);  }  static int qmp_ufs_com_init(struct qmp_ufs *qmp) @@ -1476,7 +1498,7 @@ static int qmp_ufs_com_init(struct qmp_ufs *qmp)  		return ret;  	} -	ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks); +	ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);  	if (ret)  		goto err_disable_regulators; @@ -1496,7 +1518,7 @@ static int qmp_ufs_com_exit(struct qmp_ufs *qmp)  	reset_control_assert(qmp->ufs_reset); -	clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); +	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);  	regulator_bulk_disable(cfg->num_vregs, qmp->vregs); @@ -1633,6 +1655,12 @@ static int qmp_ufs_disable(struct phy *phy)  static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode)  {  	struct qmp_ufs *qmp = phy_get_drvdata(phy); +	const struct qmp_phy_cfg *cfg = qmp->cfg; + +	if (submode > cfg->max_supported_gear || submode == 0) { +		dev_err(qmp->dev, "Invalid PHY submode %d\n", submode); +		return -EINVAL; +	}  	qmp->mode = mode;  	qmp->submode = submode; @@ -1666,19 +1694,13 @@ static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)  static int qmp_ufs_clk_init(struct qmp_ufs *qmp)  { -	const struct qmp_phy_cfg *cfg = qmp->cfg;  	struct device *dev = qmp->dev; -	int num = cfg->num_clks; -	int i; -	qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); -	if (!qmp->clks) -		return -ENOMEM; - -	for (i = 0; i < num; i++) -		qmp->clks[i].id = cfg->clk_list[i]; +	qmp->num_clks = devm_clk_bulk_get_all(dev, &qmp->clks); +	if (qmp->num_clks < 0) +		return qmp->num_clks; -	return devm_clk_bulk_get(dev, num, qmp->clks); +	return 0;  }  static void qmp_ufs_clk_release_provider(void *res) @@ -1881,6 +1903,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {  		.compatible = "qcom,sa8775p-qmp-ufs-phy",  		.data = &sa8775p_ufsphy_cfg,  	}, { +		.compatible = "qcom,sc7180-qmp-ufs-phy", +		.data = &sm7150_ufsphy_cfg, +	}, {  		.compatible = "qcom,sc7280-qmp-ufs-phy",  		.data = &sc7280_ufsphy_cfg,  	}, { diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c index cf466f6df94d..6d0ba39c1943 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c @@ -25,15 +25,7 @@  #include "phy-qcom-qmp-pcs-usb-v4.h"  #include "phy-qcom-qmp-pcs-usb-v5.h" -/* QPHY_SW_RESET bit */ -#define SW_RESET				BIT(0) -/* QPHY_POWER_DOWN_CONTROL */ -#define SW_PWRDN				BIT(0) -/* QPHY_START_CONTROL bits */ -#define SERDES_START				BIT(0) -#define PCS_START				BIT(1) -/* QPHY_PCS_STATUS bit */ -#define PHYSTATUS				BIT(6) +#include "phy-qcom-qmp-dp-com-v3.h"  /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */  /* DP PHY soft reset */ @@ -49,17 +41,6 @@  #define USB3_MODE				BIT(0) /* enables USB3 mode */  #define DP_MODE					BIT(1) /* enables DP mode */ -/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */ -#define ARCVR_DTCT_EN				BIT(0) -#define ALFPS_DTCT_EN				BIT(1) -#define ARCVR_DTCT_EVENT_SEL			BIT(4) - -/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */ -#define IRQ_CLEAR				BIT(0) - -/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */ -#define CLAMP_EN				BIT(0) /* enables i/o clamp_n */ -  #define PHY_INIT_COMPLETE_TIMEOUT		10000  struct qmp_phy_init_tbl { @@ -507,8 +488,6 @@ struct qmp_usb_legacy_offsets {  /* struct qmp_phy_cfg - per-PHY initialization config */  struct qmp_phy_cfg { -	int lanes; -  	const struct qmp_usb_legacy_offsets *offsets;  	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */ @@ -621,8 +600,6 @@ static const char * const qmp_phy_vreg_l[] = {  };  static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = { -	.lanes			= 2, -  	.serdes_tbl		= qmp_v3_usb3_serdes_tbl,  	.serdes_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),  	.tx_tbl			= qmp_v3_usb3_tx_tbl, @@ -641,8 +618,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {  };  static const struct qmp_phy_cfg sc7180_usb3phy_cfg = { -	.lanes			= 2, -  	.serdes_tbl		= qmp_v3_usb3_serdes_tbl,  	.serdes_tbl_num		= ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),  	.tx_tbl			= qmp_v3_usb3_tx_tbl, @@ -661,8 +636,6 @@ static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {  };  static const struct qmp_phy_cfg sm8150_usb3phy_cfg = { -	.lanes			= 2, -  	.serdes_tbl		= sm8150_usb3_serdes_tbl,  	.serdes_tbl_num		= ARRAY_SIZE(sm8150_usb3_serdes_tbl),  	.tx_tbl			= sm8150_usb3_tx_tbl, @@ -684,8 +657,6 @@ static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {  };  static const struct qmp_phy_cfg sm8250_usb3phy_cfg = { -	.lanes			= 2, -  	.serdes_tbl		= sm8150_usb3_serdes_tbl,  	.serdes_tbl_num		= ARRAY_SIZE(sm8150_usb3_serdes_tbl),  	.tx_tbl			= sm8250_usb3_tx_tbl, @@ -707,8 +678,6 @@ static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {  };  static const struct qmp_phy_cfg sm8350_usb3phy_cfg = { -	.lanes			= 2, -  	.serdes_tbl		= sm8150_usb3_serdes_tbl,  	.serdes_tbl_num		= ARRAY_SIZE(sm8150_usb3_serdes_tbl),  	.tx_tbl			= sm8350_usb3_tx_tbl, @@ -874,10 +843,8 @@ static int qmp_usb_legacy_power_on(struct phy *phy)  	qmp_usb_legacy_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);  	qmp_usb_legacy_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); -	if (cfg->lanes >= 2) { -		qmp_usb_legacy_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); -		qmp_usb_legacy_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); -	} +	qmp_usb_legacy_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); +	qmp_usb_legacy_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);  	qmp_usb_legacy_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); @@ -1180,27 +1147,11 @@ static int phy_pipe_clk_register(struct qmp_usb *qmp, struct device_node *np)  	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);  } -static void __iomem *qmp_usb_legacy_iomap(struct device *dev, struct device_node *np, -					int index, bool exclusive) -{ -	struct resource res; - -	if (!exclusive) { -		if (of_address_to_resource(np, index, &res)) -			return IOMEM_ERR_PTR(-EINVAL); - -		return devm_ioremap(dev, res.start, resource_size(&res)); -	} - -	return devm_of_iomap(dev, np, index, NULL); -} -  static int qmp_usb_legacy_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np)  {  	struct platform_device *pdev = to_platform_device(qmp->dev);  	const struct qmp_phy_cfg *cfg = qmp->cfg;  	struct device *dev = qmp->dev; -	bool exclusive = true;  	qmp->serdes = devm_platform_ioremap_resource(pdev, 0);  	if (IS_ERR(qmp->serdes)) @@ -1224,27 +1175,22 @@ static int qmp_usb_legacy_parse_dt_legacy(struct qmp_usb *qmp, struct device_nod  	if (IS_ERR(qmp->rx))  		return PTR_ERR(qmp->rx); -	qmp->pcs = qmp_usb_legacy_iomap(dev, np, 2, exclusive); +	qmp->pcs = devm_of_iomap(dev, np, 2, NULL);  	if (IS_ERR(qmp->pcs))  		return PTR_ERR(qmp->pcs);  	if (cfg->pcs_usb_offset)  		qmp->pcs_usb = qmp->pcs + cfg->pcs_usb_offset; -	if (cfg->lanes >= 2) { -		qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); -		if (IS_ERR(qmp->tx2)) -			return PTR_ERR(qmp->tx2); - -		qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); -		if (IS_ERR(qmp->rx2)) -			return PTR_ERR(qmp->rx2); +	qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); +	if (IS_ERR(qmp->tx2)) +		return PTR_ERR(qmp->tx2); -		qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); -	} else { -		qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL); -	} +	qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); +	if (IS_ERR(qmp->rx2)) +		return PTR_ERR(qmp->rx2); +	qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);  	if (IS_ERR(qmp->pcs_misc)) {  		dev_vdbg(dev, "PHY pcs_misc-reg not used\n");  		qmp->pcs_misc = NULL; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c index 5c003988c35d..85253936fac3 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c @@ -19,6 +19,8 @@  #include <linux/reset.h>  #include <linux/slab.h> +#include "phy-qcom-qmp-common.h" +  #include "phy-qcom-qmp.h"  #include "phy-qcom-qmp-pcs-misc-v3.h"  #include "phy-qcom-qmp-pcs-misc-v4.h" @@ -27,67 +29,8 @@  #include "phy-qcom-qmp-pcs-usb-v6.h"  #include "phy-qcom-qmp-pcs-usb-v7.h" -/* QPHY_SW_RESET bit */ -#define SW_RESET				BIT(0) -/* QPHY_POWER_DOWN_CONTROL */ -#define SW_PWRDN				BIT(0) -/* QPHY_START_CONTROL bits */ -#define SERDES_START				BIT(0) -#define PCS_START				BIT(1) -/* QPHY_PCS_STATUS bit */ -#define PHYSTATUS				BIT(6) - -/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */ -/* DP PHY soft reset */ -#define SW_DPPHY_RESET				BIT(0) -/* mux to select DP PHY reset control, 0:HW control, 1: software reset */ -#define SW_DPPHY_RESET_MUX			BIT(1) -/* USB3 PHY soft reset */ -#define SW_USB3PHY_RESET			BIT(2) -/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */ -#define SW_USB3PHY_RESET_MUX			BIT(3) - -/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */ -#define USB3_MODE				BIT(0) /* enables USB3 mode */ -#define DP_MODE					BIT(1) /* enables DP mode */ - -/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */ -#define ARCVR_DTCT_EN				BIT(0) -#define ALFPS_DTCT_EN				BIT(1) -#define ARCVR_DTCT_EVENT_SEL			BIT(4) - -/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */ -#define IRQ_CLEAR				BIT(0) - -/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */ -#define CLAMP_EN				BIT(0) /* enables i/o clamp_n */ -  #define PHY_INIT_COMPLETE_TIMEOUT		10000 -struct qmp_phy_init_tbl { -	unsigned int offset; -	unsigned int val; -	/* -	 * mask of lanes for which this register is written -	 * for cases when second lane needs different values -	 */ -	u8 lane_mask; -}; - -#define QMP_PHY_INIT_CFG(o, v)		\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = 0xff,	\ -	} - -#define QMP_PHY_INIT_CFG_LANE(o, v, l)	\ -	{				\ -		.offset = o,		\ -		.val = v,		\ -		.lane_mask = l,		\ -	} -  /* set of registers with offsets different per-PHY */  enum qphy_reg_layout {  	/* PCS registers */ @@ -121,15 +64,6 @@ static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {  	[QPHY_PCS_MISC_CLAMP_ENABLE]	= QPHY_V3_PCS_MISC_CLAMP_ENABLE,  }; -static const unsigned int qmp_v3_usb3phy_regs_layout_qcm2290[QPHY_LAYOUT_SIZE] = { -	[QPHY_SW_RESET]			= QPHY_V3_PCS_SW_RESET, -	[QPHY_START_CTRL]		= QPHY_V3_PCS_START_CONTROL, -	[QPHY_PCS_STATUS]		= QPHY_V3_PCS_PCS_STATUS, -	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL, -	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR, -	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V3_PCS_POWER_DOWN_CONTROL, -}; -  static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {  	[QPHY_SW_RESET]			= QPHY_V4_PCS_SW_RESET,  	[QPHY_START_CTRL]		= QPHY_V4_PCS_START_CONTROL, @@ -514,115 +448,6 @@ static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {  	QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60),  }; -static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = { -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85), -	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07), -}; - -static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = { -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10), -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12), -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16), -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00), -}; - -static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = { -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05), -}; - -static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = { -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13), -}; -  static const struct qmp_phy_init_tbl sm8150_usb3_uniphy_serdes_tbl[] = {  	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),  	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), @@ -1089,99 +914,6 @@ static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_usb_tbl[] = {  	QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),  }; -static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = { -	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14), -	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), -	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), -	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06), -	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08), -	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f), -	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82), -	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55), -	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55), -	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03), -	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), -	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), -	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), -	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80), -	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a), -	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15), -	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34), -	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a), -	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31), -	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01), -	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde), -	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07), -	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), -	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06), -	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80), -	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01), -}; - -static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = { -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10), -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12), -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6), -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00), -}; - -static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = { -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00), -	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00), -}; - -static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = { -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00), -	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88), -}; -  static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_serdes_tbl[] = {  	QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x1a),  	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), @@ -1448,15 +1180,10 @@ struct qmp_usb_offsets {  	u16 pcs_usb;  	u16 tx;  	u16 rx; -	/* for PHYs with >= 2 lanes */ -	u16 tx2; -	u16 rx2;  };  /* struct qmp_phy_cfg - per-PHY initialization config */  struct qmp_phy_cfg { -	int lanes; -  	const struct qmp_usb_offsets *offsets;  	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */ @@ -1496,8 +1223,6 @@ struct qmp_usb {  	void __iomem *pcs_usb;  	void __iomem *tx;  	void __iomem *rx; -	void __iomem *tx2; -	void __iomem *rx2;  	struct clk *pipe_clk;  	struct clk_bulk_data *clks; @@ -1579,16 +1304,6 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v3_msm8996 = {  	.rx		= 0x400,  }; -static const struct qmp_usb_offsets qmp_usb_offsets_v3_qcm2290 = { -	.serdes		= 0x0, -	.pcs		= 0xc00, -	.pcs_misc	= 0xa00, -	.tx		= 0x200, -	.rx		= 0x400, -	.tx2		= 0x600, -	.rx2		= 0x800, -}; -  static const struct qmp_usb_offsets qmp_usb_offsets_v4 = {  	.serdes		= 0,  	.pcs		= 0x0800, @@ -1622,8 +1337,6 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v7 = {  };  static const struct qmp_phy_cfg ipq6018_usb3phy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v3,  	.serdes_tbl		= ipq9574_usb3_serdes_tbl, @@ -1640,8 +1353,6 @@ static const struct qmp_phy_cfg ipq6018_usb3phy_cfg = {  };  static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v3,  	.serdes_tbl		= ipq8074_usb3_serdes_tbl, @@ -1658,8 +1369,6 @@ static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {  };  static const struct qmp_phy_cfg ipq9574_usb3phy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_ipq9574,  	.serdes_tbl		= ipq9574_usb3_serdes_tbl, @@ -1676,8 +1385,6 @@ static const struct qmp_phy_cfg ipq9574_usb3phy_cfg = {  };  static const struct qmp_phy_cfg msm8996_usb3phy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v3_msm8996,  	.serdes_tbl		= msm8996_usb3_serdes_tbl, @@ -1694,8 +1401,6 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {  };  static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v5,  	.serdes_tbl		= sc8280xp_usb3_uniphy_serdes_tbl, @@ -1714,8 +1419,6 @@ static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = {  };  static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v5,  	.serdes_tbl		= sc8280xp_usb3_uniphy_serdes_tbl, @@ -1734,8 +1437,6 @@ static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = {  };  static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v3,  	.serdes_tbl		= qmp_v3_usb3_uniphy_serdes_tbl, @@ -1753,27 +1454,7 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {  	.has_pwrdn_delay	= true,  }; -static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { -	.lanes			= 2, - -	.offsets		= &qmp_usb_offsets_v3_qcm2290, - -	.serdes_tbl             = msm8998_usb3_serdes_tbl, -	.serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl), -	.tx_tbl                 = msm8998_usb3_tx_tbl, -	.tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl), -	.rx_tbl                 = msm8998_usb3_rx_tbl, -	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl), -	.pcs_tbl                = msm8998_usb3_pcs_tbl, -	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl), -	.vreg_list              = qmp_phy_vreg_l, -	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l), -	.regs                   = qmp_v3_usb3phy_regs_layout, -}; -  static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v4,  	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl, @@ -1795,8 +1476,6 @@ static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {  };  static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v4,  	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl, @@ -1818,8 +1497,6 @@ static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {  };  static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v4,  	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl, @@ -1841,8 +1518,6 @@ static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {  };  static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v5,  	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl, @@ -1864,7 +1539,6 @@ static const struct qmp_phy_cfg sdx65_usb3_uniphy_cfg = {  };  static const struct qmp_phy_cfg sdx75_usb3_uniphy_cfg = { -	.lanes			= 1,  	.offsets		= &qmp_usb_offsets_v6,  	.serdes_tbl		= sdx75_usb3_uniphy_serdes_tbl, @@ -1886,8 +1560,6 @@ static const struct qmp_phy_cfg sdx75_usb3_uniphy_cfg = {  };  static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v5,  	.serdes_tbl		= sm8150_usb3_uniphy_serdes_tbl, @@ -1908,27 +1580,7 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {  	.has_pwrdn_delay	= true,  }; -static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = { -	.lanes			= 2, - -	.offsets		= &qmp_usb_offsets_v3_qcm2290, - -	.serdes_tbl		= qcm2290_usb3_serdes_tbl, -	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl), -	.tx_tbl			= qcm2290_usb3_tx_tbl, -	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl), -	.rx_tbl			= qcm2290_usb3_rx_tbl, -	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl), -	.pcs_tbl		= qcm2290_usb3_pcs_tbl, -	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl), -	.vreg_list		= qmp_phy_vreg_l, -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l), -	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290, -}; -  static const struct qmp_phy_cfg x1e80100_usb3_uniphy_cfg = { -	.lanes			= 1, -  	.offsets		= &qmp_usb_offsets_v7,  	.serdes_tbl		= x1e80100_usb3_uniphy_serdes_tbl, @@ -1946,32 +1598,6 @@ static const struct qmp_phy_cfg x1e80100_usb3_uniphy_cfg = {  	.regs			= qmp_v7_usb3phy_regs_layout,  }; -static void qmp_usb_configure_lane(void __iomem *base, -					const struct qmp_phy_init_tbl tbl[], -					int num, -					u8 lane_mask) -{ -	int i; -	const struct qmp_phy_init_tbl *t = tbl; - -	if (!t) -		return; - -	for (i = 0; i < num; i++, t++) { -		if (!(t->lane_mask & lane_mask)) -			continue; - -		writel(t->val, base + t->offset); -	} -} - -static void qmp_usb_configure(void __iomem *base, -				   const struct qmp_phy_init_tbl tbl[], -				   int num) -{ -	qmp_usb_configure_lane(base, tbl, num, 0xff); -} -  static int qmp_usb_serdes_init(struct qmp_usb *qmp)  {  	const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -1979,7 +1605,7 @@ static int qmp_usb_serdes_init(struct qmp_usb *qmp)  	const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;  	int serdes_tbl_num = cfg->serdes_tbl_num; -	qmp_usb_configure(serdes, serdes_tbl, serdes_tbl_num); +	qmp_configure(serdes, serdes_tbl, serdes_tbl_num);  	return 0;  } @@ -2060,18 +1686,13 @@ static int qmp_usb_power_on(struct phy *phy)  	}  	/* Tx, Rx, and PCS configurations */ -	qmp_usb_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); -	qmp_usb_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); - -	if (cfg->lanes >= 2) { -		qmp_usb_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); -		qmp_usb_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); -	} +	qmp_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); +	qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); -	qmp_usb_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); +	qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);  	if (pcs_usb) -		qmp_usb_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num); +		qmp_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);  	if (cfg->has_pwrdn_delay)  		usleep_range(10, 20); @@ -2414,7 +2035,6 @@ static int qmp_usb_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np)  	/*  	 * Get memory resources for the PHY:  	 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. -	 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5  	 * For single lane PHYs: pcs_misc (optional) -> 3.  	 */  	qmp->tx = devm_of_iomap(dev, np, 0, NULL); @@ -2432,19 +2052,7 @@ static int qmp_usb_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np)  	if (cfg->pcs_usb_offset)  		qmp->pcs_usb = qmp->pcs + cfg->pcs_usb_offset; -	if (cfg->lanes >= 2) { -		qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); -		if (IS_ERR(qmp->tx2)) -			return PTR_ERR(qmp->tx2); - -		qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); -		if (IS_ERR(qmp->rx2)) -			return PTR_ERR(qmp->rx2); - -		qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); -	} else { -		qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL); -	} +	qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);  	if (IS_ERR(qmp->pcs_misc)) {  		dev_vdbg(dev, "PHY pcs_misc-reg not used\n"); @@ -2496,11 +2104,6 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp)  	qmp->tx = base + offs->tx;  	qmp->rx = base + offs->rx; -	if (cfg->lanes >= 2) { -		qmp->tx2 = base + offs->tx2; -		qmp->rx2 = base + offs->rx2; -	} -  	ret = qmp_usb_clk_init(qmp);  	if (ret)  		return ret; @@ -2600,12 +2203,6 @@ static const struct of_device_id qmp_usb_of_match_table[] = {  		.compatible = "qcom,msm8996-qmp-usb3-phy",  		.data = &msm8996_usb3phy_cfg,  	}, { -		.compatible = "qcom,msm8998-qmp-usb3-phy", -		.data = &msm8998_usb3phy_cfg, -	}, { -		.compatible = "qcom,qcm2290-qmp-usb3-phy", -		.data = &qcm2290_usb3phy_cfg, -	}, {  		.compatible = "qcom,sa8775p-qmp-usb3-uni-phy",  		.data = &sa8775p_usb3_uniphy_cfg,  	}, { @@ -2624,9 +2221,6 @@ static const struct of_device_id qmp_usb_of_match_table[] = {  		.compatible = "qcom,sdx75-qmp-usb3-uni-phy",  		.data = &sdx75_usb3_uniphy_cfg,  	}, { -		.compatible = "qcom,sm6115-qmp-usb3-phy", -		.data = &qcm2290_usb3phy_cfg, -	}, {  		.compatible = "qcom,sm8150-qmp-usb3-uni-phy",  		.data = &sm8150_usb3_uniphy_cfg,  	}, { diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c new file mode 100644 index 000000000000..5cbc5fd529eb --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -0,0 +1,1149 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/reset.h> +#include <linux/slab.h> +#include <linux/usb/typec.h> +#include <linux/usb/typec_mux.h> + +#include "phy-qcom-qmp-common.h" + +#include "phy-qcom-qmp.h" +#include "phy-qcom-qmp-pcs-misc-v3.h" + +#define PHY_INIT_COMPLETE_TIMEOUT		10000 + +/* set of registers with offsets different per-PHY */ +enum qphy_reg_layout { +	/* PCS registers */ +	QPHY_SW_RESET, +	QPHY_START_CTRL, +	QPHY_PCS_STATUS, +	QPHY_PCS_AUTONOMOUS_MODE_CTRL, +	QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR, +	QPHY_PCS_POWER_DOWN_CONTROL, +	/* Keep last to ensure regs_layout arrays are properly initialized */ +	QPHY_LAYOUT_SIZE +}; + +static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { +	[QPHY_SW_RESET]			= QPHY_V3_PCS_SW_RESET, +	[QPHY_START_CTRL]		= QPHY_V3_PCS_START_CONTROL, +	[QPHY_PCS_STATUS]		= QPHY_V3_PCS_PCS_STATUS, +	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL, +	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR, +	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V3_PCS_POWER_DOWN_CONTROL, +}; + +static const unsigned int qmp_v3_usb3phy_regs_layout_qcm2290[QPHY_LAYOUT_SIZE] = { +	[QPHY_SW_RESET]			= QPHY_V3_PCS_SW_RESET, +	[QPHY_START_CTRL]		= QPHY_V3_PCS_START_CONTROL, +	[QPHY_PCS_STATUS]		= QPHY_V3_PCS_PCS_STATUS, +	[QPHY_PCS_AUTONOMOUS_MODE_CTRL]	= QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL, +	[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR, +	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V3_PCS_POWER_DOWN_CONTROL, +}; + +static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85), +	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07), +}; + +static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10), +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12), +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16), +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00), +}; + +static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05), +}; + +static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = { +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13), +}; + +static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14), +	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), +	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), +	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08), +	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f), +	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82), +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55), +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55), +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03), +	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), +	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15), +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34), +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31), +	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01), +	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde), +	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07), +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), +	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01), +}; + +static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10), +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12), +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6), +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00), +}; + +static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00), +}; + +/* the only difference is QSERDES_V3_RX_UCDR_PI_CONTROLS */ +static const struct qmp_phy_init_tbl sdm660_usb3_rx_tbl[] = { +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00), +	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00), +}; + +static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = { +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00), +	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88), +}; + +struct qmp_usbc_offsets { +	u16 serdes; +	u16 pcs; +	u16 pcs_misc; +	u16 tx; +	u16 rx; +	/* for PHYs with >= 2 lanes */ +	u16 tx2; +	u16 rx2; +}; + +/* struct qmp_phy_cfg - per-PHY initialization config */ +struct qmp_phy_cfg { +	const struct qmp_usbc_offsets *offsets; + +	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */ +	const struct qmp_phy_init_tbl *serdes_tbl; +	int serdes_tbl_num; +	const struct qmp_phy_init_tbl *tx_tbl; +	int tx_tbl_num; +	const struct qmp_phy_init_tbl *rx_tbl; +	int rx_tbl_num; +	const struct qmp_phy_init_tbl *pcs_tbl; +	int pcs_tbl_num; + +	/* regulators to be requested */ +	const char * const *vreg_list; +	int num_vregs; + +	/* array of registers with different offsets */ +	const unsigned int *regs; +}; + +struct qmp_usbc { +	struct device *dev; + +	const struct qmp_phy_cfg *cfg; + +	void __iomem *serdes; +	void __iomem *pcs; +	void __iomem *pcs_misc; +	void __iomem *tx; +	void __iomem *rx; +	void __iomem *tx2; +	void __iomem *rx2; + +	struct regmap *tcsr_map; +	u32 vls_clamp_reg; + +	struct clk *pipe_clk; +	struct clk_bulk_data *clks; +	int num_clks; +	int num_resets; +	struct reset_control_bulk_data *resets; +	struct regulator_bulk_data *vregs; + +	struct mutex phy_mutex; + +	enum phy_mode mode; +	unsigned int usb_init_count; + +	struct phy *phy; + +	struct clk_fixed_rate pipe_clk_fixed; + +	struct typec_switch_dev *sw; +	enum typec_orientation orientation; +}; + +static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) +{ +	u32 reg; + +	reg = readl(base + offset); +	reg |= val; +	writel(reg, base + offset); + +	/* ensure that above write is through */ +	readl(base + offset); +} + +static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val) +{ +	u32 reg; + +	reg = readl(base + offset); +	reg &= ~val; +	writel(reg, base + offset); + +	/* ensure that above write is through */ +	readl(base + offset); +} + +/* list of clocks required by phy */ +static const char * const qmp_usbc_phy_clk_l[] = { +	"aux", "cfg_ahb", "ref", "com_aux", +}; + +/* list of resets */ +static const char * const usb3phy_legacy_reset_l[] = { +	"phy", "common", +}; + +static const char * const usb3phy_reset_l[] = { +	"phy_phy", "phy", +}; + +/* list of regulators */ +static const char * const qmp_phy_vreg_l[] = { +	"vdda-phy", "vdda-pll", +}; + +static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = { +	.serdes		= 0x0, +	.pcs		= 0xc00, +	.pcs_misc	= 0xa00, +	.tx		= 0x200, +	.rx		= 0x400, +	.tx2		= 0x600, +	.rx2		= 0x800, +}; + +static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { +	.offsets		= &qmp_usbc_offsets_v3_qcm2290, + +	.serdes_tbl             = msm8998_usb3_serdes_tbl, +	.serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl), +	.tx_tbl                 = msm8998_usb3_tx_tbl, +	.tx_tbl_num             = ARRAY_SIZE(msm8998_usb3_tx_tbl), +	.rx_tbl                 = msm8998_usb3_rx_tbl, +	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl), +	.pcs_tbl                = msm8998_usb3_pcs_tbl, +	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl), +	.vreg_list              = qmp_phy_vreg_l, +	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l), +	.regs                   = qmp_v3_usb3phy_regs_layout, +}; + +static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = { +	.offsets		= &qmp_usbc_offsets_v3_qcm2290, + +	.serdes_tbl		= qcm2290_usb3_serdes_tbl, +	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl), +	.tx_tbl			= qcm2290_usb3_tx_tbl, +	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl), +	.rx_tbl			= qcm2290_usb3_rx_tbl, +	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl), +	.pcs_tbl		= qcm2290_usb3_pcs_tbl, +	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl), +	.vreg_list		= qmp_phy_vreg_l, +	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l), +	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290, +}; + +static const struct qmp_phy_cfg sdm660_usb3phy_cfg = { +	.offsets		= &qmp_usbc_offsets_v3_qcm2290, + +	.serdes_tbl		= qcm2290_usb3_serdes_tbl, +	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl), +	.tx_tbl			= qcm2290_usb3_tx_tbl, +	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl), +	.rx_tbl			= sdm660_usb3_rx_tbl, +	.rx_tbl_num		= ARRAY_SIZE(sdm660_usb3_rx_tbl), +	.pcs_tbl		= qcm2290_usb3_pcs_tbl, +	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl), +	.vreg_list		= qmp_phy_vreg_l, +	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l), +	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290, +}; + +static int qmp_usbc_init(struct phy *phy) +{ +	struct qmp_usbc *qmp = phy_get_drvdata(phy); +	const struct qmp_phy_cfg *cfg = qmp->cfg; +	void __iomem *pcs = qmp->pcs; +	u32 val = 0; +	int ret; + +	ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); +	if (ret) { +		dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); +		return ret; +	} + +	ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets); +	if (ret) { +		dev_err(qmp->dev, "reset assert failed\n"); +		goto err_disable_regulators; +	} + +	ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets); +	if (ret) { +		dev_err(qmp->dev, "reset deassert failed\n"); +		goto err_disable_regulators; +	} + +	ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); +	if (ret) +		goto err_assert_reset; + +	qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); + +#define SW_PORTSELECT_VAL			BIT(0) +#define SW_PORTSELECT_MUX			BIT(1) +	/* Use software based port select and switch on typec orientation */ +	val = SW_PORTSELECT_MUX; +	if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) +		val |= SW_PORTSELECT_VAL; +	writel(val, qmp->pcs_misc); + +	return 0; + +err_assert_reset: +	reset_control_bulk_assert(qmp->num_resets, qmp->resets); +err_disable_regulators: +	regulator_bulk_disable(cfg->num_vregs, qmp->vregs); + +	return ret; +} + +static int qmp_usbc_exit(struct phy *phy) +{ +	struct qmp_usbc *qmp = phy_get_drvdata(phy); +	const struct qmp_phy_cfg *cfg = qmp->cfg; + +	reset_control_bulk_assert(qmp->num_resets, qmp->resets); + +	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); + +	regulator_bulk_disable(cfg->num_vregs, qmp->vregs); + +	return 0; +} + +static int qmp_usbc_power_on(struct phy *phy) +{ +	struct qmp_usbc *qmp = phy_get_drvdata(phy); +	const struct qmp_phy_cfg *cfg = qmp->cfg; +	void __iomem *status; +	unsigned int val; +	int ret; + +	qmp_configure(qmp->serdes, cfg->serdes_tbl, cfg->serdes_tbl_num); + +	ret = clk_prepare_enable(qmp->pipe_clk); +	if (ret) { +		dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret); +		return ret; +	} + +	/* Tx, Rx, and PCS configurations */ +	qmp_configure_lane(qmp->tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); +	qmp_configure_lane(qmp->rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); + +	qmp_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); +	qmp_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); + +	qmp_configure(qmp->pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); + +	/* Pull PHY out of reset state */ +	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); + +	/* start SerDes and Phy-Coding-Sublayer */ +	qphy_setbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START); + +	status = qmp->pcs + cfg->regs[QPHY_PCS_STATUS]; +	ret = readl_poll_timeout(status, val, !(val & PHYSTATUS), 200, +				 PHY_INIT_COMPLETE_TIMEOUT); +	if (ret) { +		dev_err(qmp->dev, "phy initialization timed-out\n"); +		goto err_disable_pipe_clk; +	} + +	return 0; + +err_disable_pipe_clk: +	clk_disable_unprepare(qmp->pipe_clk); + +	return ret; +} + +static int qmp_usbc_power_off(struct phy *phy) +{ +	struct qmp_usbc *qmp = phy_get_drvdata(phy); +	const struct qmp_phy_cfg *cfg = qmp->cfg; + +	clk_disable_unprepare(qmp->pipe_clk); + +	/* PHY reset */ +	qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); + +	/* stop SerDes and Phy-Coding-Sublayer */ +	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], +			SERDES_START | PCS_START); + +	/* Put PHY into POWER DOWN state: active low */ +	qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], +			SW_PWRDN); + +	return 0; +} + +static int qmp_usbc_enable(struct phy *phy) +{ +	struct qmp_usbc *qmp = phy_get_drvdata(phy); +	int ret; + +	mutex_lock(&qmp->phy_mutex); + +	ret = qmp_usbc_init(phy); +	if (ret) +		goto out_unlock; + +	ret = qmp_usbc_power_on(phy); +	if (ret) { +		qmp_usbc_exit(phy); +		goto out_unlock; +	} + +	qmp->usb_init_count++; +out_unlock: +	mutex_unlock(&qmp->phy_mutex); + +	return ret; +} + +static int qmp_usbc_disable(struct phy *phy) +{ +	struct qmp_usbc *qmp = phy_get_drvdata(phy); +	int ret; + +	qmp->usb_init_count--; +	ret = qmp_usbc_power_off(phy); +	if (ret) +		return ret; +	return qmp_usbc_exit(phy); +} + +static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode) +{ +	struct qmp_usbc *qmp = phy_get_drvdata(phy); + +	qmp->mode = mode; + +	return 0; +} + +static const struct phy_ops qmp_usbc_phy_ops = { +	.init		= qmp_usbc_enable, +	.exit		= qmp_usbc_disable, +	.set_mode	= qmp_usbc_set_mode, +	.owner		= THIS_MODULE, +}; + +static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp) +{ +	const struct qmp_phy_cfg *cfg = qmp->cfg; +	void __iomem *pcs = qmp->pcs; +	u32 intr_mask; + +	if (qmp->mode == PHY_MODE_USB_HOST_SS || +	    qmp->mode == PHY_MODE_USB_DEVICE_SS) +		intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN; +	else +		intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL; + +	/* Clear any pending interrupts status */ +	qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR); +	/* Writing 1 followed by 0 clears the interrupt */ +	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR); + +	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], +		     ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL); + +	/* Enable required PHY autonomous mode interrupts */ +	qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask); + +	/* Enable i/o clamp_n for autonomous mode */ +	if (qmp->tcsr_map && qmp->vls_clamp_reg) +		regmap_write(qmp->tcsr_map, qmp->vls_clamp_reg, 1); +} + +static void qmp_usbc_disable_autonomous_mode(struct qmp_usbc *qmp) +{ +	const struct qmp_phy_cfg *cfg = qmp->cfg; +	void __iomem *pcs = qmp->pcs; + +	/* Disable i/o clamp_n on resume for normal mode */ +	if (qmp->tcsr_map && qmp->vls_clamp_reg) +		regmap_write(qmp->tcsr_map, qmp->vls_clamp_reg, 0); + +	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], +		     ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN); + +	qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR); +	/* Writing 1 followed by 0 clears the interrupt */ +	qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR); +} + +static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev) +{ +	struct qmp_usbc *qmp = dev_get_drvdata(dev); + +	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); + +	if (!qmp->phy->init_count) { +		dev_vdbg(dev, "PHY not initialized, bailing out\n"); +		return 0; +	} + +	qmp_usbc_enable_autonomous_mode(qmp); + +	clk_disable_unprepare(qmp->pipe_clk); +	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); + +	return 0; +} + +static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev) +{ +	struct qmp_usbc *qmp = dev_get_drvdata(dev); +	int ret = 0; + +	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); + +	if (!qmp->phy->init_count) { +		dev_vdbg(dev, "PHY not initialized, bailing out\n"); +		return 0; +	} + +	ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); +	if (ret) +		return ret; + +	ret = clk_prepare_enable(qmp->pipe_clk); +	if (ret) { +		dev_err(dev, "pipe_clk enable failed, err=%d\n", ret); +		clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); +		return ret; +	} + +	qmp_usbc_disable_autonomous_mode(qmp); + +	return 0; +} + +static const struct dev_pm_ops qmp_usbc_pm_ops = { +	SET_RUNTIME_PM_OPS(qmp_usbc_runtime_suspend, +			   qmp_usbc_runtime_resume, NULL) +}; + +static int qmp_usbc_vreg_init(struct qmp_usbc *qmp) +{ +	const struct qmp_phy_cfg *cfg = qmp->cfg; +	struct device *dev = qmp->dev; +	int num = cfg->num_vregs; +	int i; + +	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); +	if (!qmp->vregs) +		return -ENOMEM; + +	for (i = 0; i < num; i++) +		qmp->vregs[i].supply = cfg->vreg_list[i]; + +	return devm_regulator_bulk_get(dev, num, qmp->vregs); +} + +static int qmp_usbc_reset_init(struct qmp_usbc *qmp, +			      const char *const *reset_list, +			      int num_resets) +{ +	struct device *dev = qmp->dev; +	int i; +	int ret; + +	qmp->resets = devm_kcalloc(dev, num_resets, +				   sizeof(*qmp->resets), GFP_KERNEL); +	if (!qmp->resets) +		return -ENOMEM; + +	for (i = 0; i < num_resets; i++) +		qmp->resets[i].id = reset_list[i]; + +	qmp->num_resets = num_resets; + +	ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets); +	if (ret) +		return dev_err_probe(dev, ret, "failed to get resets\n"); + +	return 0; +} + +static int qmp_usbc_clk_init(struct qmp_usbc *qmp) +{ +	struct device *dev = qmp->dev; +	int num = ARRAY_SIZE(qmp_usbc_phy_clk_l); +	int i; + +	qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); +	if (!qmp->clks) +		return -ENOMEM; + +	for (i = 0; i < num; i++) +		qmp->clks[i].id = qmp_usbc_phy_clk_l[i]; + +	qmp->num_clks = num; + +	return devm_clk_bulk_get_optional(dev, num, qmp->clks); +} + +static void phy_clk_release_provider(void *res) +{ +	of_clk_del_provider(res); +} + +/* + * Register a fixed rate pipe clock. + * + * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate + * controls it. The <s>_pipe_clk coming out of the GCC is requested + * by the PHY driver for its operations. + * We register the <s>_pipe_clksrc here. The gcc driver takes care + * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk. + * Below picture shows this relationship. + * + *         +---------------+ + *         |   PHY block   |<<---------------------------------------+ + *         |               |                                         | + *         |   +-------+   |                   +-----+               | + *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+ + *    clk  |   +-------+   |                   +-----+ + *         +---------------+ + */ +static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np) +{ +	struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; +	struct clk_init_data init = { }; +	int ret; + +	ret = of_property_read_string(np, "clock-output-names", &init.name); +	if (ret) { +		dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np); +		return ret; +	} + +	init.ops = &clk_fixed_rate_ops; + +	/* controllers using QMP phys use 125MHz pipe clock interface */ +	fixed->fixed_rate = 125000000; +	fixed->hw.init = &init; + +	ret = devm_clk_hw_register(qmp->dev, &fixed->hw); +	if (ret) +		return ret; + +	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw); +	if (ret) +		return ret; + +	/* +	 * Roll a devm action because the clock provider is the child node, but +	 * the child node is not actually a device. +	 */ +	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np); +} + +#if IS_ENABLED(CONFIG_TYPEC) +static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw, +				      enum typec_orientation orientation) +{ +	struct qmp_usbc *qmp = typec_switch_get_drvdata(sw); + +	if (orientation == qmp->orientation || orientation == TYPEC_ORIENTATION_NONE) +		return 0; + +	mutex_lock(&qmp->phy_mutex); +	qmp->orientation = orientation; + +	if (qmp->usb_init_count) { +		qmp_usbc_power_off(qmp->phy); +		qmp_usbc_exit(qmp->phy); + +		qmp_usbc_init(qmp->phy); +		qmp_usbc_power_on(qmp->phy); +	} + +	mutex_unlock(&qmp->phy_mutex); + +	return 0; +} + +static void qmp_usbc_typec_unregister(void *data) +{ +	struct qmp_usbc *qmp = data; + +	typec_switch_unregister(qmp->sw); +} + +static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp) +{ +	struct typec_switch_desc sw_desc = {}; +	struct device *dev = qmp->dev; + +	sw_desc.drvdata = qmp; +	sw_desc.fwnode = dev->fwnode; +	sw_desc.set = qmp_usbc_typec_switch_set; +	qmp->sw = typec_switch_register(dev, &sw_desc); +	if (IS_ERR(qmp->sw)) { +		dev_err(dev, "Unable to register typec switch: %pe\n", qmp->sw); +		return PTR_ERR(qmp->sw); +	} + +	return devm_add_action_or_reset(dev, qmp_usbc_typec_unregister, qmp); +} +#else +static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp) +{ +	return 0; +} +#endif + +static int qmp_usbc_parse_dt_legacy(struct qmp_usbc *qmp, struct device_node *np) +{ +	struct platform_device *pdev = to_platform_device(qmp->dev); +	struct device *dev = qmp->dev; +	int ret; + +	qmp->serdes = devm_platform_ioremap_resource(pdev, 0); +	if (IS_ERR(qmp->serdes)) +		return PTR_ERR(qmp->serdes); + +	/* +	 * Get memory resources for the PHY: +	 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. +	 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5 +	 * For single lane PHYs: pcs_misc (optional) -> 3. +	 */ +	qmp->tx = devm_of_iomap(dev, np, 0, NULL); +	if (IS_ERR(qmp->tx)) +		return PTR_ERR(qmp->tx); + +	qmp->rx = devm_of_iomap(dev, np, 1, NULL); +	if (IS_ERR(qmp->rx)) +		return PTR_ERR(qmp->rx); + +	qmp->pcs = devm_of_iomap(dev, np, 2, NULL); +	if (IS_ERR(qmp->pcs)) +		return PTR_ERR(qmp->pcs); + +	qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); +	if (IS_ERR(qmp->tx2)) +		return PTR_ERR(qmp->tx2); + +	qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); +	if (IS_ERR(qmp->rx2)) +		return PTR_ERR(qmp->rx2); + +	qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); +	if (IS_ERR(qmp->pcs_misc)) { +		dev_vdbg(dev, "PHY pcs_misc-reg not used\n"); +		qmp->pcs_misc = NULL; +	} + +	qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL); +	if (IS_ERR(qmp->pipe_clk)) { +		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), +				     "failed to get pipe clock\n"); +	} + +	ret = devm_clk_bulk_get_all(qmp->dev, &qmp->clks); +	if (ret < 0) +		return ret; + +	qmp->num_clks = ret; + +	ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l, +				 ARRAY_SIZE(usb3phy_legacy_reset_l)); +	if (ret) +		return ret; + +	return 0; +} + +static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) +{ +	struct platform_device *pdev = to_platform_device(qmp->dev); +	const struct qmp_phy_cfg *cfg = qmp->cfg; +	const struct qmp_usbc_offsets *offs = cfg->offsets; +	struct device *dev = qmp->dev; +	void __iomem *base; +	int ret; + +	if (!offs) +		return -EINVAL; + +	base = devm_platform_ioremap_resource(pdev, 0); +	if (IS_ERR(base)) +		return PTR_ERR(base); + +	qmp->serdes = base + offs->serdes; +	qmp->pcs = base + offs->pcs; +	if (offs->pcs_misc) +		qmp->pcs_misc = base + offs->pcs_misc; +	qmp->tx = base + offs->tx; +	qmp->rx = base + offs->rx; + +	qmp->tx2 = base + offs->tx2; +	qmp->rx2 = base + offs->rx2; + +	ret = qmp_usbc_clk_init(qmp); +	if (ret) +		return ret; + +	qmp->pipe_clk = devm_clk_get(dev, "pipe"); +	if (IS_ERR(qmp->pipe_clk)) { +		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), +				     "failed to get pipe clock\n"); +	} + +	ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l, +				 ARRAY_SIZE(usb3phy_reset_l)); +	if (ret) +		return ret; + +	return 0; +} + +static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp) +{ +	struct of_phandle_args tcsr_args; +	struct device *dev = qmp->dev; +	int ret; + +	/*  for backwards compatibility ignore if there is no property */ +	ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0, +					       &tcsr_args); +	if (ret == -ENOENT) +		return 0; +	else if (ret < 0) +		return dev_err_probe(dev, ret, "Failed to parse qcom,tcsr-reg\n"); + +	qmp->tcsr_map = syscon_node_to_regmap(tcsr_args.np); +	of_node_put(tcsr_args.np); +	if (IS_ERR(qmp->tcsr_map)) +		return PTR_ERR(qmp->tcsr_map); + +	qmp->vls_clamp_reg = tcsr_args.args[0]; + +	return 0; +} + +static int qmp_usbc_probe(struct platform_device *pdev) +{ +	struct device *dev = &pdev->dev; +	struct phy_provider *phy_provider; +	struct device_node *np; +	struct qmp_usbc *qmp; +	int ret; + +	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL); +	if (!qmp) +		return -ENOMEM; + +	qmp->dev = dev; + +	qmp->orientation = TYPEC_ORIENTATION_NORMAL; + +	qmp->cfg = of_device_get_match_data(dev); +	if (!qmp->cfg) +		return -EINVAL; + +	mutex_init(&qmp->phy_mutex); + +	ret = qmp_usbc_vreg_init(qmp); +	if (ret) +		return ret; + +	ret = qmp_usbc_typec_switch_register(qmp); +	if (ret) +		return ret; + +	ret = qmp_usbc_parse_vls_clamp(qmp); +	if (ret) +		return ret; + +	/* Check for legacy binding with child node. */ +	np = of_get_child_by_name(dev->of_node, "phy"); +	if (np) { +		ret = qmp_usbc_parse_dt_legacy(qmp, np); +	} else { +		np = of_node_get(dev->of_node); +		ret = qmp_usbc_parse_dt(qmp); +	} +	if (ret) +		goto err_node_put; + +	pm_runtime_set_active(dev); +	ret = devm_pm_runtime_enable(dev); +	if (ret) +		goto err_node_put; +	/* +	 * Prevent runtime pm from being ON by default. Users can enable +	 * it using power/control in sysfs. +	 */ +	pm_runtime_forbid(dev); + +	ret = phy_pipe_clk_register(qmp, np); +	if (ret) +		goto err_node_put; + +	qmp->phy = devm_phy_create(dev, np, &qmp_usbc_phy_ops); +	if (IS_ERR(qmp->phy)) { +		ret = PTR_ERR(qmp->phy); +		dev_err(dev, "failed to create PHY: %d\n", ret); +		goto err_node_put; +	} + +	phy_set_drvdata(qmp->phy, qmp); + +	of_node_put(np); + +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + +	return PTR_ERR_OR_ZERO(phy_provider); + +err_node_put: +	of_node_put(np); +	return ret; +} + +static const struct of_device_id qmp_usbc_of_match_table[] = { +	{ +		.compatible = "qcom,msm8998-qmp-usb3-phy", +		.data = &msm8998_usb3phy_cfg, +	}, { +		.compatible = "qcom,qcm2290-qmp-usb3-phy", +		.data = &qcm2290_usb3phy_cfg, +	}, { +		.compatible = "qcom,sdm660-qmp-usb3-phy", +		.data = &sdm660_usb3phy_cfg, +	}, { +		.compatible = "qcom,sm6115-qmp-usb3-phy", +		.data = &qcm2290_usb3phy_cfg, +	}, +	{ }, +}; +MODULE_DEVICE_TABLE(of, qmp_usbc_of_match_table); + +static struct platform_driver qmp_usbc_driver = { +	.probe		= qmp_usbc_probe, +	.driver = { +		.name	= "qcom-qmp-usbc-phy", +		.pm	= &qmp_usbc_pm_ops, +		.of_match_table = qmp_usbc_of_match_table, +	}, +}; + +module_platform_driver(qmp_usbc_driver); + +MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>"); +MODULE_DESCRIPTION("Qualcomm QMP USB-C PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index 6923496cbfee..d10b8f653c4b 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -50,92 +50,29 @@  #include "phy-qcom-qmp-pcs-v7.h" -/* Only for QMP V3 & V4 PHY - DP COM registers */ -#define QPHY_V3_DP_COM_PHY_MODE_CTRL			0x00 -#define QPHY_V3_DP_COM_SW_RESET				0x04 -#define QPHY_V3_DP_COM_POWER_DOWN_CTRL			0x08 -#define QPHY_V3_DP_COM_SWI_CTRL				0x0c -#define QPHY_V3_DP_COM_TYPEC_CTRL			0x10 -#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL			0x14 -#define QPHY_V3_DP_COM_RESET_OVRD_CTRL			0x1c - -/* QSERDES V3 COM bits */ -# define QSERDES_V3_COM_BIAS_EN				0x0001 -# define QSERDES_V3_COM_BIAS_EN_MUX			0x0002 -# define QSERDES_V3_COM_CLKBUF_R_EN			0x0004 -# define QSERDES_V3_COM_CLKBUF_L_EN			0x0008 -# define QSERDES_V3_COM_EN_SYSCLK_TX_SEL		0x0010 -# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_L		0x0020 -# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_R		0x0040 - -/* QSERDES V3 TX bits */ -# define DP_PHY_TXn_TX_EMP_POST1_LVL_MASK		0x001f -# define DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN		0x0020 -# define DP_PHY_TXn_TX_DRV_LVL_MASK			0x001f -# define DP_PHY_TXn_TX_DRV_LVL_MUX_EN			0x0020 - -/* QMP PHY - DP PHY registers */ -#define QSERDES_DP_PHY_REVISION_ID0			0x000 -#define QSERDES_DP_PHY_REVISION_ID1			0x004 -#define QSERDES_DP_PHY_REVISION_ID2			0x008 -#define QSERDES_DP_PHY_REVISION_ID3			0x00c -#define QSERDES_DP_PHY_CFG				0x010 -#define QSERDES_DP_PHY_PD_CTL				0x018 -# define DP_PHY_PD_CTL_PWRDN				0x001 -# define DP_PHY_PD_CTL_PSR_PWRDN			0x002 -# define DP_PHY_PD_CTL_AUX_PWRDN			0x004 -# define DP_PHY_PD_CTL_LANE_0_1_PWRDN			0x008 -# define DP_PHY_PD_CTL_LANE_2_3_PWRDN			0x010 -# define DP_PHY_PD_CTL_PLL_PWRDN			0x020 -# define DP_PHY_PD_CTL_DP_CLAMP_EN			0x040 -#define QSERDES_DP_PHY_MODE				0x01c -#define QSERDES_DP_PHY_AUX_CFG0				0x020 -#define QSERDES_DP_PHY_AUX_CFG1				0x024 -#define QSERDES_DP_PHY_AUX_CFG2				0x028 -#define QSERDES_DP_PHY_AUX_CFG3				0x02c -#define QSERDES_DP_PHY_AUX_CFG4				0x030 -#define QSERDES_DP_PHY_AUX_CFG5				0x034 -#define QSERDES_DP_PHY_AUX_CFG6				0x038 -#define QSERDES_DP_PHY_AUX_CFG7				0x03c -#define QSERDES_DP_PHY_AUX_CFG8				0x040 -#define QSERDES_DP_PHY_AUX_CFG9				0x044 - -/* Only for QMP V3 PHY - DP PHY registers */ -#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK		0x048 -# define PHY_AUX_STOP_ERR_MASK				0x01 -# define PHY_AUX_DEC_ERR_MASK				0x02 -# define PHY_AUX_SYNC_ERR_MASK				0x04 -# define PHY_AUX_ALIGN_ERR_MASK				0x08 -# define PHY_AUX_REQ_ERR_MASK				0x10 - -#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_CLEAR		0x04c -#define QSERDES_V3_DP_PHY_AUX_BIST_CFG			0x050 - -#define QSERDES_V3_DP_PHY_VCO_DIV			0x064 -#define QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL		0x06c -#define QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL		0x088 - -#define QSERDES_V3_DP_PHY_SPARE0			0x0ac -#define DP_PHY_SPARE0_MASK				0x0f -#define DP_PHY_SPARE0_ORIENTATION_INFO_SHIFT		0x04(0x0004) - -#define QSERDES_V3_DP_PHY_STATUS			0x0c0 - -/* Only for QMP V4 PHY - DP PHY registers */ -#define QSERDES_V4_DP_PHY_CFG_1				0x014 -#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK		0x054 -#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_CLEAR		0x058 -#define QSERDES_V4_DP_PHY_VCO_DIV			0x070 -#define QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL		0x078 -#define QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL		0x09c -#define QSERDES_V4_DP_PHY_SPARE0			0x0c8 -#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS		0x0d8 -#define QSERDES_V4_DP_PHY_STATUS			0x0dc - -#define QSERDES_V5_DP_PHY_STATUS			0x0dc - -/* Only for QMP V6 PHY - DP PHY registers */ -#define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS		0x0e0 -#define QSERDES_V6_DP_PHY_STATUS			0x0e4 +/* QPHY_SW_RESET bit */ +#define SW_RESET				BIT(0) +/* QPHY_POWER_DOWN_CONTROL */ +#define SW_PWRDN				BIT(0) +#define REFCLK_DRV_DSBL				BIT(1) /* PCIe */ + +/* QPHY_START_CONTROL bits */ +#define SERDES_START				BIT(0) +#define PCS_START				BIT(1) + +/* QPHY_PCS_STATUS bit */ +#define PHYSTATUS				BIT(6) +#define PHYSTATUS_4_20				BIT(7) + +/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */ +#define ARCVR_DTCT_EN				BIT(0) +#define ALFPS_DTCT_EN				BIT(1) +#define ARCVR_DTCT_EVENT_SEL			BIT(4) + +/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */ +#define IRQ_CLEAR				BIT(0) + +/* QPHY_PCS_MISC_CLAMP_ENABLE register bits */ +#define CLAMP_EN				BIT(0) /* enables i/o clamp_n */  #endif diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c index 03dc753f0de1..5b1c82459c12 100644 --- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c +++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c @@ -11,93 +11,14 @@  #include <linux/platform_device.h>  #include <linux/regmap.h> -#define QSERDES_QMP_PLL					0x0 -#define QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0		(QSERDES_QMP_PLL + 0x1ac) -#define QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0		(QSERDES_QMP_PLL + 0x1b0) -#define QSERDES_COM_BIN_VCOCAL_HSCLK_SEL		(QSERDES_QMP_PLL + 0x1bc) -#define QSERDES_COM_CORE_CLK_EN				(QSERDES_QMP_PLL + 0x174) -#define QSERDES_COM_CORECLK_DIV_MODE0			(QSERDES_QMP_PLL + 0x168) -#define QSERDES_COM_CP_CTRL_MODE0			(QSERDES_QMP_PLL + 0x74) -#define QSERDES_COM_DEC_START_MODE0			(QSERDES_QMP_PLL + 0xbc) -#define QSERDES_COM_DIV_FRAC_START1_MODE0		(QSERDES_QMP_PLL + 0xcc) -#define QSERDES_COM_DIV_FRAC_START2_MODE0		(QSERDES_QMP_PLL + 0xd0) -#define QSERDES_COM_DIV_FRAC_START3_MODE0		(QSERDES_QMP_PLL + 0xd4) -#define QSERDES_COM_HSCLK_HS_SWITCH_SEL			(QSERDES_QMP_PLL + 0x15c) -#define QSERDES_COM_HSCLK_SEL				(QSERDES_QMP_PLL + 0x158) -#define QSERDES_COM_LOCK_CMP1_MODE0			(QSERDES_QMP_PLL + 0xac) -#define QSERDES_COM_LOCK_CMP2_MODE0			(QSERDES_QMP_PLL + 0xb0) -#define QSERDES_COM_PLL_CCTRL_MODE0			(QSERDES_QMP_PLL + 0x84) -#define QSERDES_COM_PLL_IVCO				(QSERDES_QMP_PLL + 0x58) -#define QSERDES_COM_PLL_RCTRL_MODE0			(QSERDES_QMP_PLL + 0x7c) -#define QSERDES_COM_SYSCLK_EN_SEL			(QSERDES_QMP_PLL + 0x94) -#define QSERDES_COM_VCO_TUNE1_MODE0			(QSERDES_QMP_PLL + 0x110) -#define QSERDES_COM_VCO_TUNE2_MODE0			(QSERDES_QMP_PLL + 0x114) -#define QSERDES_COM_VCO_TUNE_INITVAL2			(QSERDES_QMP_PLL + 0x124) -#define QSERDES_COM_C_READY_STATUS			(QSERDES_QMP_PLL + 0x178) -#define QSERDES_COM_CMN_STATUS				(QSERDES_QMP_PLL + 0x140) +#include "phy-qcom-qmp-pcs-sgmii.h" +#include "phy-qcom-qmp-qserdes-com-v5.h" +#include "phy-qcom-qmp-qserdes-txrx-v5.h" +#define QSERDES_QMP_PLL					0x0  #define QSERDES_RX					0x600 -#define QSERDES_RX_UCDR_FO_GAIN				(QSERDES_RX + 0x8) -#define QSERDES_RX_UCDR_SO_GAIN				(QSERDES_RX + 0x14) -#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN		(QSERDES_RX + 0x30) -#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE	(QSERDES_RX + 0x34) -#define QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW		(QSERDES_RX + 0x3c) -#define QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH		(QSERDES_RX + 0x40) -#define QSERDES_RX_UCDR_PI_CONTROLS			(QSERDES_RX + 0x44) -#define QSERDES_RX_UCDR_PI_CTRL2			(QSERDES_RX + 0x48) -#define QSERDES_RX_RX_TERM_BW				(QSERDES_RX + 0x80) -#define QSERDES_RX_VGA_CAL_CNTRL2			(QSERDES_RX + 0xd8) -#define QSERDES_RX_GM_CAL				(QSERDES_RX + 0xdc) -#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1		(QSERDES_RX + 0xe8) -#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2		(QSERDES_RX + 0xec) -#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3		(QSERDES_RX + 0xf0) -#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4		(QSERDES_RX + 0xf4) -#define QSERDES_RX_RX_IDAC_TSETTLE_LOW			(QSERDES_RX + 0xf8) -#define QSERDES_RX_RX_IDAC_TSETTLE_HIGH			(QSERDES_RX + 0xfc) -#define QSERDES_RX_RX_IDAC_MEASURE_TIME			(QSERDES_RX + 0x100) -#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1		(QSERDES_RX + 0x110) -#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2		(QSERDES_RX + 0x114) -#define QSERDES_RX_SIGDET_CNTRL				(QSERDES_RX + 0x11c) -#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL		(QSERDES_RX + 0x124) -#define QSERDES_RX_RX_BAND				(QSERDES_RX + 0x128) -#define QSERDES_RX_RX_MODE_00_LOW			(QSERDES_RX + 0x15c) -#define QSERDES_RX_RX_MODE_00_HIGH			(QSERDES_RX + 0x160) -#define QSERDES_RX_RX_MODE_00_HIGH2			(QSERDES_RX + 0x164) -#define QSERDES_RX_RX_MODE_00_HIGH3			(QSERDES_RX + 0x168) -#define QSERDES_RX_RX_MODE_00_HIGH4			(QSERDES_RX + 0x16c) -#define QSERDES_RX_RX_MODE_01_LOW			(QSERDES_RX + 0x170) -#define QSERDES_RX_RX_MODE_01_HIGH			(QSERDES_RX + 0x174) -#define QSERDES_RX_RX_MODE_01_HIGH2			(QSERDES_RX + 0x178) -#define QSERDES_RX_RX_MODE_01_HIGH3			(QSERDES_RX + 0x17c) -#define QSERDES_RX_RX_MODE_01_HIGH4			(QSERDES_RX + 0x180) -#define QSERDES_RX_RX_MODE_10_LOW			(QSERDES_RX + 0x184) -#define QSERDES_RX_RX_MODE_10_HIGH			(QSERDES_RX + 0x188) -#define QSERDES_RX_RX_MODE_10_HIGH2			(QSERDES_RX + 0x18c) -#define QSERDES_RX_RX_MODE_10_HIGH3			(QSERDES_RX + 0x190) -#define QSERDES_RX_RX_MODE_10_HIGH4			(QSERDES_RX + 0x194) -#define QSERDES_RX_DCC_CTRL1				(QSERDES_RX + 0x1a8) -  #define QSERDES_TX					0x400 -#define QSERDES_TX_TX_BAND				(QSERDES_TX + 0x24) -#define QSERDES_TX_SLEW_CNTL				(QSERDES_TX + 0x28) -#define QSERDES_TX_RES_CODE_LANE_OFFSET_TX		(QSERDES_TX + 0x3c) -#define QSERDES_TX_RES_CODE_LANE_OFFSET_RX		(QSERDES_TX + 0x40) -#define QSERDES_TX_LANE_MODE_1				(QSERDES_TX + 0x84) -#define QSERDES_TX_LANE_MODE_3				(QSERDES_TX + 0x8c) -#define QSERDES_TX_RCV_DETECT_LVL_2			(QSERDES_TX + 0xa4) -#define QSERDES_TX_TRAN_DRVR_EMP_EN			(QSERDES_TX + 0xc0) - -#define QSERDES_PCS					0xC00 -#define QSERDES_PCS_PHY_START				(QSERDES_PCS + 0x0) -#define QSERDES_PCS_POWER_DOWN_CONTROL			(QSERDES_PCS + 0x4) -#define QSERDES_PCS_SW_RESET				(QSERDES_PCS + 0x8) -#define QSERDES_PCS_LINE_RESET_TIME			(QSERDES_PCS + 0xc) -#define QSERDES_PCS_TX_LARGE_AMP_DRV_LVL		(QSERDES_PCS + 0x20) -#define QSERDES_PCS_TX_SMALL_AMP_DRV_LVL		(QSERDES_PCS + 0x28) -#define QSERDES_PCS_TX_MID_TERM_CTRL1			(QSERDES_PCS + 0xd8) -#define QSERDES_PCS_TX_MID_TERM_CTRL2			(QSERDES_PCS + 0xdc) -#define QSERDES_PCS_SGMII_MISC_CTRL8			(QSERDES_PCS + 0x118) -#define QSERDES_PCS_PCS_READY_STATUS			(QSERDES_PCS + 0x94) +#define QSERDES_PCS					0xc00  #define QSERDES_COM_C_READY				BIT(0)  #define QSERDES_PCS_READY				BIT(0) @@ -112,178 +33,178 @@ struct qcom_dwmac_sgmii_phy_data {  static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap)  { -	regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01); -	regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01); - -	regmap_write(regmap, QSERDES_COM_PLL_IVCO, 0x0F); -	regmap_write(regmap, QSERDES_COM_CP_CTRL_MODE0, 0x06); -	regmap_write(regmap, QSERDES_COM_PLL_RCTRL_MODE0, 0x16); -	regmap_write(regmap, QSERDES_COM_PLL_CCTRL_MODE0, 0x36); -	regmap_write(regmap, QSERDES_COM_SYSCLK_EN_SEL, 0x1A); -	regmap_write(regmap, QSERDES_COM_LOCK_CMP1_MODE0, 0x0A); -	regmap_write(regmap, QSERDES_COM_LOCK_CMP2_MODE0, 0x1A); -	regmap_write(regmap, QSERDES_COM_DEC_START_MODE0, 0x82); -	regmap_write(regmap, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55); -	regmap_write(regmap, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55); -	regmap_write(regmap, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03); -	regmap_write(regmap, QSERDES_COM_VCO_TUNE1_MODE0, 0x24); - -	regmap_write(regmap, QSERDES_COM_VCO_TUNE2_MODE0, 0x02); -	regmap_write(regmap, QSERDES_COM_VCO_TUNE_INITVAL2, 0x00); -	regmap_write(regmap, QSERDES_COM_HSCLK_SEL, 0x04); -	regmap_write(regmap, QSERDES_COM_HSCLK_HS_SWITCH_SEL, 0x00); -	regmap_write(regmap, QSERDES_COM_CORECLK_DIV_MODE0, 0x0A); -	regmap_write(regmap, QSERDES_COM_CORE_CLK_EN, 0x00); -	regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xB9); -	regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1E); -	regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_HSCLK_SEL, 0x11); - -	regmap_write(regmap, QSERDES_TX_TX_BAND, 0x05); -	regmap_write(regmap, QSERDES_TX_SLEW_CNTL, 0x0A); -	regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_TX, 0x09); -	regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_RX, 0x09); -	regmap_write(regmap, QSERDES_TX_LANE_MODE_1, 0x05); -	regmap_write(regmap, QSERDES_TX_LANE_MODE_3, 0x00); -	regmap_write(regmap, QSERDES_TX_RCV_DETECT_LVL_2, 0x12); -	regmap_write(regmap, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x0C); - -	regmap_write(regmap, QSERDES_RX_UCDR_FO_GAIN, 0x0A); -	regmap_write(regmap, QSERDES_RX_UCDR_SO_GAIN, 0x06); -	regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A); -	regmap_write(regmap, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F); -	regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00); -	regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01); -	regmap_write(regmap, QSERDES_RX_UCDR_PI_CONTROLS, 0x81); -	regmap_write(regmap, QSERDES_RX_UCDR_PI_CTRL2, 0x80); -	regmap_write(regmap, QSERDES_RX_RX_TERM_BW, 0x04); -	regmap_write(regmap, QSERDES_RX_VGA_CAL_CNTRL2, 0x08); -	regmap_write(regmap, QSERDES_RX_GM_CAL, 0x0F); -	regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04); -	regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00); -	regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A); -	regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A); -	regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_LOW, 0x80); -	regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_HIGH, 0x01); -	regmap_write(regmap, QSERDES_RX_RX_IDAC_MEASURE_TIME, 0x20); -	regmap_write(regmap, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17); -	regmap_write(regmap, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00); -	regmap_write(regmap, QSERDES_RX_SIGDET_CNTRL, 0x0F); -	regmap_write(regmap, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E); -	regmap_write(regmap, QSERDES_RX_RX_BAND, 0x05); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_LOW, 0xE0); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH2, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH3, 0x09); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH4, 0xB1); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_LOW, 0xE0); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH2, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH3, 0x09); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH4, 0xB1); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_LOW, 0xE0); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH2, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH3, 0x3B); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH4, 0xB7); -	regmap_write(regmap, QSERDES_RX_DCC_CTRL1, 0x0C); - -	regmap_write(regmap, QSERDES_PCS_LINE_RESET_TIME, 0x0C); -	regmap_write(regmap, QSERDES_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F); -	regmap_write(regmap, QSERDES_PCS_TX_SMALL_AMP_DRV_LVL, 0x03); -	regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL1, 0x83); -	regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08); -	regmap_write(regmap, QSERDES_PCS_SGMII_MISC_CTRL8, 0x0C); -	regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x00); - -	regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_POWER_DOWN_CONTROL, 0x01); + +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_IVCO, 0x0F); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CP_CTRL_MODE0, 0x06); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_SYSCLK_EN_SEL, 0x1A); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0A); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1A); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DEC_START_MODE0, 0x82); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24); + +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE2_MODE0, 0x02); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_HSCLK_SEL, 0x04); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x0A); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CORE_CLK_EN, 0x00); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xB9); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1E); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11); + +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_TX_BAND, 0x05); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_SLEW_CNTL, 0x0A); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_LANE_MODE_1, 0x05); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_LANE_MODE_3, 0x00); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0C); + +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FO_GAIN, 0x0A); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_SO_GAIN, 0x06); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x81); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_TERM_BW, 0x04); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x08); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_GM_CAL, 0x0F); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0x80); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x01); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x20); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_SIGDET_CNTRL, 0x0F); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1E); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_BAND, 0x05); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_LOW, 0xE0); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x09); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xB1); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_LOW, 0xE0); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x09); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xB1); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_LOW, 0xE0); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3B); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xB7); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_DCC_CTRL1, 0x0C); + +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_LINE_RESET_TIME, 0x0C); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_SMALL_AMP_DRV_LVL, 0x03); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL1, 0x83); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL2, 0x08); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SGMII_MISC_CTRL8, 0x0C); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x00); + +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);  }  static void qcom_dwmac_sgmii_phy_init_2p5g(struct regmap *regmap)  { -	regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x01); -	regmap_write(regmap, QSERDES_PCS_POWER_DOWN_CONTROL, 0x01); - -	regmap_write(regmap, QSERDES_COM_PLL_IVCO, 0x0F); -	regmap_write(regmap, QSERDES_COM_CP_CTRL_MODE0, 0x06); -	regmap_write(regmap, QSERDES_COM_PLL_RCTRL_MODE0, 0x16); -	regmap_write(regmap, QSERDES_COM_PLL_CCTRL_MODE0, 0x36); -	regmap_write(regmap, QSERDES_COM_SYSCLK_EN_SEL, 0x1A); -	regmap_write(regmap, QSERDES_COM_LOCK_CMP1_MODE0, 0x1A); -	regmap_write(regmap, QSERDES_COM_LOCK_CMP2_MODE0, 0x41); -	regmap_write(regmap, QSERDES_COM_DEC_START_MODE0, 0x7A); -	regmap_write(regmap, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00); -	regmap_write(regmap, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x20); -	regmap_write(regmap, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x01); -	regmap_write(regmap, QSERDES_COM_VCO_TUNE1_MODE0, 0xA1); - -	regmap_write(regmap, QSERDES_COM_VCO_TUNE2_MODE0, 0x02); -	regmap_write(regmap, QSERDES_COM_VCO_TUNE_INITVAL2, 0x00); -	regmap_write(regmap, QSERDES_COM_HSCLK_SEL, 0x03); -	regmap_write(regmap, QSERDES_COM_HSCLK_HS_SWITCH_SEL, 0x00); -	regmap_write(regmap, QSERDES_COM_CORECLK_DIV_MODE0, 0x05); -	regmap_write(regmap, QSERDES_COM_CORE_CLK_EN, 0x00); -	regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xCD); -	regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1C); -	regmap_write(regmap, QSERDES_COM_BIN_VCOCAL_HSCLK_SEL, 0x11); - -	regmap_write(regmap, QSERDES_TX_TX_BAND, 0x04); -	regmap_write(regmap, QSERDES_TX_SLEW_CNTL, 0x0A); -	regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_TX, 0x09); -	regmap_write(regmap, QSERDES_TX_RES_CODE_LANE_OFFSET_RX, 0x02); -	regmap_write(regmap, QSERDES_TX_LANE_MODE_1, 0x05); -	regmap_write(regmap, QSERDES_TX_LANE_MODE_3, 0x00); -	regmap_write(regmap, QSERDES_TX_RCV_DETECT_LVL_2, 0x12); -	regmap_write(regmap, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x0C); - -	regmap_write(regmap, QSERDES_RX_UCDR_FO_GAIN, 0x0A); -	regmap_write(regmap, QSERDES_RX_UCDR_SO_GAIN, 0x06); -	regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A); -	regmap_write(regmap, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F); -	regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00); -	regmap_write(regmap, QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01); -	regmap_write(regmap, QSERDES_RX_UCDR_PI_CONTROLS, 0x81); -	regmap_write(regmap, QSERDES_RX_UCDR_PI_CTRL2, 0x80); -	regmap_write(regmap, QSERDES_RX_RX_TERM_BW, 0x00); -	regmap_write(regmap, QSERDES_RX_VGA_CAL_CNTRL2, 0x08); -	regmap_write(regmap, QSERDES_RX_GM_CAL, 0x0F); -	regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04); -	regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00); -	regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A); -	regmap_write(regmap, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A); -	regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_LOW, 0x80); -	regmap_write(regmap, QSERDES_RX_RX_IDAC_TSETTLE_HIGH, 0x01); -	regmap_write(regmap, QSERDES_RX_RX_IDAC_MEASURE_TIME, 0x20); -	regmap_write(regmap, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17); -	regmap_write(regmap, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00); -	regmap_write(regmap, QSERDES_RX_SIGDET_CNTRL, 0x0F); -	regmap_write(regmap, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E); -	regmap_write(regmap, QSERDES_RX_RX_BAND, 0x18); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_LOW, 0x18); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH2, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH3, 0x0C); -	regmap_write(regmap, QSERDES_RX_RX_MODE_00_HIGH4, 0xB8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_LOW, 0xE0); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH2, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH3, 0x09); -	regmap_write(regmap, QSERDES_RX_RX_MODE_01_HIGH4, 0xB1); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_LOW, 0xE0); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH2, 0xC8); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH3, 0x3B); -	regmap_write(regmap, QSERDES_RX_RX_MODE_10_HIGH4, 0xB7); -	regmap_write(regmap, QSERDES_RX_DCC_CTRL1, 0x0C); - -	regmap_write(regmap, QSERDES_PCS_LINE_RESET_TIME, 0x0C); -	regmap_write(regmap, QSERDES_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F); -	regmap_write(regmap, QSERDES_PCS_TX_SMALL_AMP_DRV_LVL, 0x03); -	regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL1, 0x83); -	regmap_write(regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08); -	regmap_write(regmap, QSERDES_PCS_SGMII_MISC_CTRL8, 0x8C); -	regmap_write(regmap, QSERDES_PCS_SW_RESET, 0x00); - -	regmap_write(regmap, QSERDES_PCS_PHY_START, 0x01); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_POWER_DOWN_CONTROL, 0x01); + +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_IVCO, 0x0F); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CP_CTRL_MODE0, 0x06); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_SYSCLK_EN_SEL, 0x1A); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x1A); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x41); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DEC_START_MODE0, 0x7A); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x00); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x20); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x01); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE1_MODE0, 0xA1); + +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE2_MODE0, 0x02); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_HSCLK_SEL, 0x03); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x05); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_CORE_CLK_EN, 0x00); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xCD); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1C); +	regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11); + +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_TX_BAND, 0x04); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_SLEW_CNTL, 0x0A); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x02); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_LANE_MODE_1, 0x05); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_LANE_MODE_3, 0x00); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_RCV_DETECT_LVL_2, 0x12); +	regmap_write(regmap, QSERDES_TX + QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0C); + +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FO_GAIN, 0x0A); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_SO_GAIN, 0x06); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x81); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_TERM_BW, 0x00); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x08); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_GM_CAL, 0x0F); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0x80); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x01); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x20); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_SIGDET_CNTRL, 0x0F); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1E); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_BAND, 0x18); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_LOW, 0x18); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x0C); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xB8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_LOW, 0xE0); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x09); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xB1); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_LOW, 0xE0); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xC8); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3B); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xB7); +	regmap_write(regmap, QSERDES_RX + QSERDES_V5_RX_DCC_CTRL1, 0x0C); + +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_LINE_RESET_TIME, 0x0C); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_LARGE_AMP_DRV_LVL, 0x1F); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_SMALL_AMP_DRV_LVL, 0x03); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL1, 0x83); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL2, 0x08); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SGMII_MISC_CTRL8, 0x8C); +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x00); + +	regmap_write(regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);  }  static inline int @@ -313,28 +234,28 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)  	}  	if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, -					     QSERDES_COM_C_READY_STATUS, +					     QSERDES_QMP_PLL + QSERDES_V5_COM_C_READY_STATUS,  					     QSERDES_COM_C_READY)) {  		dev_err(dev, "QSERDES_COM_C_READY_STATUS timed-out");  		return -ETIMEDOUT;  	}  	if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, -					     QSERDES_PCS_PCS_READY_STATUS, +					     QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,  					     QSERDES_PCS_READY)) {  		dev_err(dev, "PCS_READY timed-out");  		return -ETIMEDOUT;  	}  	if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, -					     QSERDES_PCS_PCS_READY_STATUS, +					     QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,  					     QSERDES_PCS_SGMIIPHY_READY)) {  		dev_err(dev, "SGMIIPHY_READY timed-out");  		return -ETIMEDOUT;  	}  	if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, -					     QSERDES_COM_CMN_STATUS, +					     QSERDES_QMP_PLL + QSERDES_V5_COM_CMN_STATUS,  					     QSERDES_COM_C_PLL_LOCKED)) {  		dev_err(dev, "PLL Lock Status timed-out");  		return -ETIMEDOUT; @@ -354,11 +275,11 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)  {  	struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); -	regmap_write(data->regmap, QSERDES_PCS_TX_MID_TERM_CTRL2, 0x08); -	regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x01); +	regmap_write(data->regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL2, 0x08); +	regmap_write(data->regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01);  	udelay(100); -	regmap_write(data->regmap, QSERDES_PCS_SW_RESET, 0x00); -	regmap_write(data->regmap, QSERDES_PCS_PHY_START, 0x01); +	regmap_write(data->regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x00); +	regmap_write(data->regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);  	clk_disable_unprepare(data->refclk); diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c index 2f876f158e1d..a591ad95347c 100644 --- a/drivers/phy/ralink/phy-mt7621-pci.c +++ b/drivers/phy/ralink/phy-mt7621-pci.c @@ -263,7 +263,7 @@ static const struct phy_ops mt7621_pci_phy_ops = {  };  static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev, -					    struct of_phandle_args *args) +					    const struct of_phandle_args *args)  {  	struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev); diff --git a/drivers/phy/renesas/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c index 507435af2656..c0221e7258c0 100644 --- a/drivers/phy/renesas/phy-rcar-gen2.c +++ b/drivers/phy/renesas/phy-rcar-gen2.c @@ -306,7 +306,7 @@ static const struct of_device_id rcar_gen2_phy_match_table[] = {  MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);  static struct phy *rcar_gen2_phy_xlate(struct device *dev, -				       struct of_phandle_args *args) +				       const struct of_phandle_args *args)  {  	struct rcar_gen2_phy_driver *drv;  	struct device_node *np = args->np; diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 6387c0d34c55..fbab6ac0f0d1 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -608,7 +608,7 @@ static const unsigned int rcar_gen3_phy_cable[] = {  };  static struct phy *rcar_gen3_phy_usb2_xlate(struct device *dev, -					    struct of_phandle_args *args) +					    const struct of_phandle_args *args)  {  	struct rcar_gen3_chan *ch = dev_get_drvdata(dev); diff --git a/drivers/phy/renesas/r8a779f0-ether-serdes.c b/drivers/phy/renesas/r8a779f0-ether-serdes.c index fc6e398fa3bf..f1f1da4a0b1f 100644 --- a/drivers/phy/renesas/r8a779f0-ether-serdes.c +++ b/drivers/phy/renesas/r8a779f0-ether-serdes.c @@ -334,7 +334,7 @@ static const struct phy_ops r8a779f0_eth_serdes_ops = {  };  static struct phy *r8a779f0_eth_serdes_xlate(struct device *dev, -					     struct of_phandle_args *args) +					     const struct of_phandle_args *args)  {  	struct r8a779f0_eth_serdes_drv_data *dd = dev_get_drvdata(dev); diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index 94360fc96a6f..a34f67bb7e61 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -83,6 +83,14 @@ config PHY_ROCKCHIP_PCIE  	help  	  Enable this to support the Rockchip PCIe PHY. +config PHY_ROCKCHIP_SAMSUNG_HDPTX +	tristate "Rockchip Samsung HDMI/eDP Combo PHY driver" +	depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF +	select GENERIC_PHY +	help +	  Enable this to support the Rockchip HDMI/eDP Combo PHY +	  with Samsung IP block. +  config PHY_ROCKCHIP_SNPS_PCIE3  	tristate "Rockchip Snps PCIe3 PHY Driver"  	depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile index 7eab129230d1..3d911304e654 100644 --- a/drivers/phy/rockchip/Makefile +++ b/drivers/phy/rockchip/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI)	+= phy-rockchip-inno-hdmi.o  obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)	+= phy-rockchip-inno-usb2.o  obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY)	+= phy-rockchip-naneng-combphy.o  obj-$(CONFIG_PHY_ROCKCHIP_PCIE)		+= phy-rockchip-pcie.o +obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX)	+= phy-rockchip-samsung-hdptx.o  obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3)	+= phy-rockchip-snps-pcie3.o  obj-$(CONFIG_PHY_ROCKCHIP_TYPEC)	+= phy-rockchip-typec.o  obj-$(CONFIG_PHY_ROCKCHIP_USB)		+= phy-rockchip-usb.o diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index 5de5e2e97ffa..76b9cf417591 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -251,7 +251,7 @@ static const struct phy_ops rochchip_combphy_ops = {  	.owner = THIS_MODULE,  }; -static struct phy *rockchip_combphy_xlate(struct device *dev, struct of_phandle_args *args) +static struct phy *rockchip_combphy_xlate(struct device *dev, const struct of_phandle_args *args)  {  	struct rockchip_combphy_priv *priv = dev_get_drvdata(dev); diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c index 1bbd6be2a584..51cc5ece0e63 100644 --- a/drivers/phy/rockchip/phy-rockchip-pcie.c +++ b/drivers/phy/rockchip/phy-rockchip-pcie.c @@ -82,7 +82,7 @@ static struct rockchip_pcie_phy *to_pcie_phy(struct phy_pcie_instance *inst)  }  static struct phy *rockchip_pcie_phy_of_xlate(struct device *dev, -					      struct of_phandle_args *args) +					      const struct of_phandle_args *args)  {  	struct rockchip_pcie_phy *rk_phy = dev_get_drvdata(dev); diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c new file mode 100644 index 000000000000..946c01210ac8 --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -0,0 +1,1028 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd. + * Copyright (c) 2024 Collabora Ltd. + * + * Author: Algea Cao <algea.cao@rock-chips.com> + * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> + */ +#include <linux/bitfield.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/rational.h> +#include <linux/regmap.h> +#include <linux/reset.h> + +#define GRF_HDPTX_CON0			0x00 +#define HDPTX_I_PLL_EN			BIT(7) +#define HDPTX_I_BIAS_EN			BIT(6) +#define HDPTX_I_BGR_EN			BIT(5) +#define GRF_HDPTX_STATUS		0x80 +#define HDPTX_O_PLL_LOCK_DONE		BIT(3) +#define HDPTX_O_PHY_CLK_RDY		BIT(2) +#define HDPTX_O_PHY_RDY			BIT(1) +#define HDPTX_O_SB_RDY			BIT(0) + +#define HDTPX_REG(_n, _min, _max)				\ +	(							\ +		BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) +	\ +		BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) +	\ +		((0x##_n) * 4)					\ +	) + +#define CMN_REG(n)			HDTPX_REG(n, 0000, 00a7) +#define SB_REG(n)			HDTPX_REG(n, 0100, 0129) +#define LNTOP_REG(n)			HDTPX_REG(n, 0200, 0229) +#define LANE_REG(n)			HDTPX_REG(n, 0300, 062d) + +/* CMN_REG(0008) */ +#define LCPLL_EN_MASK			BIT(6) +#define LCPLL_LCVCO_MODE_EN_MASK	BIT(4) +/* CMN_REG(001e) */ +#define LCPLL_PI_EN_MASK		BIT(5) +#define LCPLL_100M_CLK_EN_MASK		BIT(0) +/* CMN_REG(0025) */ +#define LCPLL_PMS_IQDIV_RSTN		BIT(4) +/* CMN_REG(0028) */ +#define LCPLL_SDC_FRAC_EN		BIT(2) +#define LCPLL_SDC_FRAC_RSTN		BIT(0) +/* CMN_REG(002d) */ +#define LCPLL_SDC_N_MASK		GENMASK(3, 1) +/* CMN_REG(002e) */ +#define LCPLL_SDC_NUMBERATOR_MASK	GENMASK(5, 0) +/* CMN_REG(002f) */ +#define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2) +#define LCPLL_SDC_NDIV_RSTN		BIT(0) +/* CMN_REG(003d) */ +#define ROPLL_LCVCO_EN			BIT(4) +/* CMN_REG(004e) */ +#define ROPLL_PI_EN			BIT(5) +/* CMN_REG(005c) */ +#define ROPLL_PMS_IQDIV_RSTN		BIT(5) +/* CMN_REG(005e) */ +#define ROPLL_SDM_EN_MASK		BIT(6) +#define ROPLL_SDM_FRAC_EN_RBR		BIT(3) +#define ROPLL_SDM_FRAC_EN_HBR		BIT(2) +#define ROPLL_SDM_FRAC_EN_HBR2		BIT(1) +#define ROPLL_SDM_FRAC_EN_HBR3		BIT(0) +/* CMN_REG(0064) */ +#define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3) +/* CMN_REG(0069) */ +#define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0) +/* CMN_REG(0074) */ +#define ROPLL_SDC_NDIV_RSTN		BIT(2) +#define ROPLL_SSC_EN			BIT(0) +/* CMN_REG(0081) */ +#define OVRD_PLL_CD_CLK_EN		BIT(8) +#define PLL_CD_HSCLK_EAST_EN		BIT(0) +/* CMN_REG(0086) */ +#define PLL_PCG_POSTDIV_SEL_MASK	GENMASK(7, 4) +#define PLL_PCG_CLK_SEL_MASK		GENMASK(3, 1) +#define PLL_PCG_CLK_EN			BIT(0) +/* CMN_REG(0087) */ +#define PLL_FRL_MODE_EN			BIT(3) +#define PLL_TX_HS_CLK_EN		BIT(2) +/* CMN_REG(0089) */ +#define LCPLL_ALONE_MODE		BIT(1) +/* CMN_REG(0097) */ +#define DIG_CLK_SEL			BIT(1) +#define ROPLL_REF			BIT(1) +#define LCPLL_REF			0 +/* CMN_REG(0099) */ +#define CMN_ROPLL_ALONE_MODE		BIT(2) +#define ROPLL_ALONE_MODE		BIT(2) +/* CMN_REG(009a) */ +#define HS_SPEED_SEL			BIT(0) +#define DIV_10_CLOCK			BIT(0) +/* CMN_REG(009b) */ +#define IS_SPEED_SEL			BIT(4) +#define LINK_SYMBOL_CLOCK		BIT(4) +#define LINK_SYMBOL_CLOCK1_2		0 + +/* SB_REG(0102) */ +#define OVRD_SB_RXTERM_EN_MASK		BIT(5) +#define SB_RXTERM_EN_MASK		BIT(4) +#define ANA_SB_RXTERM_OFFSP_MASK	GENMASK(3, 0) +/* SB_REG(0103) */ +#define ANA_SB_RXTERM_OFFSN_MASK	GENMASK(6, 3) +#define OVRD_SB_RX_RESCAL_DONE_MASK	BIT(1) +#define SB_RX_RESCAL_DONE_MASK		BIT(0) +/* SB_REG(0104) */ +#define OVRD_SB_EN_MASK			BIT(5) +#define SB_EN_MASK			BIT(4) +/* SB_REG(0105) */ +#define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6) +#define SB_EARC_CMDC_EN_MASK		BIT(5) +#define ANA_SB_TX_HLVL_PROG_MASK	GENMASK(2, 0) +/* SB_REG(0106) */ +#define ANA_SB_TX_LLVL_PROG_MASK	GENMASK(6, 4) +/* SB_REG(0109) */ +#define ANA_SB_DMRX_AFC_DIV_RATIO_MASK	GENMASK(2, 0) +/* SB_REG(010f) */ +#define OVRD_SB_VREG_EN_MASK		BIT(7) +#define SB_VREG_EN_MASK			BIT(6) +#define OVRD_SB_VREG_LPF_BYPASS_MASK	BIT(5) +#define SB_VREG_LPF_BYPASS_MASK		BIT(4) +#define ANA_SB_VREG_GAIN_CTRL_MASK	GENMASK(3, 0) +/* SB_REG(0110) */ +#define ANA_SB_VREG_REF_SEL_MASK	BIT(0) +/* SB_REG(0113) */ +#define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4) +#define SB_RX_RTERM_CTRL_MASK		GENMASK(3, 0) +/* SB_REG(0114) */ +#define SB_TG_SB_EN_DELAY_TIME_MASK	GENMASK(5, 3) +#define SB_TG_RXTERM_EN_DELAY_TIME_MASK	GENMASK(2, 0) +/* SB_REG(0115) */ +#define SB_READY_DELAY_TIME_MASK	GENMASK(5, 3) +#define SB_TG_OSC_EN_DELAY_TIME_MASK	GENMASK(2, 0) +/* SB_REG(0116) */ +#define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4) +/* SB_REG(0117) */ +#define FAST_PULSE_TIME_MASK		GENMASK(3, 0) +/* SB_REG(011b) */ +#define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4) +#define SB_AFC_TOL_MASK			GENMASK(3, 0) +/* SB_REG(011f) */ +#define SB_PWM_AFC_CTRL_MASK		GENMASK(7, 2) +#define SB_RCAL_RSTN_MASK		BIT(1) +/* SB_REG(0120) */ +#define SB_EARC_EN_MASK			BIT(1) +#define SB_EARC_AFC_EN_MASK		BIT(2) +/* SB_REG(0123) */ +#define OVRD_SB_READY_MASK		BIT(5) +#define SB_READY_MASK			BIT(4) + +/* LNTOP_REG(0200) */ +#define PROTOCOL_SEL			BIT(2) +#define HDMI_MODE			BIT(2) +#define HDMI_TMDS_FRL_SEL		BIT(1) +/* LNTOP_REG(0206) */ +#define DATA_BUS_SEL			BIT(0) +#define DATA_BUS_36_40			BIT(0) +/* LNTOP_REG(0207) */ +#define LANE_EN				0xf +#define ALL_LANE_EN			0xf + +/* LANE_REG(0312) */ +#define LN0_TX_SER_RATE_SEL_RBR		BIT(5) +#define LN0_TX_SER_RATE_SEL_HBR		BIT(4) +#define LN0_TX_SER_RATE_SEL_HBR2	BIT(3) +#define LN0_TX_SER_RATE_SEL_HBR3	BIT(2) +/* LANE_REG(0412) */ +#define LN1_TX_SER_RATE_SEL_RBR		BIT(5) +#define LN1_TX_SER_RATE_SEL_HBR		BIT(4) +#define LN1_TX_SER_RATE_SEL_HBR2	BIT(3) +#define LN1_TX_SER_RATE_SEL_HBR3	BIT(2) +/* LANE_REG(0512) */ +#define LN2_TX_SER_RATE_SEL_RBR		BIT(5) +#define LN2_TX_SER_RATE_SEL_HBR		BIT(4) +#define LN2_TX_SER_RATE_SEL_HBR2	BIT(3) +#define LN2_TX_SER_RATE_SEL_HBR3	BIT(2) +/* LANE_REG(0612) */ +#define LN3_TX_SER_RATE_SEL_RBR		BIT(5) +#define LN3_TX_SER_RATE_SEL_HBR		BIT(4) +#define LN3_TX_SER_RATE_SEL_HBR2	BIT(3) +#define LN3_TX_SER_RATE_SEL_HBR3	BIT(2) + +struct lcpll_config { +	u32 bit_rate; +	u8 lcvco_mode_en; +	u8 pi_en; +	u8 clk_en_100m; +	u8 pms_mdiv; +	u8 pms_mdiv_afc; +	u8 pms_pdiv; +	u8 pms_refdiv; +	u8 pms_sdiv; +	u8 pi_cdiv_rstn; +	u8 pi_cdiv_sel; +	u8 sdm_en; +	u8 sdm_rstn; +	u8 sdc_frac_en; +	u8 sdc_rstn; +	u8 sdm_deno; +	u8 sdm_num_sign; +	u8 sdm_num; +	u8 sdc_n; +	u8 sdc_n2; +	u8 sdc_num; +	u8 sdc_deno; +	u8 sdc_ndiv_rstn; +	u8 ssc_en; +	u8 ssc_fm_dev; +	u8 ssc_fm_freq; +	u8 ssc_clk_div_sel; +	u8 cd_tx_ser_rate_sel; +}; + +struct ropll_config { +	u32 bit_rate; +	u8 pms_mdiv; +	u8 pms_mdiv_afc; +	u8 pms_pdiv; +	u8 pms_refdiv; +	u8 pms_sdiv; +	u8 pms_iqdiv_rstn; +	u8 ref_clk_sel; +	u8 sdm_en; +	u8 sdm_rstn; +	u8 sdc_frac_en; +	u8 sdc_rstn; +	u8 sdm_clk_div; +	u8 sdm_deno; +	u8 sdm_num_sign; +	u8 sdm_num; +	u8 sdc_n; +	u8 sdc_num; +	u8 sdc_deno; +	u8 sdc_ndiv_rstn; +	u8 ssc_en; +	u8 ssc_fm_dev; +	u8 ssc_fm_freq; +	u8 ssc_clk_div_sel; +	u8 ana_cpp_ctrl; +	u8 ana_lpf_c_sel; +	u8 cd_tx_ser_rate_sel; +}; + +enum rk_hdptx_reset { +	RST_PHY = 0, +	RST_APB, +	RST_INIT, +	RST_CMN, +	RST_LANE, +	RST_ROPLL, +	RST_LCPLL, +	RST_MAX +}; + +struct rk_hdptx_phy { +	struct device *dev; +	struct regmap *regmap; +	struct regmap *grf; + +	struct phy *phy; +	struct phy_config *phy_cfg; +	struct clk_bulk_data *clks; +	int nr_clks; +	struct reset_control_bulk_data rsts[RST_MAX]; +}; + +static const struct ropll_config ropll_tmds_cfg[] = { +	{ 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 3712500, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 2970000, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 1620000, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10, +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 1856250, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 1540000, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 1485000, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5, +	  0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 1462500, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1, +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 1190000, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1, +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 1065000, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1, +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 1080000, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, +	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 855000, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 835000, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 928125, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 742500, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 650000, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1, +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 337500, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5, +	  1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 400000, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, +	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 270000, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, +	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +	{ 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1, +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +}; + +static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { +	REG_SEQ0(CMN_REG(0009), 0x0c), +	REG_SEQ0(CMN_REG(000a), 0x83), +	REG_SEQ0(CMN_REG(000b), 0x06), +	REG_SEQ0(CMN_REG(000c), 0x20), +	REG_SEQ0(CMN_REG(000d), 0xb8), +	REG_SEQ0(CMN_REG(000e), 0x0f), +	REG_SEQ0(CMN_REG(000f), 0x0f), +	REG_SEQ0(CMN_REG(0010), 0x04), +	REG_SEQ0(CMN_REG(0011), 0x00), +	REG_SEQ0(CMN_REG(0012), 0x26), +	REG_SEQ0(CMN_REG(0013), 0x22), +	REG_SEQ0(CMN_REG(0014), 0x24), +	REG_SEQ0(CMN_REG(0015), 0x77), +	REG_SEQ0(CMN_REG(0016), 0x08), +	REG_SEQ0(CMN_REG(0017), 0x00), +	REG_SEQ0(CMN_REG(0018), 0x04), +	REG_SEQ0(CMN_REG(0019), 0x48), +	REG_SEQ0(CMN_REG(001a), 0x01), +	REG_SEQ0(CMN_REG(001b), 0x00), +	REG_SEQ0(CMN_REG(001c), 0x01), +	REG_SEQ0(CMN_REG(001d), 0x64), +	REG_SEQ0(CMN_REG(001f), 0x00), +	REG_SEQ0(CMN_REG(0026), 0x53), +	REG_SEQ0(CMN_REG(0029), 0x01), +	REG_SEQ0(CMN_REG(0030), 0x00), +	REG_SEQ0(CMN_REG(0031), 0x20), +	REG_SEQ0(CMN_REG(0032), 0x30), +	REG_SEQ0(CMN_REG(0033), 0x0b), +	REG_SEQ0(CMN_REG(0034), 0x23), +	REG_SEQ0(CMN_REG(0035), 0x00), +	REG_SEQ0(CMN_REG(0038), 0x00), +	REG_SEQ0(CMN_REG(0039), 0x00), +	REG_SEQ0(CMN_REG(003a), 0x00), +	REG_SEQ0(CMN_REG(003b), 0x00), +	REG_SEQ0(CMN_REG(003c), 0x80), +	REG_SEQ0(CMN_REG(003e), 0x0c), +	REG_SEQ0(CMN_REG(003f), 0x83), +	REG_SEQ0(CMN_REG(0040), 0x06), +	REG_SEQ0(CMN_REG(0041), 0x20), +	REG_SEQ0(CMN_REG(0042), 0xb8), +	REG_SEQ0(CMN_REG(0043), 0x00), +	REG_SEQ0(CMN_REG(0044), 0x46), +	REG_SEQ0(CMN_REG(0045), 0x24), +	REG_SEQ0(CMN_REG(0046), 0xff), +	REG_SEQ0(CMN_REG(0047), 0x00), +	REG_SEQ0(CMN_REG(0048), 0x44), +	REG_SEQ0(CMN_REG(0049), 0xfa), +	REG_SEQ0(CMN_REG(004a), 0x08), +	REG_SEQ0(CMN_REG(004b), 0x00), +	REG_SEQ0(CMN_REG(004c), 0x01), +	REG_SEQ0(CMN_REG(004d), 0x64), +	REG_SEQ0(CMN_REG(004e), 0x14), +	REG_SEQ0(CMN_REG(004f), 0x00), +	REG_SEQ0(CMN_REG(0050), 0x00), +	REG_SEQ0(CMN_REG(005d), 0x0c), +	REG_SEQ0(CMN_REG(005f), 0x01), +	REG_SEQ0(CMN_REG(006b), 0x04), +	REG_SEQ0(CMN_REG(0073), 0x30), +	REG_SEQ0(CMN_REG(0074), 0x00), +	REG_SEQ0(CMN_REG(0075), 0x20), +	REG_SEQ0(CMN_REG(0076), 0x30), +	REG_SEQ0(CMN_REG(0077), 0x08), +	REG_SEQ0(CMN_REG(0078), 0x0c), +	REG_SEQ0(CMN_REG(0079), 0x00), +	REG_SEQ0(CMN_REG(007b), 0x00), +	REG_SEQ0(CMN_REG(007c), 0x00), +	REG_SEQ0(CMN_REG(007d), 0x00), +	REG_SEQ0(CMN_REG(007e), 0x00), +	REG_SEQ0(CMN_REG(007f), 0x00), +	REG_SEQ0(CMN_REG(0080), 0x00), +	REG_SEQ0(CMN_REG(0081), 0x09), +	REG_SEQ0(CMN_REG(0082), 0x04), +	REG_SEQ0(CMN_REG(0083), 0x24), +	REG_SEQ0(CMN_REG(0084), 0x20), +	REG_SEQ0(CMN_REG(0085), 0x03), +	REG_SEQ0(CMN_REG(0086), 0x01), +	REG_SEQ0(CMN_REG(0087), 0x0c), +	REG_SEQ0(CMN_REG(008a), 0x55), +	REG_SEQ0(CMN_REG(008b), 0x25), +	REG_SEQ0(CMN_REG(008c), 0x2c), +	REG_SEQ0(CMN_REG(008d), 0x22), +	REG_SEQ0(CMN_REG(008e), 0x14), +	REG_SEQ0(CMN_REG(008f), 0x20), +	REG_SEQ0(CMN_REG(0090), 0x00), +	REG_SEQ0(CMN_REG(0091), 0x00), +	REG_SEQ0(CMN_REG(0092), 0x00), +	REG_SEQ0(CMN_REG(0093), 0x00), +	REG_SEQ0(CMN_REG(009a), 0x11), +	REG_SEQ0(CMN_REG(009b), 0x10), +}; + +static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { +	REG_SEQ0(CMN_REG(0008), 0x00), +	REG_SEQ0(CMN_REG(0011), 0x01), +	REG_SEQ0(CMN_REG(0017), 0x20), +	REG_SEQ0(CMN_REG(001e), 0x14), +	REG_SEQ0(CMN_REG(0020), 0x00), +	REG_SEQ0(CMN_REG(0021), 0x00), +	REG_SEQ0(CMN_REG(0022), 0x11), +	REG_SEQ0(CMN_REG(0023), 0x00), +	REG_SEQ0(CMN_REG(0024), 0x00), +	REG_SEQ0(CMN_REG(0025), 0x53), +	REG_SEQ0(CMN_REG(0026), 0x00), +	REG_SEQ0(CMN_REG(0027), 0x00), +	REG_SEQ0(CMN_REG(0028), 0x01), +	REG_SEQ0(CMN_REG(002a), 0x00), +	REG_SEQ0(CMN_REG(002b), 0x00), +	REG_SEQ0(CMN_REG(002c), 0x00), +	REG_SEQ0(CMN_REG(002d), 0x00), +	REG_SEQ0(CMN_REG(002e), 0x04), +	REG_SEQ0(CMN_REG(002f), 0x00), +	REG_SEQ0(CMN_REG(0030), 0x20), +	REG_SEQ0(CMN_REG(0031), 0x30), +	REG_SEQ0(CMN_REG(0032), 0x0b), +	REG_SEQ0(CMN_REG(0033), 0x23), +	REG_SEQ0(CMN_REG(0034), 0x00), +	REG_SEQ0(CMN_REG(003d), 0x40), +	REG_SEQ0(CMN_REG(0042), 0x78), +	REG_SEQ0(CMN_REG(004e), 0x34), +	REG_SEQ0(CMN_REG(005c), 0x25), +	REG_SEQ0(CMN_REG(005e), 0x4f), +	REG_SEQ0(CMN_REG(0074), 0x04), +	REG_SEQ0(CMN_REG(0081), 0x01), +	REG_SEQ0(CMN_REG(0087), 0x04), +	REG_SEQ0(CMN_REG(0089), 0x00), +	REG_SEQ0(CMN_REG(0095), 0x00), +	REG_SEQ0(CMN_REG(0097), 0x02), +	REG_SEQ0(CMN_REG(0099), 0x04), +	REG_SEQ0(CMN_REG(009b), 0x00), +}; + +static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = { +	REG_SEQ0(SB_REG(0114), 0x00), +	REG_SEQ0(SB_REG(0115), 0x00), +	REG_SEQ0(SB_REG(0116), 0x00), +	REG_SEQ0(SB_REG(0117), 0x00), +}; + +static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = { +	REG_SEQ0(LNTOP_REG(0201), 0x00), +	REG_SEQ0(LNTOP_REG(0202), 0x00), +	REG_SEQ0(LNTOP_REG(0203), 0x0f), +	REG_SEQ0(LNTOP_REG(0204), 0xff), +	REG_SEQ0(LNTOP_REG(0205), 0xff), +}; + +static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = { +	REG_SEQ0(LNTOP_REG(0201), 0x07), +	REG_SEQ0(LNTOP_REG(0202), 0xc1), +	REG_SEQ0(LNTOP_REG(0203), 0xf0), +	REG_SEQ0(LNTOP_REG(0204), 0x7c), +	REG_SEQ0(LNTOP_REG(0205), 0x1f), +}; + +static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { +	REG_SEQ0(LANE_REG(0303), 0x0c), +	REG_SEQ0(LANE_REG(0307), 0x20), +	REG_SEQ0(LANE_REG(030a), 0x17), +	REG_SEQ0(LANE_REG(030b), 0x77), +	REG_SEQ0(LANE_REG(030c), 0x77), +	REG_SEQ0(LANE_REG(030d), 0x77), +	REG_SEQ0(LANE_REG(030e), 0x38), +	REG_SEQ0(LANE_REG(0310), 0x03), +	REG_SEQ0(LANE_REG(0311), 0x0f), +	REG_SEQ0(LANE_REG(0316), 0x02), +	REG_SEQ0(LANE_REG(031b), 0x01), +	REG_SEQ0(LANE_REG(031f), 0x15), +	REG_SEQ0(LANE_REG(0320), 0xa0), +	REG_SEQ0(LANE_REG(0403), 0x0c), +	REG_SEQ0(LANE_REG(0407), 0x20), +	REG_SEQ0(LANE_REG(040a), 0x17), +	REG_SEQ0(LANE_REG(040b), 0x77), +	REG_SEQ0(LANE_REG(040c), 0x77), +	REG_SEQ0(LANE_REG(040d), 0x77), +	REG_SEQ0(LANE_REG(040e), 0x38), +	REG_SEQ0(LANE_REG(0410), 0x03), +	REG_SEQ0(LANE_REG(0411), 0x0f), +	REG_SEQ0(LANE_REG(0416), 0x02), +	REG_SEQ0(LANE_REG(041b), 0x01), +	REG_SEQ0(LANE_REG(041f), 0x15), +	REG_SEQ0(LANE_REG(0420), 0xa0), +	REG_SEQ0(LANE_REG(0503), 0x0c), +	REG_SEQ0(LANE_REG(0507), 0x20), +	REG_SEQ0(LANE_REG(050a), 0x17), +	REG_SEQ0(LANE_REG(050b), 0x77), +	REG_SEQ0(LANE_REG(050c), 0x77), +	REG_SEQ0(LANE_REG(050d), 0x77), +	REG_SEQ0(LANE_REG(050e), 0x38), +	REG_SEQ0(LANE_REG(0510), 0x03), +	REG_SEQ0(LANE_REG(0511), 0x0f), +	REG_SEQ0(LANE_REG(0516), 0x02), +	REG_SEQ0(LANE_REG(051b), 0x01), +	REG_SEQ0(LANE_REG(051f), 0x15), +	REG_SEQ0(LANE_REG(0520), 0xa0), +	REG_SEQ0(LANE_REG(0603), 0x0c), +	REG_SEQ0(LANE_REG(0607), 0x20), +	REG_SEQ0(LANE_REG(060a), 0x17), +	REG_SEQ0(LANE_REG(060b), 0x77), +	REG_SEQ0(LANE_REG(060c), 0x77), +	REG_SEQ0(LANE_REG(060d), 0x77), +	REG_SEQ0(LANE_REG(060e), 0x38), +	REG_SEQ0(LANE_REG(0610), 0x03), +	REG_SEQ0(LANE_REG(0611), 0x0f), +	REG_SEQ0(LANE_REG(0616), 0x02), +	REG_SEQ0(LANE_REG(061b), 0x01), +	REG_SEQ0(LANE_REG(061f), 0x15), +	REG_SEQ0(LANE_REG(0620), 0xa0), +}; + +static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { +	REG_SEQ0(LANE_REG(0312), 0x00), +	REG_SEQ0(LANE_REG(031e), 0x00), +	REG_SEQ0(LANE_REG(0412), 0x00), +	REG_SEQ0(LANE_REG(041e), 0x00), +	REG_SEQ0(LANE_REG(0512), 0x00), +	REG_SEQ0(LANE_REG(051e), 0x00), +	REG_SEQ0(LANE_REG(0612), 0x00), +	REG_SEQ0(LANE_REG(061e), 0x08), +	REG_SEQ0(LANE_REG(0303), 0x2f), +	REG_SEQ0(LANE_REG(0403), 0x2f), +	REG_SEQ0(LANE_REG(0503), 0x2f), +	REG_SEQ0(LANE_REG(0603), 0x2f), +	REG_SEQ0(LANE_REG(0305), 0x03), +	REG_SEQ0(LANE_REG(0405), 0x03), +	REG_SEQ0(LANE_REG(0505), 0x03), +	REG_SEQ0(LANE_REG(0605), 0x03), +	REG_SEQ0(LANE_REG(0306), 0x1c), +	REG_SEQ0(LANE_REG(0406), 0x1c), +	REG_SEQ0(LANE_REG(0506), 0x1c), +	REG_SEQ0(LANE_REG(0606), 0x1c), +}; + +static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg) +{ +	switch (reg) { +	case 0x0000 ... 0x029c: +	case 0x0400 ... 0x04a4: +	case 0x0800 ... 0x08a4: +	case 0x0c00 ... 0x0cb4: +	case 0x1000 ... 0x10b4: +	case 0x1400 ... 0x14b4: +	case 0x1800 ... 0x18b4: +		return true; +	} + +	return false; +} + +static const struct regmap_config rk_hdptx_phy_regmap_config = { +	.reg_bits = 32, +	.reg_stride = 4, +	.val_bits = 32, +	.writeable_reg = rk_hdptx_phy_is_rw_reg, +	.readable_reg = rk_hdptx_phy_is_rw_reg, +	.fast_io = true, +	.max_register = 0x18b4, +}; + +#define rk_hdptx_multi_reg_write(hdptx, seq) \ +	regmap_multi_reg_write((hdptx)->regmap, seq, ARRAY_SIZE(seq)) + +static void rk_hdptx_pre_power_up(struct rk_hdptx_phy *hdptx) +{ +	u32 val; + +	reset_control_assert(hdptx->rsts[RST_APB].rstc); +	usleep_range(20, 25); +	reset_control_deassert(hdptx->rsts[RST_APB].rstc); + +	reset_control_assert(hdptx->rsts[RST_LANE].rstc); +	reset_control_assert(hdptx->rsts[RST_CMN].rstc); +	reset_control_assert(hdptx->rsts[RST_INIT].rstc); + +	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16; +	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); +} + +static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx) +{ +	u32 val; +	int ret; + +	reset_control_deassert(hdptx->rsts[RST_LANE].rstc); + +	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 | +	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN; +	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); + +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val, +				       (val & HDPTX_O_PHY_RDY) && +				       (val & HDPTX_O_PLL_LOCK_DONE), +				       100, 5000); +	if (ret) { +		dev_err(hdptx->dev, "Failed to get PHY lane lock: %d\n", ret); +		return ret; +	} + +	dev_dbg(hdptx->dev, "PHY lane locked\n"); + +	return 0; +} + +static int rk_hdptx_post_enable_pll(struct rk_hdptx_phy *hdptx) +{ +	u32 val; +	int ret; + +	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 | +	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN; +	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); + +	usleep_range(10, 15); +	reset_control_deassert(hdptx->rsts[RST_INIT].rstc); + +	usleep_range(10, 15); +	val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN; +	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); + +	usleep_range(10, 15); +	reset_control_deassert(hdptx->rsts[RST_CMN].rstc); + +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val, +				       val & HDPTX_O_PHY_CLK_RDY, 20, 400); +	if (ret) { +		dev_err(hdptx->dev, "Failed to get PHY clk ready: %d\n", ret); +		return ret; +	} + +	dev_dbg(hdptx->dev, "PHY clk ready\n"); + +	return 0; +} + +static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx) +{ +	u32 val; + +	/* reset phy and apb, or phy locked flag may keep 1 */ +	reset_control_assert(hdptx->rsts[RST_PHY].rstc); +	usleep_range(20, 30); +	reset_control_deassert(hdptx->rsts[RST_PHY].rstc); + +	reset_control_assert(hdptx->rsts[RST_APB].rstc); +	usleep_range(20, 30); +	reset_control_deassert(hdptx->rsts[RST_APB].rstc); + +	regmap_write(hdptx->regmap, LANE_REG(0300), 0x82); +	regmap_write(hdptx->regmap, SB_REG(010f), 0xc1); +	regmap_write(hdptx->regmap, SB_REG(0110), 0x1); +	regmap_write(hdptx->regmap, LANE_REG(0301), 0x80); +	regmap_write(hdptx->regmap, LANE_REG(0401), 0x80); +	regmap_write(hdptx->regmap, LANE_REG(0501), 0x80); +	regmap_write(hdptx->regmap, LANE_REG(0601), 0x80); + +	reset_control_assert(hdptx->rsts[RST_LANE].rstc); +	reset_control_assert(hdptx->rsts[RST_CMN].rstc); +	reset_control_assert(hdptx->rsts[RST_INIT].rstc); + +	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16; +	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); +} + +static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate, +				      struct ropll_config *cfg) +{ +	const unsigned int fout = data_rate / 2, fref = 24000; +	unsigned long k = 0, lc, k_sub, lc_sub; +	unsigned int fvco, sdc; +	u32 mdiv, sdiv, n = 8; + +	if (fout > 0xfffffff) +		return false; + +	for (sdiv = 16; sdiv >= 1; sdiv--) { +		if (sdiv % 2 && sdiv != 1) +			continue; + +		fvco = fout * sdiv; + +		if (fvco < 2000000 || fvco > 4000000) +			continue; + +		mdiv = DIV_ROUND_UP(fvco, fref); +		if (mdiv < 20 || mdiv > 255) +			continue; + +		if (fref * mdiv - fvco) { +			for (sdc = 264000; sdc <= 750000; sdc += fref) +				if (sdc * n > fref * mdiv) +					break; + +			if (sdc > 750000) +				continue; + +			rational_best_approximation(fref * mdiv - fvco, +						    sdc / 16, +						    GENMASK(6, 0), +						    GENMASK(7, 0), +						    &k, &lc); + +			rational_best_approximation(sdc * n - fref * mdiv, +						    sdc, +						    GENMASK(6, 0), +						    GENMASK(7, 0), +						    &k_sub, &lc_sub); +		} + +		break; +	} + +	if (sdiv < 1) +		return false; + +	if (cfg) { +		cfg->pms_mdiv = mdiv; +		cfg->pms_mdiv_afc = mdiv; +		cfg->pms_pdiv = 1; +		cfg->pms_refdiv = 1; +		cfg->pms_sdiv = sdiv - 1; + +		cfg->sdm_en = k > 0 ? 1 : 0; +		if (cfg->sdm_en) { +			cfg->sdm_deno = lc; +			cfg->sdm_num_sign = 1; +			cfg->sdm_num = k; +			cfg->sdc_n = n - 3; +			cfg->sdc_num = k_sub; +			cfg->sdc_deno = lc_sub; +		} +	} + +	return true; +} + +static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx, +					  unsigned int rate) +{ +	const struct ropll_config *cfg = NULL; +	struct ropll_config rc = {0}; +	int i; + +	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++) +		if (rate == ropll_tmds_cfg[i].bit_rate) { +			cfg = &ropll_tmds_cfg[i]; +			break; +		} + +	if (!cfg) { +		if (rk_hdptx_phy_clk_pll_calc(rate, &rc)) { +			cfg = &rc; +		} else { +			dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__); +			return -EINVAL; +		} +	} + +	dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u, sdm_en=%u, k_sign=%u, k=%u, lc=%u\n", +		cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en, +		cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno); + +	rk_hdptx_pre_power_up(hdptx); + +	reset_control_assert(hdptx->rsts[RST_ROPLL].rstc); +	usleep_range(20, 30); +	reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc); + +	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq); +	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq); + +	regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv); +	regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc); +	regmap_write(hdptx->regmap, CMN_REG(0059), +		     (cfg->pms_pdiv << 4) | cfg->pms_refdiv); +	regmap_write(hdptx->regmap, CMN_REG(005a), cfg->pms_sdiv << 4); + +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK, +			   FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en)); +	if (!cfg->sdm_en) +		regmap_update_bits(hdptx->regmap, CMN_REG(005e), 0xf, 0); + +	regmap_update_bits(hdptx->regmap, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK, +			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign)); + +	regmap_write(hdptx->regmap, CMN_REG(0060), cfg->sdm_deno); +	regmap_write(hdptx->regmap, CMN_REG(0065), cfg->sdm_num); + +	regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK, +			   FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n)); + +	regmap_write(hdptx->regmap, CMN_REG(006c), cfg->sdc_num); +	regmap_write(hdptx->regmap, CMN_REG(0070), cfg->sdc_deno); + +	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK, +			   FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv)); + +	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN, +			   PLL_PCG_CLK_EN); + +	return rk_hdptx_post_enable_pll(hdptx); +} + +static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx, +					   unsigned int rate) +{ +	u32 val; +	int ret; + +	ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val); +	if (ret) +		return ret; + +	if (!(val & HDPTX_O_PLL_LOCK_DONE)) { +		ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate); +		if (ret) +			return ret; +	} + +	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq); + +	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06); + +	if (rate >= 3400000) { +		/* For 1/40 bitrate clk */ +		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq); +	} else { +		/* For 1/10 bitrate clk */ +		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq); +	} + +	regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07); +	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f); + +	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq); +	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq); + +	return rk_hdptx_post_enable_lane(hdptx); +} + +static int rk_hdptx_phy_power_on(struct phy *phy) +{ +	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); +	int ret, bus_width = phy_get_bus_width(hdptx->phy); +	/* +	 * FIXME: Temporary workaround to pass pixel_clk_rate +	 * from the HDMI bridge driver until phy_configure_opts_hdmi +	 * becomes available in the PHY API. +	 */ +	unsigned int rate = bus_width & 0xfffffff; + +	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n", +		__func__, bus_width, rate); + +	ret = pm_runtime_resume_and_get(hdptx->dev); +	if (ret) { +		dev_err(hdptx->dev, "Failed to resume phy: %d\n", ret); +		return ret; +	} + +	ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate); +	if (ret) +		pm_runtime_put(hdptx->dev); + +	return ret; +} + +static int rk_hdptx_phy_power_off(struct phy *phy) +{ +	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); +	u32 val; +	int ret; + +	ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val); +	if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE)) +		rk_hdptx_phy_disable(hdptx); + +	pm_runtime_put(hdptx->dev); + +	return ret; +} + +static const struct phy_ops rk_hdptx_phy_ops = { +	.power_on  = rk_hdptx_phy_power_on, +	.power_off = rk_hdptx_phy_power_off, +	.owner	   = THIS_MODULE, +}; + +static int rk_hdptx_phy_runtime_suspend(struct device *dev) +{ +	struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev); + +	clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks); + +	return 0; +} + +static int rk_hdptx_phy_runtime_resume(struct device *dev) +{ +	struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev); +	int ret; + +	ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks); +	if (ret) +		dev_err(hdptx->dev, "Failed to enable clocks: %d\n", ret); + +	return ret; +} + +static int rk_hdptx_phy_probe(struct platform_device *pdev) +{ +	struct phy_provider *phy_provider; +	struct device *dev = &pdev->dev; +	struct rk_hdptx_phy *hdptx; +	void __iomem *regs; +	int ret; + +	hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL); +	if (!hdptx) +		return -ENOMEM; + +	hdptx->dev = dev; + +	regs = devm_platform_ioremap_resource(pdev, 0); +	if (IS_ERR(regs)) +		return dev_err_probe(dev, PTR_ERR(regs), +				     "Failed to ioremap resource\n"); + +	ret = devm_clk_bulk_get_all(dev, &hdptx->clks); +	if (ret < 0) +		return dev_err_probe(dev, ret, "Failed to get clocks\n"); +	if (ret == 0) +		return dev_err_probe(dev, -EINVAL, "Missing clocks\n"); + +	hdptx->nr_clks = ret; + +	hdptx->regmap = devm_regmap_init_mmio(dev, regs, +					      &rk_hdptx_phy_regmap_config); +	if (IS_ERR(hdptx->regmap)) +		return dev_err_probe(dev, PTR_ERR(hdptx->regmap), +				     "Failed to init regmap\n"); + +	hdptx->rsts[RST_PHY].id = "phy"; +	hdptx->rsts[RST_APB].id = "apb"; +	hdptx->rsts[RST_INIT].id = "init"; +	hdptx->rsts[RST_CMN].id = "cmn"; +	hdptx->rsts[RST_LANE].id = "lane"; +	hdptx->rsts[RST_ROPLL].id = "ropll"; +	hdptx->rsts[RST_LCPLL].id = "lcpll"; + +	ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts); +	if (ret) +		return dev_err_probe(dev, ret, "Failed to get resets\n"); + +	hdptx->grf = syscon_regmap_lookup_by_phandle(dev->of_node, +						     "rockchip,grf"); +	if (IS_ERR(hdptx->grf)) +		return dev_err_probe(dev, PTR_ERR(hdptx->grf), +				     "Could not get GRF syscon\n"); + +	hdptx->phy = devm_phy_create(dev, NULL, &rk_hdptx_phy_ops); +	if (IS_ERR(hdptx->phy)) +		return dev_err_probe(dev, PTR_ERR(hdptx->phy), +				     "Failed to create HDMI PHY\n"); + +	platform_set_drvdata(pdev, hdptx); +	phy_set_drvdata(hdptx->phy, hdptx); +	phy_set_bus_width(hdptx->phy, 8); + +	ret = devm_pm_runtime_enable(dev); +	if (ret) +		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); + +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); +	if (IS_ERR(phy_provider)) +		return dev_err_probe(dev, PTR_ERR(phy_provider), +				     "Failed to register PHY provider\n"); + +	reset_control_deassert(hdptx->rsts[RST_APB].rstc); +	reset_control_deassert(hdptx->rsts[RST_CMN].rstc); +	reset_control_deassert(hdptx->rsts[RST_INIT].rstc); + +	return 0; +} + +static const struct dev_pm_ops rk_hdptx_phy_pm_ops = { +	RUNTIME_PM_OPS(rk_hdptx_phy_runtime_suspend, +		       rk_hdptx_phy_runtime_resume, NULL) +}; + +static const struct of_device_id rk_hdptx_phy_of_match[] = { +	{ .compatible = "rockchip,rk3588-hdptx-phy", }, +	{} +}; +MODULE_DEVICE_TABLE(of, rk_hdptx_phy_of_match); + +static struct platform_driver rk_hdptx_phy_driver = { +	.probe  = rk_hdptx_phy_probe, +	.driver = { +		.name = "rockchip-hdptx-phy", +		.pm = &rk_hdptx_phy_pm_ops, +		.of_match_table = rk_hdptx_phy_of_match, +	}, +}; +module_platform_driver(rk_hdptx_phy_driver); + +MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>"); +MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>"); +MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/samsung/phy-exynos-mipi-video.c b/drivers/phy/samsung/phy-exynos-mipi-video.c index 592d8067e848..f6756a609a9a 100644 --- a/drivers/phy/samsung/phy-exynos-mipi-video.c +++ b/drivers/phy/samsung/phy-exynos-mipi-video.c @@ -274,7 +274,7 @@ static int exynos_mipi_video_phy_power_off(struct phy *phy)  }  static struct phy *exynos_mipi_video_phy_xlate(struct device *dev, -					struct of_phandle_args *args) +					const struct of_phandle_args *args)  {  	struct exynos_mipi_video_phy *state = dev_get_drvdata(dev); diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 3f310b28bfff..04171eed5b16 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -715,7 +715,7 @@ static int exynos5420_usbdrd_phy_calibrate(struct exynos5_usbdrd_phy *phy_drd)  }  static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev, -					struct of_phandle_args *args) +					const struct of_phandle_args *args)  {  	struct exynos5_usbdrd_phy *phy_drd = dev_get_drvdata(dev); diff --git a/drivers/phy/samsung/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c index 68a174eca0ba..9de744cd6f39 100644 --- a/drivers/phy/samsung/phy-samsung-usb2.c +++ b/drivers/phy/samsung/phy-samsung-usb2.c @@ -87,7 +87,7 @@ static const struct phy_ops samsung_usb2_phy_ops = {  };  static struct phy *samsung_usb2_phy_xlate(struct device *dev, -					struct of_phandle_args *args) +					const struct of_phandle_args *args)  {  	struct samsung_usb2_phy_driver *drv; diff --git a/drivers/phy/socionext/phy-uniphier-usb2.c b/drivers/phy/socionext/phy-uniphier-usb2.c index 3f2086ed4fe4..21c201717d95 100644 --- a/drivers/phy/socionext/phy-uniphier-usb2.c +++ b/drivers/phy/socionext/phy-uniphier-usb2.c @@ -81,7 +81,7 @@ static int uniphier_u2phy_init(struct phy *phy)  }  static struct phy *uniphier_u2phy_xlate(struct device *dev, -					struct of_phandle_args *args) +					const struct of_phandle_args *args)  {  	struct uniphier_u2phy_priv *priv = dev_get_drvdata(dev); diff --git a/drivers/phy/st/phy-miphy28lp.c b/drivers/phy/st/phy-miphy28lp.c index e30305b77f0d..063fc38788ed 100644 --- a/drivers/phy/st/phy-miphy28lp.c +++ b/drivers/phy/st/phy-miphy28lp.c @@ -1074,7 +1074,7 @@ static int miphy28lp_get_addr(struct miphy28lp_phy *miphy_phy)  }  static struct phy *miphy28lp_xlate(struct device *dev, -				   struct of_phandle_args *args) +				   const struct of_phandle_args *args)  {  	struct miphy28lp_dev *miphy_dev = dev_get_drvdata(dev);  	struct miphy28lp_phy *miphy_phy = NULL; diff --git a/drivers/phy/st/phy-spear1310-miphy.c b/drivers/phy/st/phy-spear1310-miphy.c index 35a9831b5161..c661ab63505f 100644 --- a/drivers/phy/st/phy-spear1310-miphy.c +++ b/drivers/phy/st/phy-spear1310-miphy.c @@ -183,7 +183,7 @@ static const struct phy_ops spear1310_miphy_ops = {  };  static struct phy *spear1310_miphy_xlate(struct device *dev, -					 struct of_phandle_args *args) +					 const struct of_phandle_args *args)  {  	struct spear1310_miphy_priv *priv = dev_get_drvdata(dev); diff --git a/drivers/phy/st/phy-spear1340-miphy.c b/drivers/phy/st/phy-spear1340-miphy.c index 34a1cf21015f..85a60d64ebb7 100644 --- a/drivers/phy/st/phy-spear1340-miphy.c +++ b/drivers/phy/st/phy-spear1340-miphy.c @@ -220,7 +220,7 @@ static SIMPLE_DEV_PM_OPS(spear1340_miphy_pm_ops, spear1340_miphy_suspend,  			 spear1340_miphy_resume);  static struct phy *spear1340_miphy_xlate(struct device *dev, -					 struct of_phandle_args *args) +					 const struct of_phandle_args *args)  {  	struct spear1340_miphy_priv *priv = dev_get_drvdata(dev); diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index d5e7e44000b5..9dbe60dcf319 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -574,7 +574,7 @@ static void stm32_usbphyc_switch_setup(struct stm32_usbphyc *usbphyc,  }  static struct phy *stm32_usbphyc_of_xlate(struct device *dev, -					  struct of_phandle_args *args) +					  const struct of_phandle_args *args)  {  	struct stm32_usbphyc *usbphyc = dev_get_drvdata(dev);  	struct stm32_usbphyc_phy *usbphyc_phy = NULL; diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 142ebe0247cc..0dc86a7740e3 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -22,7 +22,7 @@  #include "xusb.h"  static struct phy *tegra_xusb_pad_of_xlate(struct device *dev, -					   struct of_phandle_args *args) +					   const struct of_phandle_args *args)  {  	struct tegra_xusb_pad *pad = dev_get_drvdata(dev);  	struct phy *phy = NULL; diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c index 3f1d43e8b7ad..8b3b937de624 100644 --- a/drivers/phy/ti/phy-am654-serdes.c +++ b/drivers/phy/ti/phy-am654-serdes.c @@ -495,7 +495,7 @@ static void serdes_am654_release(struct phy *x)  }  static struct phy *serdes_am654_xlate(struct device *dev, -				      struct of_phandle_args *args) +				      const struct of_phandle_args *args)  {  	struct serdes_am654 *am654_phy;  	struct phy *phy; diff --git a/drivers/phy/ti/phy-da8xx-usb.c b/drivers/phy/ti/phy-da8xx-usb.c index b7a9ef3f4654..0fe577f0d6c1 100644 --- a/drivers/phy/ti/phy-da8xx-usb.c +++ b/drivers/phy/ti/phy-da8xx-usb.c @@ -119,7 +119,7 @@ static const struct phy_ops da8xx_usb20_phy_ops = {  };  static struct phy *da8xx_usb_phy_of_xlate(struct device *dev, -					 struct of_phandle_args *args) +					 const struct of_phandle_args *args)  {  	struct da8xx_usb_phy *d_phy = dev_get_drvdata(dev); diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c index 0f4818adb440..b30bf740e2e0 100644 --- a/drivers/phy/ti/phy-gmii-sel.c +++ b/drivers/phy/ti/phy-gmii-sel.c @@ -297,7 +297,7 @@ static const struct phy_ops phy_gmii_sel_ops = {  };  static struct phy *phy_gmii_sel_of_xlate(struct device *dev, -					 struct of_phandle_args *args) +					 const struct of_phandle_args *args)  {  	struct phy_gmii_sel_priv *priv = dev_get_drvdata(dev);  	int phy_id = args->args[0]; @@ -494,11 +494,35 @@ static int phy_gmii_sel_probe(struct platform_device *pdev)  	return 0;  } +static int phy_gmii_sel_resume_noirq(struct device *dev) +{ +	struct phy_gmii_sel_priv *priv = dev_get_drvdata(dev); +	struct phy_gmii_sel_phy_priv *if_phys = priv->if_phys; +	int ret, i; + +	for (i = 0; i < priv->num_ports; i++) { +		if (if_phys[i].phy_if_mode) { +			ret = phy_gmii_sel_mode(if_phys[i].if_phy, +						PHY_MODE_ETHERNET, if_phys[i].phy_if_mode); +			if (ret) { +				dev_err(dev, "port%u: restore mode fail %d\n", +					if_phys[i].if_phy->id, ret); +				return ret; +			} +		} +	} + +	return 0; +} + +static DEFINE_NOIRQ_DEV_PM_OPS(phy_gmii_sel_pm_ops, NULL, phy_gmii_sel_resume_noirq); +  static struct platform_driver phy_gmii_sel_driver = {  	.probe		= phy_gmii_sel_probe,  	.driver		= {  		.name	= "phy-gmii-sel",  		.of_match_table = phy_gmii_sel_id_table, +		.pm = pm_sleep_ptr(&phy_gmii_sel_pm_ops),  	},  };  module_platform_driver(phy_gmii_sel_driver); diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c index b4881cb34475..13cd614e12a1 100644 --- a/drivers/phy/ti/phy-tusb1210.c +++ b/drivers/phy/ti/phy-tusb1210.c @@ -17,6 +17,10 @@  #include <linux/property.h>  #include <linux/workqueue.h> +#define TI_VENDOR_ID		0x0451 +#define TI_DEVICE_TUSB1210	0x1507 +#define TI_DEVICE_TUSB1211	0x1508 +  #define TUSB1211_POWER_CONTROL				0x3d  #define TUSB1211_POWER_CONTROL_SET			0x3e  #define TUSB1211_POWER_CONTROL_CLEAR			0x3f @@ -52,7 +56,7 @@ enum tusb1210_chg_det_state {  };  struct tusb1210 { -	struct ulpi *ulpi; +	struct device *dev;  	struct phy *phy;  	struct gpio_desc *gpio_reset;  	struct gpio_desc *gpio_cs; @@ -71,26 +75,27 @@ struct tusb1210 {  static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)  { +	struct device *dev = tusb->dev;  	int ret; -	ret = ulpi_write(tusb->ulpi, reg, val); +	ret = ulpi_write(to_ulpi_dev(dev), reg, val);  	if (ret) -		dev_err(&tusb->ulpi->dev, "error %d writing val 0x%02x to reg 0x%02x\n", -			ret, val, reg); +		dev_err(dev, "error %d writing val 0x%02x to reg 0x%02x\n", ret, val, reg);  	return ret;  }  static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val)  { +	struct device *dev = tusb->dev;  	int ret; -	ret = ulpi_read(tusb->ulpi, reg); +	ret = ulpi_read(to_ulpi_dev(dev), reg);  	if (ret >= 0) {  		*val = ret;  		ret = 0;  	} else { -		dev_err(&tusb->ulpi->dev, "error %d reading reg 0x%02x\n", ret, reg); +		dev_err(dev, "error %d reading reg 0x%02x\n", ret, reg);  	}  	return ret; @@ -178,7 +183,7 @@ static void tusb1210_reset(struct tusb1210 *tusb)  static void tusb1210_chg_det_set_type(struct tusb1210 *tusb,  				      enum power_supply_usb_type type)  { -	dev_dbg(&tusb->ulpi->dev, "charger type: %d\n", type); +	dev_dbg(tusb->dev, "charger type: %d\n", type);  	tusb->chg_type = type;  	tusb->chg_det_retries = 0;  	power_supply_changed(tusb->psy); @@ -189,7 +194,7 @@ static void tusb1210_chg_det_set_state(struct tusb1210 *tusb,  				       int delay_ms)  {  	if (delay_ms) -		dev_dbg(&tusb->ulpi->dev, "chg_det new state %s in %d ms\n", +		dev_dbg(tusb->dev, "chg_det new state %s in %d ms\n",  			tusb1210_chg_det_states[new_state], delay_ms);  	tusb->chg_det_state = new_state; @@ -253,7 +258,7 @@ static void tusb1210_chg_det_work(struct work_struct *work)  	int ret;  	u8 val; -	dev_dbg(&tusb->ulpi->dev, "chg_det state %s vbus_present %d\n", +	dev_dbg(tusb->dev, "chg_det state %s vbus_present %d\n",  		tusb1210_chg_det_states[tusb->chg_det_state], vbus_present);  	switch (tusb->chg_det_state) { @@ -261,9 +266,9 @@ static void tusb1210_chg_det_work(struct work_struct *work)  		tusb->chg_type = POWER_SUPPLY_USB_TYPE_UNKNOWN;  		tusb->chg_det_retries = 0;  		/* Power on USB controller for ulpi_read()/_write() */ -		ret = pm_runtime_resume_and_get(tusb->ulpi->dev.parent); +		ret = pm_runtime_resume_and_get(tusb->dev->parent);  		if (ret < 0) { -			dev_err(&tusb->ulpi->dev, "error %d runtime-resuming\n", ret); +			dev_err(tusb->dev, "error %d runtime-resuming\n", ret);  			/* Should never happen, skip charger detection */  			tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);  			return; @@ -332,7 +337,7 @@ static void tusb1210_chg_det_work(struct work_struct *work)  		mutex_unlock(&tusb->phy->mutex); -		pm_runtime_put(tusb->ulpi->dev.parent); +		pm_runtime_put(tusb->dev->parent);  		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);  		break;  	case TUSB1210_CHG_DET_CONNECTED: @@ -428,13 +433,14 @@ static const struct power_supply_desc tusb1210_psy_desc = {  static void tusb1210_probe_charger_detect(struct tusb1210 *tusb)  {  	struct power_supply_config psy_cfg = { .drv_data = tusb }; -	struct device *dev = &tusb->ulpi->dev; +	struct device *dev = tusb->dev; +	struct ulpi *ulpi = to_ulpi_dev(dev);  	int ret;  	if (!device_property_read_bool(dev->parent, "linux,phy_charger_detect"))  		return; -	if (tusb->ulpi->id.product != 0x1508) { +	if (ulpi->id.product != TI_DEVICE_TUSB1211) {  		dev_err(dev, "error charger detection is only supported on the TUSB1211\n");  		return;  	} @@ -485,25 +491,24 @@ static const struct phy_ops phy_ops = {  static int tusb1210_probe(struct ulpi *ulpi)  { +	struct device *dev = &ulpi->dev;  	struct tusb1210 *tusb;  	u8 val, reg;  	int ret; -	tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL); +	tusb = devm_kzalloc(dev, sizeof(*tusb), GFP_KERNEL);  	if (!tusb)  		return -ENOMEM; -	tusb->ulpi = ulpi; +	tusb->dev = dev; -	tusb->gpio_reset = devm_gpiod_get_optional(&ulpi->dev, "reset", -						   GPIOD_OUT_LOW); +	tusb->gpio_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);  	if (IS_ERR(tusb->gpio_reset))  		return PTR_ERR(tusb->gpio_reset);  	gpiod_set_value_cansleep(tusb->gpio_reset, 1); -	tusb->gpio_cs = devm_gpiod_get_optional(&ulpi->dev, "cs", -						GPIOD_OUT_LOW); +	tusb->gpio_cs = devm_gpiod_get_optional(dev, "cs", GPIOD_OUT_LOW);  	if (IS_ERR(tusb->gpio_cs))  		return PTR_ERR(tusb->gpio_cs); @@ -519,15 +524,15 @@ static int tusb1210_probe(struct ulpi *ulpi)  		return ret;  	/* High speed output drive strength configuration */ -	if (!device_property_read_u8(&ulpi->dev, "ihstx", &val)) +	if (!device_property_read_u8(dev, "ihstx", &val))  		u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK);  	/* High speed output impedance configuration */ -	if (!device_property_read_u8(&ulpi->dev, "zhsdrv", &val)) +	if (!device_property_read_u8(dev, "zhsdrv", &val))  		u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK);  	/* DP/DM swap control */ -	if (!device_property_read_u8(&ulpi->dev, "datapolarity", &val)) +	if (!device_property_read_u8(dev, "datapolarity", &val))  		u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK);  	ret = tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, reg); @@ -561,11 +566,9 @@ static void tusb1210_remove(struct ulpi *ulpi)  	tusb1210_remove_charger_detect(tusb);  } -#define TI_VENDOR_ID 0x0451 -  static const struct ulpi_device_id tusb1210_ulpi_id[] = { -	{ TI_VENDOR_ID, 0x1507, },  /* TUSB1210 */ -	{ TI_VENDOR_ID, 0x1508, },  /* TUSB1211 */ +	{ TI_VENDOR_ID, TI_DEVICE_TUSB1210 }, +	{ TI_VENDOR_ID, TI_DEVICE_TUSB1211 },  	{ },  };  MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id); diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c index 2559c6594cea..f72c5257d712 100644 --- a/drivers/phy/xilinx/phy-zynqmp.c +++ b/drivers/phy/xilinx/phy-zynqmp.c @@ -768,7 +768,7 @@ static const unsigned int icm_matrix[NUM_LANES][CONTROLLERS_PER_LANE] = {  /* Translate OF phandle and args to PHY instance. */  static struct phy *xpsgtr_xlate(struct device *dev, -				struct of_phandle_args *args) +				const struct of_phandle_args *args)  {  	struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev);  	struct xpsgtr_phy *gtr_phy; diff --git a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c index 7641848be4de..96ef57a7d385 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c @@ -685,7 +685,7 @@ static const struct phy_ops sata_phy_ops = {  };  static struct phy *tegra_xusb_padctl_xlate(struct device *dev, -					   struct of_phandle_args *args) +					   const struct of_phandle_args *args)  {  	struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev);  	unsigned int index = args->args[0];  | 
