xref: /openbmc/linux/drivers/phy/cadence/phy-cadence-torrent.c (revision 29d1fd2f2cc6a112abf93bca23a6852b6f1f112d)
1c589e701SYuti Amonkar // SPDX-License-Identifier: GPL-2.0-only
2c589e701SYuti Amonkar /*
392e9ccc6SSwapnil Jakhade  * Cadence Torrent SD0801 PHY driver.
4c589e701SYuti Amonkar  *
5c589e701SYuti Amonkar  * Copyright 2018 Cadence Design Systems, Inc.
6c589e701SYuti Amonkar  *
7c589e701SYuti Amonkar  */
8c589e701SYuti Amonkar 
9afa4ba05SSwapnil Jakhade #include <dt-bindings/phy/phy.h>
10e4b496a3SSwapnil Jakhade #include <linux/clk.h>
11c589e701SYuti Amonkar #include <linux/delay.h>
12c589e701SYuti Amonkar #include <linux/err.h>
13c589e701SYuti Amonkar #include <linux/io.h>
14c589e701SYuti Amonkar #include <linux/iopoll.h>
15c589e701SYuti Amonkar #include <linux/kernel.h>
16c589e701SYuti Amonkar #include <linux/module.h>
17c589e701SYuti Amonkar #include <linux/of.h>
18c589e701SYuti Amonkar #include <linux/of_address.h>
19c589e701SYuti Amonkar #include <linux/of_device.h>
20c589e701SYuti Amonkar #include <linux/phy/phy.h>
21c589e701SYuti Amonkar #include <linux/platform_device.h>
22afa4ba05SSwapnil Jakhade #include <linux/reset.h>
2369d114acSSwapnil Jakhade #include <linux/regmap.h>
24c589e701SYuti Amonkar 
25e4b496a3SSwapnil Jakhade #define REF_CLK_19_2MHz		19200000
26e4b496a3SSwapnil Jakhade #define REF_CLK_25MHz		25000000
27e4b496a3SSwapnil Jakhade 
28e4b496a3SSwapnil Jakhade #define DEFAULT_NUM_LANES	4
29c589e701SYuti Amonkar #define MAX_NUM_LANES		4
30c589e701SYuti Amonkar #define DEFAULT_MAX_BIT_RATE	8100 /* in Mbps */
31c589e701SYuti Amonkar 
3221c79146SSwapnil Jakhade #define POLL_TIMEOUT_US		5000
3369d114acSSwapnil Jakhade 
3469d114acSSwapnil Jakhade #define TORRENT_COMMON_CDB_OFFSET	0x0
3569d114acSSwapnil Jakhade 
3669d114acSSwapnil Jakhade #define TORRENT_TX_LANE_CDB_OFFSET(ln, block_offset, reg_offset)	\
3769d114acSSwapnil Jakhade 				((0x4000 << (block_offset)) +		\
3869d114acSSwapnil Jakhade 				(((ln) << 9) << (reg_offset)))
3969d114acSSwapnil Jakhade 
4069d114acSSwapnil Jakhade #define TORRENT_RX_LANE_CDB_OFFSET(ln, block_offset, reg_offset)	\
4169d114acSSwapnil Jakhade 				((0x8000 << (block_offset)) +		\
4269d114acSSwapnil Jakhade 				(((ln) << 9) << (reg_offset)))
4369d114acSSwapnil Jakhade 
4469d114acSSwapnil Jakhade #define TORRENT_PHY_PCS_COMMON_OFFSET(block_offset)	\
4569d114acSSwapnil Jakhade 				(0xC000 << (block_offset))
4669d114acSSwapnil Jakhade 
4769d114acSSwapnil Jakhade #define TORRENT_PHY_PMA_COMMON_OFFSET(block_offset)	\
4869d114acSSwapnil Jakhade 				(0xE000 << (block_offset))
49c589e701SYuti Amonkar 
50cba472ecSSwapnil Jakhade #define TORRENT_DPTX_PHY_OFFSET		0x0
51cba472ecSSwapnil Jakhade 
52c589e701SYuti Amonkar /*
53c589e701SYuti Amonkar  * register offsets from DPTX PHY register block base (i.e MHDP
54c589e701SYuti Amonkar  * register base + 0x30a00)
55c589e701SYuti Amonkar  */
56c589e701SYuti Amonkar #define PHY_AUX_CTRL			0x04
57c589e701SYuti Amonkar #define PHY_RESET			0x20
58572d6592SSwapnil Jakhade #define PMA_TX_ELEC_IDLE_MASK		0xF0U
59572d6592SSwapnil Jakhade #define PMA_TX_ELEC_IDLE_SHIFT		4
60572d6592SSwapnil Jakhade #define PHY_L00_RESET_N_MASK		0x01U
61c589e701SYuti Amonkar #define PHY_PMA_XCVR_PLLCLK_EN		0x24
62c589e701SYuti Amonkar #define PHY_PMA_XCVR_PLLCLK_EN_ACK	0x28
63c589e701SYuti Amonkar #define PHY_PMA_XCVR_POWER_STATE_REQ	0x2c
64c589e701SYuti Amonkar #define PHY_POWER_STATE_LN_0	0x0000
65c589e701SYuti Amonkar #define PHY_POWER_STATE_LN_1	0x0008
66c589e701SYuti Amonkar #define PHY_POWER_STATE_LN_2	0x0010
67c589e701SYuti Amonkar #define PHY_POWER_STATE_LN_3	0x0018
6821c79146SSwapnil Jakhade #define PMA_XCVR_POWER_STATE_REQ_LN_MASK	0x3FU
69c589e701SYuti Amonkar #define PHY_PMA_XCVR_POWER_STATE_ACK	0x30
70c589e701SYuti Amonkar #define PHY_PMA_CMN_READY		0x34
71c589e701SYuti Amonkar 
72c589e701SYuti Amonkar /*
73c589e701SYuti Amonkar  * register offsets from SD0801 PHY register block base (i.e MHDP
74c589e701SYuti Amonkar  * register base + 0x500000)
75c589e701SYuti Amonkar  */
7669d114acSSwapnil Jakhade #define CMN_SSM_BANDGAP_TMR		0x0021U
7769d114acSSwapnil Jakhade #define CMN_SSM_BIAS_TMR		0x0022U
7869d114acSSwapnil Jakhade #define CMN_PLLSM0_PLLPRE_TMR		0x002AU
7969d114acSSwapnil Jakhade #define CMN_PLLSM0_PLLLOCK_TMR		0x002CU
8069d114acSSwapnil Jakhade #define CMN_PLLSM1_PLLPRE_TMR		0x0032U
8169d114acSSwapnil Jakhade #define CMN_PLLSM1_PLLLOCK_TMR		0x0034U
8269d114acSSwapnil Jakhade #define CMN_BGCAL_INIT_TMR		0x0064U
8369d114acSSwapnil Jakhade #define CMN_BGCAL_ITER_TMR		0x0065U
8469d114acSSwapnil Jakhade #define CMN_IBCAL_INIT_TMR		0x0074U
8569d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_TCTRL		0x0082U
8669d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_INIT_TMR	0x0084U
8769d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_ITER_TMR	0x0085U
8869d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_REFTIM_START	0x0086U
8969d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_PLLCNT_START	0x0088U
9069d114acSSwapnil Jakhade #define CMN_PLL0_INTDIV_M0		0x0090U
9169d114acSSwapnil Jakhade #define CMN_PLL0_FRACDIVL_M0		0x0091U
9269d114acSSwapnil Jakhade #define CMN_PLL0_FRACDIVH_M0		0x0092U
9369d114acSSwapnil Jakhade #define CMN_PLL0_HIGH_THR_M0		0x0093U
9469d114acSSwapnil Jakhade #define CMN_PLL0_DSM_DIAG_M0		0x0094U
9569d114acSSwapnil Jakhade #define CMN_PLL0_SS_CTRL1_M0		0x0098U
9669d114acSSwapnil Jakhade #define CMN_PLL0_SS_CTRL2_M0            0x0099U
9769d114acSSwapnil Jakhade #define CMN_PLL0_SS_CTRL3_M0            0x009AU
9869d114acSSwapnil Jakhade #define CMN_PLL0_SS_CTRL4_M0            0x009BU
9969d114acSSwapnil Jakhade #define CMN_PLL0_LOCK_REFCNT_START      0x009CU
10069d114acSSwapnil Jakhade #define CMN_PLL0_LOCK_PLLCNT_START	0x009EU
10169d114acSSwapnil Jakhade #define CMN_PLL0_LOCK_PLLCNT_THR        0x009FU
10269d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_TCTRL		0x00C2U
10369d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_INIT_TMR	0x00C4U
10469d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_ITER_TMR	0x00C5U
10569d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_REFTIM_START	0x00C6U
10669d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_PLLCNT_START	0x00C8U
10769d114acSSwapnil Jakhade #define CMN_PLL1_INTDIV_M0		0x00D0U
10869d114acSSwapnil Jakhade #define CMN_PLL1_FRACDIVL_M0		0x00D1U
10969d114acSSwapnil Jakhade #define CMN_PLL1_FRACDIVH_M0		0x00D2U
11069d114acSSwapnil Jakhade #define CMN_PLL1_HIGH_THR_M0		0x00D3U
11169d114acSSwapnil Jakhade #define CMN_PLL1_DSM_DIAG_M0		0x00D4U
11269d114acSSwapnil Jakhade #define CMN_PLL1_SS_CTRL1_M0		0x00D8U
11369d114acSSwapnil Jakhade #define CMN_PLL1_SS_CTRL2_M0            0x00D9U
11469d114acSSwapnil Jakhade #define CMN_PLL1_SS_CTRL3_M0            0x00DAU
11569d114acSSwapnil Jakhade #define CMN_PLL1_SS_CTRL4_M0            0x00DBU
11669d114acSSwapnil Jakhade #define CMN_PLL1_LOCK_REFCNT_START      0x00DCU
11769d114acSSwapnil Jakhade #define CMN_PLL1_LOCK_PLLCNT_START	0x00DEU
11869d114acSSwapnil Jakhade #define CMN_PLL1_LOCK_PLLCNT_THR        0x00DFU
11969d114acSSwapnil Jakhade #define CMN_TXPUCAL_INIT_TMR		0x0104U
12069d114acSSwapnil Jakhade #define CMN_TXPUCAL_ITER_TMR		0x0105U
12169d114acSSwapnil Jakhade #define CMN_TXPDCAL_INIT_TMR		0x010CU
12269d114acSSwapnil Jakhade #define CMN_TXPDCAL_ITER_TMR		0x010DU
12369d114acSSwapnil Jakhade #define CMN_RXCAL_INIT_TMR		0x0114U
12469d114acSSwapnil Jakhade #define CMN_RXCAL_ITER_TMR		0x0115U
12569d114acSSwapnil Jakhade #define CMN_SD_CAL_INIT_TMR		0x0124U
12669d114acSSwapnil Jakhade #define CMN_SD_CAL_ITER_TMR		0x0125U
12769d114acSSwapnil Jakhade #define CMN_SD_CAL_REFTIM_START		0x0126U
12869d114acSSwapnil Jakhade #define CMN_SD_CAL_PLLCNT_START		0x0128U
12969d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CTRL_M0		0x01A0U
13069d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CLK_SEL_M0	0x01A1U
13169d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CP_PADJ_M0	0x01A4U
13269d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CP_IADJ_M0	0x01A5U
13369d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_FILT_PADJ_M0	0x01A6U
13469d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CP_PADJ_M1	0x01B4U
13569d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CP_IADJ_M1	0x01B5U
13669d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_CTRL_M0		0x01C0U
13769d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_CLK_SEL_M0	0x01C1U
13869d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_CP_PADJ_M0	0x01C4U
13969d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_CP_IADJ_M0	0x01C5U
14069d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_FILT_PADJ_M0	0x01C6U
141e4b496a3SSwapnil Jakhade 
14269d114acSSwapnil Jakhade /* PMA TX Lane registers */
14369d114acSSwapnil Jakhade #define TX_TXCC_CTRL			0x0040U
14469d114acSSwapnil Jakhade #define TX_TXCC_CPOST_MULT_00		0x004CU
14569d114acSSwapnil Jakhade #define TX_TXCC_MGNFS_MULT_000		0x0050U
14669d114acSSwapnil Jakhade #define DRV_DIAG_TX_DRV			0x00C6U
14769d114acSSwapnil Jakhade #define XCVR_DIAG_PLLDRC_CTRL		0x00E5U
14869d114acSSwapnil Jakhade #define XCVR_DIAG_HSCLK_SEL		0x00E6U
14969d114acSSwapnil Jakhade #define XCVR_DIAG_HSCLK_DIV		0x00E7U
15069d114acSSwapnil Jakhade #define XCVR_DIAG_BIDI_CTRL		0x00EAU
15169d114acSSwapnil Jakhade #define TX_PSC_A0			0x0100U
15269d114acSSwapnil Jakhade #define TX_PSC_A2			0x0102U
15369d114acSSwapnil Jakhade #define TX_PSC_A3			0x0103U
15469d114acSSwapnil Jakhade #define TX_RCVDET_ST_TMR		0x0123U
15569d114acSSwapnil Jakhade #define TX_DIAG_ACYA			0x01E7U
156572d6592SSwapnil Jakhade #define TX_DIAG_ACYA_HBDC_MASK		0x0001U
157e4b496a3SSwapnil Jakhade 
15869d114acSSwapnil Jakhade /* PMA RX Lane registers */
15969d114acSSwapnil Jakhade #define RX_PSC_A0			0x0000U
16069d114acSSwapnil Jakhade #define RX_PSC_A2			0x0002U
16169d114acSSwapnil Jakhade #define RX_PSC_A3			0x0003U
16269d114acSSwapnil Jakhade #define RX_PSC_CAL			0x0006U
16369d114acSSwapnil Jakhade #define RX_REE_GCSM1_CTRL		0x0108U
16469d114acSSwapnil Jakhade #define RX_REE_GCSM2_CTRL		0x0110U
16569d114acSSwapnil Jakhade #define RX_REE_PERGCSM_CTRL		0x0118U
166c589e701SYuti Amonkar 
16769d114acSSwapnil Jakhade /* PHY PCS common registers */
16869d114acSSwapnil Jakhade #define PHY_PLL_CFG			0x000EU
16969d114acSSwapnil Jakhade 
17069d114acSSwapnil Jakhade /* PHY PMA common registers */
17169d114acSSwapnil Jakhade #define PHY_PMA_CMN_CTRL2		0x0001U
17269d114acSSwapnil Jakhade #define PHY_PMA_PLL_RAW_CTRL		0x0003U
17369d114acSSwapnil Jakhade 
17469d114acSSwapnil Jakhade static const struct reg_field phy_pll_cfg =
17569d114acSSwapnil Jakhade 				REG_FIELD(PHY_PLL_CFG, 0, 1);
17669d114acSSwapnil Jakhade 
17769d114acSSwapnil Jakhade static const struct reg_field phy_pma_cmn_ctrl_2 =
17869d114acSSwapnil Jakhade 				REG_FIELD(PHY_PMA_CMN_CTRL2, 0, 7);
17969d114acSSwapnil Jakhade 
18069d114acSSwapnil Jakhade static const struct reg_field phy_pma_pll_raw_ctrl =
18169d114acSSwapnil Jakhade 				REG_FIELD(PHY_PMA_PLL_RAW_CTRL, 0, 1);
18269d114acSSwapnil Jakhade 
183cba472ecSSwapnil Jakhade static const struct reg_field phy_reset_ctrl =
184cba472ecSSwapnil Jakhade 				REG_FIELD(PHY_RESET, 8, 8);
185cba472ecSSwapnil Jakhade 
186afa4ba05SSwapnil Jakhade struct cdns_torrent_inst {
187afa4ba05SSwapnil Jakhade 	struct phy *phy;
188afa4ba05SSwapnil Jakhade 	u32 mlane;
189afa4ba05SSwapnil Jakhade 	u32 phy_type;
190afa4ba05SSwapnil Jakhade 	u32 num_lanes;
191afa4ba05SSwapnil Jakhade 	struct reset_control *lnk_rst;
192afa4ba05SSwapnil Jakhade };
193afa4ba05SSwapnil Jakhade 
19492e9ccc6SSwapnil Jakhade struct cdns_torrent_phy {
195c589e701SYuti Amonkar 	void __iomem *base;	/* DPTX registers base */
196c589e701SYuti Amonkar 	void __iomem *sd_base; /* SD0801 registers base */
197c589e701SYuti Amonkar 	u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */
198afa4ba05SSwapnil Jakhade 	struct reset_control *phy_rst;
199c589e701SYuti Amonkar 	struct device *dev;
200e4b496a3SSwapnil Jakhade 	struct clk *clk;
201e4b496a3SSwapnil Jakhade 	unsigned long ref_clk_rate;
202afa4ba05SSwapnil Jakhade 	struct cdns_torrent_inst phys[MAX_NUM_LANES];
203afa4ba05SSwapnil Jakhade 	int nsubnodes;
204*29d1fd2fSSwapnil Jakhade 	const struct cdns_torrent_data *init_data;
20569d114acSSwapnil Jakhade 	struct regmap *regmap;
20669d114acSSwapnil Jakhade 	struct regmap *regmap_common_cdb;
20769d114acSSwapnil Jakhade 	struct regmap *regmap_phy_pcs_common_cdb;
20869d114acSSwapnil Jakhade 	struct regmap *regmap_phy_pma_common_cdb;
20969d114acSSwapnil Jakhade 	struct regmap *regmap_tx_lane_cdb[MAX_NUM_LANES];
21069d114acSSwapnil Jakhade 	struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES];
211cba472ecSSwapnil Jakhade 	struct regmap *regmap_dptx_phy_reg;
21269d114acSSwapnil Jakhade 	struct regmap_field *phy_pll_cfg;
21369d114acSSwapnil Jakhade 	struct regmap_field *phy_pma_cmn_ctrl_2;
21469d114acSSwapnil Jakhade 	struct regmap_field *phy_pma_pll_raw_ctrl;
215cba472ecSSwapnil Jakhade 	struct regmap_field *phy_reset_ctrl;
216c589e701SYuti Amonkar };
217c589e701SYuti Amonkar 
21821c79146SSwapnil Jakhade enum phy_powerstate {
21921c79146SSwapnil Jakhade 	POWERSTATE_A0 = 0,
22021c79146SSwapnil Jakhade 	/* Powerstate A1 is unused */
22121c79146SSwapnil Jakhade 	POWERSTATE_A2 = 2,
22221c79146SSwapnil Jakhade 	POWERSTATE_A3 = 3,
22321c79146SSwapnil Jakhade };
22421c79146SSwapnil Jakhade 
22592e9ccc6SSwapnil Jakhade static int cdns_torrent_dp_init(struct phy *phy);
226e4b496a3SSwapnil Jakhade static int cdns_torrent_dp_exit(struct phy *phy);
227572d6592SSwapnil Jakhade static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
228572d6592SSwapnil Jakhade 			       u32 num_lanes);
22992e9ccc6SSwapnil Jakhade static
23021c79146SSwapnil Jakhade int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy);
231afa4ba05SSwapnil Jakhade static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy,
232afa4ba05SSwapnil Jakhade 				    struct cdns_torrent_inst *inst);
23392e9ccc6SSwapnil Jakhade static
234e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy);
235e4b496a3SSwapnil Jakhade static
236e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
237e4b496a3SSwapnil Jakhade 					     u32 rate, bool ssc);
238e4b496a3SSwapnil Jakhade static
23992e9ccc6SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy);
240e4b496a3SSwapnil Jakhade static
241e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
242e4b496a3SSwapnil Jakhade 					   u32 rate, bool ssc);
24392e9ccc6SSwapnil Jakhade static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
244c589e701SYuti Amonkar 					 unsigned int lane);
245e4b496a3SSwapnil Jakhade static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
246e4b496a3SSwapnil Jakhade 					 u32 rate, u32 num_lanes);
247572d6592SSwapnil Jakhade static int cdns_torrent_dp_configure(struct phy *phy,
248572d6592SSwapnil Jakhade 				     union phy_configure_opts *opts);
249572d6592SSwapnil Jakhade static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
250572d6592SSwapnil Jakhade 					   u32 num_lanes,
251572d6592SSwapnil Jakhade 					   enum phy_powerstate powerstate);
252afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_on(struct phy *phy);
253afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_off(struct phy *phy);
254572d6592SSwapnil Jakhade 
25592e9ccc6SSwapnil Jakhade static const struct phy_ops cdns_torrent_phy_ops = {
25692e9ccc6SSwapnil Jakhade 	.init		= cdns_torrent_dp_init,
257e4b496a3SSwapnil Jakhade 	.exit		= cdns_torrent_dp_exit,
258572d6592SSwapnil Jakhade 	.configure	= cdns_torrent_dp_configure,
259afa4ba05SSwapnil Jakhade 	.power_on	= cdns_torrent_phy_on,
260afa4ba05SSwapnil Jakhade 	.power_off	= cdns_torrent_phy_off,
261c589e701SYuti Amonkar 	.owner		= THIS_MODULE,
262c589e701SYuti Amonkar };
263c589e701SYuti Amonkar 
26469d114acSSwapnil Jakhade struct cdns_torrent_data {
26569d114acSSwapnil Jakhade 		u8 block_offset_shift;
26669d114acSSwapnil Jakhade 		u8 reg_offset_shift;
26769d114acSSwapnil Jakhade };
26869d114acSSwapnil Jakhade 
26969d114acSSwapnil Jakhade struct cdns_regmap_cdb_context {
27069d114acSSwapnil Jakhade 	struct device *dev;
27169d114acSSwapnil Jakhade 	void __iomem *base;
27269d114acSSwapnil Jakhade 	u8 reg_offset_shift;
27369d114acSSwapnil Jakhade };
27469d114acSSwapnil Jakhade 
27569d114acSSwapnil Jakhade static int cdns_regmap_write(void *context, unsigned int reg, unsigned int val)
27669d114acSSwapnil Jakhade {
27769d114acSSwapnil Jakhade 	struct cdns_regmap_cdb_context *ctx = context;
27869d114acSSwapnil Jakhade 	u32 offset = reg << ctx->reg_offset_shift;
27969d114acSSwapnil Jakhade 
28069d114acSSwapnil Jakhade 	writew(val, ctx->base + offset);
28169d114acSSwapnil Jakhade 
28269d114acSSwapnil Jakhade 	return 0;
28369d114acSSwapnil Jakhade }
28469d114acSSwapnil Jakhade 
28569d114acSSwapnil Jakhade static int cdns_regmap_read(void *context, unsigned int reg, unsigned int *val)
28669d114acSSwapnil Jakhade {
28769d114acSSwapnil Jakhade 	struct cdns_regmap_cdb_context *ctx = context;
28869d114acSSwapnil Jakhade 	u32 offset = reg << ctx->reg_offset_shift;
28969d114acSSwapnil Jakhade 
29069d114acSSwapnil Jakhade 	*val = readw(ctx->base + offset);
29169d114acSSwapnil Jakhade 	return 0;
29269d114acSSwapnil Jakhade }
29369d114acSSwapnil Jakhade 
294cba472ecSSwapnil Jakhade static int cdns_regmap_dptx_write(void *context, unsigned int reg,
295cba472ecSSwapnil Jakhade 				  unsigned int val)
296cba472ecSSwapnil Jakhade {
297cba472ecSSwapnil Jakhade 	struct cdns_regmap_cdb_context *ctx = context;
298cba472ecSSwapnil Jakhade 	u32 offset = reg;
299cba472ecSSwapnil Jakhade 
300cba472ecSSwapnil Jakhade 	writel(val, ctx->base + offset);
301cba472ecSSwapnil Jakhade 
302cba472ecSSwapnil Jakhade 	return 0;
303cba472ecSSwapnil Jakhade }
304cba472ecSSwapnil Jakhade 
305cba472ecSSwapnil Jakhade static int cdns_regmap_dptx_read(void *context, unsigned int reg,
306cba472ecSSwapnil Jakhade 				 unsigned int *val)
307cba472ecSSwapnil Jakhade {
308cba472ecSSwapnil Jakhade 	struct cdns_regmap_cdb_context *ctx = context;
309cba472ecSSwapnil Jakhade 	u32 offset = reg;
310cba472ecSSwapnil Jakhade 
311cba472ecSSwapnil Jakhade 	*val = readl(ctx->base + offset);
312cba472ecSSwapnil Jakhade 	return 0;
313cba472ecSSwapnil Jakhade }
314cba472ecSSwapnil Jakhade 
31569d114acSSwapnil Jakhade #define TORRENT_TX_LANE_CDB_REGMAP_CONF(n) \
31669d114acSSwapnil Jakhade { \
31769d114acSSwapnil Jakhade 	.name = "torrent_tx_lane" n "_cdb", \
31869d114acSSwapnil Jakhade 	.reg_stride = 1, \
31969d114acSSwapnil Jakhade 	.fast_io = true, \
32069d114acSSwapnil Jakhade 	.reg_write = cdns_regmap_write, \
32169d114acSSwapnil Jakhade 	.reg_read = cdns_regmap_read, \
32269d114acSSwapnil Jakhade }
32369d114acSSwapnil Jakhade 
32469d114acSSwapnil Jakhade #define TORRENT_RX_LANE_CDB_REGMAP_CONF(n) \
32569d114acSSwapnil Jakhade { \
32669d114acSSwapnil Jakhade 	.name = "torrent_rx_lane" n "_cdb", \
32769d114acSSwapnil Jakhade 	.reg_stride = 1, \
32869d114acSSwapnil Jakhade 	.fast_io = true, \
32969d114acSSwapnil Jakhade 	.reg_write = cdns_regmap_write, \
33069d114acSSwapnil Jakhade 	.reg_read = cdns_regmap_read, \
33169d114acSSwapnil Jakhade }
33269d114acSSwapnil Jakhade 
33357d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_tx_lane_cdb_config[] = {
33469d114acSSwapnil Jakhade 	TORRENT_TX_LANE_CDB_REGMAP_CONF("0"),
33569d114acSSwapnil Jakhade 	TORRENT_TX_LANE_CDB_REGMAP_CONF("1"),
33669d114acSSwapnil Jakhade 	TORRENT_TX_LANE_CDB_REGMAP_CONF("2"),
33769d114acSSwapnil Jakhade 	TORRENT_TX_LANE_CDB_REGMAP_CONF("3"),
33869d114acSSwapnil Jakhade };
33969d114acSSwapnil Jakhade 
34057d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_rx_lane_cdb_config[] = {
34169d114acSSwapnil Jakhade 	TORRENT_RX_LANE_CDB_REGMAP_CONF("0"),
34269d114acSSwapnil Jakhade 	TORRENT_RX_LANE_CDB_REGMAP_CONF("1"),
34369d114acSSwapnil Jakhade 	TORRENT_RX_LANE_CDB_REGMAP_CONF("2"),
34469d114acSSwapnil Jakhade 	TORRENT_RX_LANE_CDB_REGMAP_CONF("3"),
34569d114acSSwapnil Jakhade };
34669d114acSSwapnil Jakhade 
34757d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_common_cdb_config = {
34869d114acSSwapnil Jakhade 	.name = "torrent_common_cdb",
34969d114acSSwapnil Jakhade 	.reg_stride = 1,
35069d114acSSwapnil Jakhade 	.fast_io = true,
35169d114acSSwapnil Jakhade 	.reg_write = cdns_regmap_write,
35269d114acSSwapnil Jakhade 	.reg_read = cdns_regmap_read,
35369d114acSSwapnil Jakhade };
35469d114acSSwapnil Jakhade 
35557d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_phy_pcs_cmn_cdb_config = {
35669d114acSSwapnil Jakhade 	.name = "torrent_phy_pcs_cmn_cdb",
35769d114acSSwapnil Jakhade 	.reg_stride = 1,
35869d114acSSwapnil Jakhade 	.fast_io = true,
35969d114acSSwapnil Jakhade 	.reg_write = cdns_regmap_write,
36069d114acSSwapnil Jakhade 	.reg_read = cdns_regmap_read,
36169d114acSSwapnil Jakhade };
36269d114acSSwapnil Jakhade 
36357d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_phy_pma_cmn_cdb_config = {
36469d114acSSwapnil Jakhade 	.name = "torrent_phy_pma_cmn_cdb",
36569d114acSSwapnil Jakhade 	.reg_stride = 1,
36669d114acSSwapnil Jakhade 	.fast_io = true,
36769d114acSSwapnil Jakhade 	.reg_write = cdns_regmap_write,
36869d114acSSwapnil Jakhade 	.reg_read = cdns_regmap_read,
36969d114acSSwapnil Jakhade };
37069d114acSSwapnil Jakhade 
37157d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_dptx_phy_config = {
372cba472ecSSwapnil Jakhade 	.name = "torrent_dptx_phy",
373cba472ecSSwapnil Jakhade 	.reg_stride = 1,
374cba472ecSSwapnil Jakhade 	.fast_io = true,
375cba472ecSSwapnil Jakhade 	.reg_write = cdns_regmap_dptx_write,
376cba472ecSSwapnil Jakhade 	.reg_read = cdns_regmap_dptx_read,
377cba472ecSSwapnil Jakhade };
378cba472ecSSwapnil Jakhade 
379ccb1b89dSSwapnil Jakhade /* PHY mmr access functions */
380ccb1b89dSSwapnil Jakhade 
38169d114acSSwapnil Jakhade static void cdns_torrent_phy_write(struct regmap *regmap, u32 offset, u32 val)
382ccb1b89dSSwapnil Jakhade {
38369d114acSSwapnil Jakhade 	regmap_write(regmap, offset, val);
384ccb1b89dSSwapnil Jakhade }
385ccb1b89dSSwapnil Jakhade 
38669d114acSSwapnil Jakhade static u32 cdns_torrent_phy_read(struct regmap *regmap, u32 offset)
387572d6592SSwapnil Jakhade {
38869d114acSSwapnil Jakhade 	unsigned int val;
389572d6592SSwapnil Jakhade 
39069d114acSSwapnil Jakhade 	regmap_read(regmap, offset, &val);
39169d114acSSwapnil Jakhade 	return val;
39269d114acSSwapnil Jakhade }
393572d6592SSwapnil Jakhade 
394f61b3aedSSwapnil Jakhade /* DPTX mmr access functions */
395f61b3aedSSwapnil Jakhade 
396cba472ecSSwapnil Jakhade static void cdns_torrent_dp_write(struct regmap *regmap, u32 offset, u32 val)
397f61b3aedSSwapnil Jakhade {
398cba472ecSSwapnil Jakhade 	regmap_write(regmap, offset, val);
399f61b3aedSSwapnil Jakhade }
400f61b3aedSSwapnil Jakhade 
401cba472ecSSwapnil Jakhade static u32 cdns_torrent_dp_read(struct regmap *regmap, u32 offset)
402f61b3aedSSwapnil Jakhade {
403cba472ecSSwapnil Jakhade 	u32 val;
404f61b3aedSSwapnil Jakhade 
405cba472ecSSwapnil Jakhade 	regmap_read(regmap, offset, &val);
406cba472ecSSwapnil Jakhade 	return val;
407cba472ecSSwapnil Jakhade }
408f61b3aedSSwapnil Jakhade 
409572d6592SSwapnil Jakhade /*
410572d6592SSwapnil Jakhade  * Structure used to store values of PHY registers for voltage-related
411572d6592SSwapnil Jakhade  * coefficients, for particular voltage swing and pre-emphasis level. Values
412572d6592SSwapnil Jakhade  * are shared across all physical lanes.
413572d6592SSwapnil Jakhade  */
414572d6592SSwapnil Jakhade struct coefficients {
415572d6592SSwapnil Jakhade 	/* Value of DRV_DIAG_TX_DRV register to use */
416572d6592SSwapnil Jakhade 	u16 diag_tx_drv;
417572d6592SSwapnil Jakhade 	/* Value of TX_TXCC_MGNFS_MULT_000 register to use */
418572d6592SSwapnil Jakhade 	u16 mgnfs_mult;
419572d6592SSwapnil Jakhade 	/* Value of TX_TXCC_CPOST_MULT_00 register to use */
420572d6592SSwapnil Jakhade 	u16 cpost_mult;
421572d6592SSwapnil Jakhade };
422572d6592SSwapnil Jakhade 
423572d6592SSwapnil Jakhade /*
424572d6592SSwapnil Jakhade  * Array consists of values of voltage-related registers for sd0801 PHY. A value
425572d6592SSwapnil Jakhade  * of 0xFFFF is a placeholder for invalid combination, and will never be used.
426572d6592SSwapnil Jakhade  */
427572d6592SSwapnil Jakhade static const struct coefficients vltg_coeff[4][4] = {
428572d6592SSwapnil Jakhade 	/* voltage swing 0, pre-emphasis 0->3 */
429572d6592SSwapnil Jakhade 	{	{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x002A,
430572d6592SSwapnil Jakhade 		 .cpost_mult = 0x0000},
431572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x001F,
432572d6592SSwapnil Jakhade 		 .cpost_mult = 0x0014},
433572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0012,
434572d6592SSwapnil Jakhade 		 .cpost_mult = 0x0020},
435572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000,
436572d6592SSwapnil Jakhade 		 .cpost_mult = 0x002A}
437572d6592SSwapnil Jakhade 	},
438572d6592SSwapnil Jakhade 
439572d6592SSwapnil Jakhade 	/* voltage swing 1, pre-emphasis 0->3 */
440572d6592SSwapnil Jakhade 	{	{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x001F,
441572d6592SSwapnil Jakhade 		 .cpost_mult = 0x0000},
442572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0013,
443572d6592SSwapnil Jakhade 		 .cpost_mult = 0x0012},
444572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000,
445572d6592SSwapnil Jakhade 		 .cpost_mult = 0x001F},
446572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
447572d6592SSwapnil Jakhade 		 .cpost_mult = 0xFFFF}
448572d6592SSwapnil Jakhade 	},
449572d6592SSwapnil Jakhade 
450572d6592SSwapnil Jakhade 	/* voltage swing 2, pre-emphasis 0->3 */
451572d6592SSwapnil Jakhade 	{	{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0013,
452572d6592SSwapnil Jakhade 		 .cpost_mult = 0x0000},
453572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000,
454572d6592SSwapnil Jakhade 		 .cpost_mult = 0x0013},
455572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
456572d6592SSwapnil Jakhade 		 .cpost_mult = 0xFFFF},
457572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
458572d6592SSwapnil Jakhade 		 .cpost_mult = 0xFFFF}
459572d6592SSwapnil Jakhade 	},
460572d6592SSwapnil Jakhade 
461572d6592SSwapnil Jakhade 	/* voltage swing 3, pre-emphasis 0->3 */
462572d6592SSwapnil Jakhade 	{	{.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000,
463572d6592SSwapnil Jakhade 		 .cpost_mult = 0x0000},
464572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
465572d6592SSwapnil Jakhade 		 .cpost_mult = 0xFFFF},
466572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
467572d6592SSwapnil Jakhade 		 .cpost_mult = 0xFFFF},
468572d6592SSwapnil Jakhade 		{.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
469572d6592SSwapnil Jakhade 		 .cpost_mult = 0xFFFF}
470572d6592SSwapnil Jakhade 	}
471572d6592SSwapnil Jakhade };
472572d6592SSwapnil Jakhade 
473572d6592SSwapnil Jakhade /*
474572d6592SSwapnil Jakhade  * Enable or disable PLL for selected lanes.
475572d6592SSwapnil Jakhade  */
476572d6592SSwapnil Jakhade static int cdns_torrent_dp_set_pll_en(struct cdns_torrent_phy *cdns_phy,
477572d6592SSwapnil Jakhade 				      struct phy_configure_opts_dp *dp,
478572d6592SSwapnil Jakhade 				      bool enable)
479572d6592SSwapnil Jakhade {
480572d6592SSwapnil Jakhade 	u32 rd_val;
481572d6592SSwapnil Jakhade 	u32 ret;
482cba472ecSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
483cba472ecSSwapnil Jakhade 
484572d6592SSwapnil Jakhade 	/*
485572d6592SSwapnil Jakhade 	 * Used to determine, which bits to check for or enable in
486572d6592SSwapnil Jakhade 	 * PHY_PMA_XCVR_PLLCLK_EN register.
487572d6592SSwapnil Jakhade 	 */
488572d6592SSwapnil Jakhade 	u32 pll_bits;
489572d6592SSwapnil Jakhade 	/* Used to enable or disable lanes. */
490572d6592SSwapnil Jakhade 	u32 pll_val;
491572d6592SSwapnil Jakhade 
492572d6592SSwapnil Jakhade 	/* Select values of registers and mask, depending on enabled lane
493572d6592SSwapnil Jakhade 	 * count.
494572d6592SSwapnil Jakhade 	 */
495572d6592SSwapnil Jakhade 	switch (dp->lanes) {
496572d6592SSwapnil Jakhade 	/* lane 0 */
497572d6592SSwapnil Jakhade 	case (1):
498572d6592SSwapnil Jakhade 		pll_bits = 0x00000001;
499572d6592SSwapnil Jakhade 		break;
500572d6592SSwapnil Jakhade 	/* lanes 0-1 */
501572d6592SSwapnil Jakhade 	case (2):
502572d6592SSwapnil Jakhade 		pll_bits = 0x00000003;
503572d6592SSwapnil Jakhade 		break;
504572d6592SSwapnil Jakhade 	/* lanes 0-3, all */
505572d6592SSwapnil Jakhade 	default:
506572d6592SSwapnil Jakhade 		pll_bits = 0x0000000F;
507572d6592SSwapnil Jakhade 		break;
508572d6592SSwapnil Jakhade 	}
509572d6592SSwapnil Jakhade 
510572d6592SSwapnil Jakhade 	if (enable)
511572d6592SSwapnil Jakhade 		pll_val = pll_bits;
512572d6592SSwapnil Jakhade 	else
513572d6592SSwapnil Jakhade 		pll_val = 0x00000000;
514572d6592SSwapnil Jakhade 
515cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, pll_val);
516572d6592SSwapnil Jakhade 
517572d6592SSwapnil Jakhade 	/* Wait for acknowledgment from PHY. */
518cba472ecSSwapnil Jakhade 	ret = regmap_read_poll_timeout(regmap,
519572d6592SSwapnil Jakhade 				       PHY_PMA_XCVR_PLLCLK_EN_ACK,
520572d6592SSwapnil Jakhade 				       rd_val,
521572d6592SSwapnil Jakhade 				       (rd_val & pll_bits) == pll_val,
522572d6592SSwapnil Jakhade 				       0, POLL_TIMEOUT_US);
523572d6592SSwapnil Jakhade 	ndelay(100);
524572d6592SSwapnil Jakhade 	return ret;
525572d6592SSwapnil Jakhade }
526572d6592SSwapnil Jakhade 
527572d6592SSwapnil Jakhade /*
528572d6592SSwapnil Jakhade  * Perform register operations related to setting link rate, once powerstate is
529572d6592SSwapnil Jakhade  * set and PLL disable request was processed.
530572d6592SSwapnil Jakhade  */
531572d6592SSwapnil Jakhade static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy,
532572d6592SSwapnil Jakhade 					  struct phy_configure_opts_dp *dp)
533572d6592SSwapnil Jakhade {
534572d6592SSwapnil Jakhade 	u32 ret;
535572d6592SSwapnil Jakhade 	u32 read_val;
536572d6592SSwapnil Jakhade 
537572d6592SSwapnil Jakhade 	/* Disable the cmn_pll0_en before re-programming the new data rate. */
53869d114acSSwapnil Jakhade 	regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x0);
539572d6592SSwapnil Jakhade 
540572d6592SSwapnil Jakhade 	/*
541572d6592SSwapnil Jakhade 	 * Wait for PLL ready de-assertion.
542572d6592SSwapnil Jakhade 	 * For PLL0 - PHY_PMA_CMN_CTRL2[2] == 1
543572d6592SSwapnil Jakhade 	 */
54469d114acSSwapnil Jakhade 	ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2,
545572d6592SSwapnil Jakhade 					     read_val,
546572d6592SSwapnil Jakhade 					     ((read_val >> 2) & 0x01) != 0,
547572d6592SSwapnil Jakhade 					     0, POLL_TIMEOUT_US);
548572d6592SSwapnil Jakhade 	if (ret)
549572d6592SSwapnil Jakhade 		return ret;
550572d6592SSwapnil Jakhade 	ndelay(200);
551572d6592SSwapnil Jakhade 
552572d6592SSwapnil Jakhade 	/* DP Rate Change - VCO Output settings. */
553572d6592SSwapnil Jakhade 	if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) {
554572d6592SSwapnil Jakhade 		/* PMA common configuration 19.2MHz */
555572d6592SSwapnil Jakhade 		cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate,
556572d6592SSwapnil Jakhade 							dp->ssc);
557572d6592SSwapnil Jakhade 		cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
558572d6592SSwapnil Jakhade 	} else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) {
559572d6592SSwapnil Jakhade 		/* PMA common configuration 25MHz */
560572d6592SSwapnil Jakhade 		cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate,
561572d6592SSwapnil Jakhade 						      dp->ssc);
562572d6592SSwapnil Jakhade 		cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
563572d6592SSwapnil Jakhade 	}
564572d6592SSwapnil Jakhade 	cdns_torrent_dp_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes);
565572d6592SSwapnil Jakhade 
566572d6592SSwapnil Jakhade 	/* Enable the cmn_pll0_en. */
56769d114acSSwapnil Jakhade 	regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x3);
568572d6592SSwapnil Jakhade 
569572d6592SSwapnil Jakhade 	/*
570572d6592SSwapnil Jakhade 	 * Wait for PLL ready assertion.
571572d6592SSwapnil Jakhade 	 * For PLL0 - PHY_PMA_CMN_CTRL2[0] == 1
572572d6592SSwapnil Jakhade 	 */
57369d114acSSwapnil Jakhade 	ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2,
574572d6592SSwapnil Jakhade 					     read_val,
575572d6592SSwapnil Jakhade 					     (read_val & 0x01) != 0,
576572d6592SSwapnil Jakhade 					     0, POLL_TIMEOUT_US);
577572d6592SSwapnil Jakhade 	return ret;
578572d6592SSwapnil Jakhade }
579572d6592SSwapnil Jakhade 
580572d6592SSwapnil Jakhade /*
581572d6592SSwapnil Jakhade  * Verify, that parameters to configure PHY with are correct.
582572d6592SSwapnil Jakhade  */
583afa4ba05SSwapnil Jakhade static int cdns_torrent_dp_verify_config(struct cdns_torrent_inst *inst,
584572d6592SSwapnil Jakhade 					 struct phy_configure_opts_dp *dp)
585572d6592SSwapnil Jakhade {
586572d6592SSwapnil Jakhade 	u8 i;
587572d6592SSwapnil Jakhade 
588572d6592SSwapnil Jakhade 	/* If changing link rate was required, verify it's supported. */
589572d6592SSwapnil Jakhade 	if (dp->set_rate) {
590572d6592SSwapnil Jakhade 		switch (dp->link_rate) {
591572d6592SSwapnil Jakhade 		case 1620:
592572d6592SSwapnil Jakhade 		case 2160:
593572d6592SSwapnil Jakhade 		case 2430:
594572d6592SSwapnil Jakhade 		case 2700:
595572d6592SSwapnil Jakhade 		case 3240:
596572d6592SSwapnil Jakhade 		case 4320:
597572d6592SSwapnil Jakhade 		case 5400:
598572d6592SSwapnil Jakhade 		case 8100:
599572d6592SSwapnil Jakhade 			/* valid bit rate */
600572d6592SSwapnil Jakhade 			break;
601572d6592SSwapnil Jakhade 		default:
602572d6592SSwapnil Jakhade 			return -EINVAL;
603572d6592SSwapnil Jakhade 		}
604572d6592SSwapnil Jakhade 	}
605572d6592SSwapnil Jakhade 
606572d6592SSwapnil Jakhade 	/* Verify lane count. */
607572d6592SSwapnil Jakhade 	switch (dp->lanes) {
608572d6592SSwapnil Jakhade 	case 1:
609572d6592SSwapnil Jakhade 	case 2:
610572d6592SSwapnil Jakhade 	case 4:
611572d6592SSwapnil Jakhade 		/* valid lane count. */
612572d6592SSwapnil Jakhade 		break;
613572d6592SSwapnil Jakhade 	default:
614572d6592SSwapnil Jakhade 		return -EINVAL;
615572d6592SSwapnil Jakhade 	}
616572d6592SSwapnil Jakhade 
617572d6592SSwapnil Jakhade 	/* Check against actual number of PHY's lanes. */
618afa4ba05SSwapnil Jakhade 	if (dp->lanes > inst->num_lanes)
619572d6592SSwapnil Jakhade 		return -EINVAL;
620572d6592SSwapnil Jakhade 
621572d6592SSwapnil Jakhade 	/*
622572d6592SSwapnil Jakhade 	 * If changing voltages is required, check swing and pre-emphasis
623572d6592SSwapnil Jakhade 	 * levels, per-lane.
624572d6592SSwapnil Jakhade 	 */
625572d6592SSwapnil Jakhade 	if (dp->set_voltages) {
626572d6592SSwapnil Jakhade 		/* Lane count verified previously. */
627572d6592SSwapnil Jakhade 		for (i = 0; i < dp->lanes; i++) {
628572d6592SSwapnil Jakhade 			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
629572d6592SSwapnil Jakhade 				return -EINVAL;
630572d6592SSwapnil Jakhade 
631572d6592SSwapnil Jakhade 			/* Sum of voltage swing and pre-emphasis levels cannot
632572d6592SSwapnil Jakhade 			 * exceed 3.
633572d6592SSwapnil Jakhade 			 */
634572d6592SSwapnil Jakhade 			if (dp->voltage[i] + dp->pre[i] > 3)
635572d6592SSwapnil Jakhade 				return -EINVAL;
636572d6592SSwapnil Jakhade 		}
637572d6592SSwapnil Jakhade 	}
638572d6592SSwapnil Jakhade 
639572d6592SSwapnil Jakhade 	return 0;
640572d6592SSwapnil Jakhade }
641572d6592SSwapnil Jakhade 
64221c79146SSwapnil Jakhade /* Set power state A0 and PLL clock enable to 0 on enabled lanes. */
64321c79146SSwapnil Jakhade static void cdns_torrent_dp_set_a0_pll(struct cdns_torrent_phy *cdns_phy,
64421c79146SSwapnil Jakhade 				       u32 num_lanes)
64521c79146SSwapnil Jakhade {
646cba472ecSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
647cba472ecSSwapnil Jakhade 	u32 pwr_state = cdns_torrent_dp_read(regmap,
64821c79146SSwapnil Jakhade 					     PHY_PMA_XCVR_POWER_STATE_REQ);
649cba472ecSSwapnil Jakhade 	u32 pll_clk_en = cdns_torrent_dp_read(regmap,
65021c79146SSwapnil Jakhade 					      PHY_PMA_XCVR_PLLCLK_EN);
65121c79146SSwapnil Jakhade 
65221c79146SSwapnil Jakhade 	/* Lane 0 is always enabled. */
65321c79146SSwapnil Jakhade 	pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
65421c79146SSwapnil Jakhade 		       PHY_POWER_STATE_LN_0);
65521c79146SSwapnil Jakhade 	pll_clk_en &= ~0x01U;
65621c79146SSwapnil Jakhade 
65721c79146SSwapnil Jakhade 	if (num_lanes > 1) {
65821c79146SSwapnil Jakhade 		/* lane 1 */
65921c79146SSwapnil Jakhade 		pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
66021c79146SSwapnil Jakhade 			       PHY_POWER_STATE_LN_1);
66121c79146SSwapnil Jakhade 		pll_clk_en &= ~(0x01U << 1);
66221c79146SSwapnil Jakhade 	}
66321c79146SSwapnil Jakhade 
66421c79146SSwapnil Jakhade 	if (num_lanes > 2) {
66521c79146SSwapnil Jakhade 		/* lanes 2 and 3 */
66621c79146SSwapnil Jakhade 		pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
66721c79146SSwapnil Jakhade 			       PHY_POWER_STATE_LN_2);
66821c79146SSwapnil Jakhade 		pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
66921c79146SSwapnil Jakhade 			       PHY_POWER_STATE_LN_3);
67021c79146SSwapnil Jakhade 		pll_clk_en &= ~(0x01U << 2);
67121c79146SSwapnil Jakhade 		pll_clk_en &= ~(0x01U << 3);
67221c79146SSwapnil Jakhade 	}
67321c79146SSwapnil Jakhade 
674cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, pwr_state);
675cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, pll_clk_en);
67621c79146SSwapnil Jakhade }
67721c79146SSwapnil Jakhade 
678572d6592SSwapnil Jakhade /* Configure lane count as required. */
679572d6592SSwapnil Jakhade static int cdns_torrent_dp_set_lanes(struct cdns_torrent_phy *cdns_phy,
680572d6592SSwapnil Jakhade 				     struct phy_configure_opts_dp *dp)
681572d6592SSwapnil Jakhade {
682572d6592SSwapnil Jakhade 	u32 value;
683572d6592SSwapnil Jakhade 	u32 ret;
684cba472ecSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
685572d6592SSwapnil Jakhade 	u8 lane_mask = (1 << dp->lanes) - 1;
686572d6592SSwapnil Jakhade 
687cba472ecSSwapnil Jakhade 	value = cdns_torrent_dp_read(regmap, PHY_RESET);
688572d6592SSwapnil Jakhade 	/* clear pma_tx_elec_idle_ln_* bits. */
689572d6592SSwapnil Jakhade 	value &= ~PMA_TX_ELEC_IDLE_MASK;
690572d6592SSwapnil Jakhade 	/* Assert pma_tx_elec_idle_ln_* for disabled lanes. */
691572d6592SSwapnil Jakhade 	value |= ((~lane_mask) << PMA_TX_ELEC_IDLE_SHIFT) &
692572d6592SSwapnil Jakhade 		 PMA_TX_ELEC_IDLE_MASK;
693cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_RESET, value);
694572d6592SSwapnil Jakhade 
695572d6592SSwapnil Jakhade 	/* reset the link by asserting phy_l00_reset_n low */
696cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_RESET,
697572d6592SSwapnil Jakhade 			      value & (~PHY_L00_RESET_N_MASK));
698572d6592SSwapnil Jakhade 
699572d6592SSwapnil Jakhade 	/*
700572d6592SSwapnil Jakhade 	 * Assert lane reset on unused lanes and lane 0 so they remain in reset
701572d6592SSwapnil Jakhade 	 * and powered down when re-enabling the link
702572d6592SSwapnil Jakhade 	 */
703572d6592SSwapnil Jakhade 	value = (value & 0x0000FFF0) | (0x0000000E & lane_mask);
704cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_RESET, value);
705572d6592SSwapnil Jakhade 
706572d6592SSwapnil Jakhade 	cdns_torrent_dp_set_a0_pll(cdns_phy, dp->lanes);
707572d6592SSwapnil Jakhade 
708572d6592SSwapnil Jakhade 	/* release phy_l0*_reset_n based on used laneCount */
709572d6592SSwapnil Jakhade 	value = (value & 0x0000FFF0) | (0x0000000F & lane_mask);
710cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_RESET, value);
711572d6592SSwapnil Jakhade 
712572d6592SSwapnil Jakhade 	/* Wait, until PHY gets ready after releasing PHY reset signal. */
713572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
714572d6592SSwapnil Jakhade 	if (ret)
715572d6592SSwapnil Jakhade 		return ret;
716572d6592SSwapnil Jakhade 
717572d6592SSwapnil Jakhade 	ndelay(100);
718572d6592SSwapnil Jakhade 
719572d6592SSwapnil Jakhade 	/* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
720cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
721572d6592SSwapnil Jakhade 
722572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_run(cdns_phy, dp->lanes);
723572d6592SSwapnil Jakhade 
724572d6592SSwapnil Jakhade 	return ret;
725572d6592SSwapnil Jakhade }
726572d6592SSwapnil Jakhade 
727572d6592SSwapnil Jakhade /* Configure link rate as required. */
728572d6592SSwapnil Jakhade static int cdns_torrent_dp_set_rate(struct cdns_torrent_phy *cdns_phy,
729572d6592SSwapnil Jakhade 				    struct phy_configure_opts_dp *dp)
730572d6592SSwapnil Jakhade {
731572d6592SSwapnil Jakhade 	u32 ret;
732572d6592SSwapnil Jakhade 
733572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
734572d6592SSwapnil Jakhade 					      POWERSTATE_A3);
735572d6592SSwapnil Jakhade 	if (ret)
736572d6592SSwapnil Jakhade 		return ret;
737572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, false);
738572d6592SSwapnil Jakhade 	if (ret)
739572d6592SSwapnil Jakhade 		return ret;
740572d6592SSwapnil Jakhade 	ndelay(200);
741572d6592SSwapnil Jakhade 
742572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_configure_rate(cdns_phy, dp);
743572d6592SSwapnil Jakhade 	if (ret)
744572d6592SSwapnil Jakhade 		return ret;
745572d6592SSwapnil Jakhade 	ndelay(200);
746572d6592SSwapnil Jakhade 
747572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, true);
748572d6592SSwapnil Jakhade 	if (ret)
749572d6592SSwapnil Jakhade 		return ret;
750572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
751572d6592SSwapnil Jakhade 					      POWERSTATE_A2);
752572d6592SSwapnil Jakhade 	if (ret)
753572d6592SSwapnil Jakhade 		return ret;
754572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
755572d6592SSwapnil Jakhade 					      POWERSTATE_A0);
756572d6592SSwapnil Jakhade 	if (ret)
757572d6592SSwapnil Jakhade 		return ret;
758572d6592SSwapnil Jakhade 	ndelay(900);
759572d6592SSwapnil Jakhade 
760572d6592SSwapnil Jakhade 	return ret;
761572d6592SSwapnil Jakhade }
762572d6592SSwapnil Jakhade 
763572d6592SSwapnil Jakhade /* Configure voltage swing and pre-emphasis for all enabled lanes. */
764572d6592SSwapnil Jakhade static void cdns_torrent_dp_set_voltages(struct cdns_torrent_phy *cdns_phy,
765572d6592SSwapnil Jakhade 					 struct phy_configure_opts_dp *dp)
766572d6592SSwapnil Jakhade {
767572d6592SSwapnil Jakhade 	u8 lane;
768572d6592SSwapnil Jakhade 	u16 val;
769572d6592SSwapnil Jakhade 
770572d6592SSwapnil Jakhade 	for (lane = 0; lane < dp->lanes; lane++) {
77169d114acSSwapnil Jakhade 		val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane],
77269d114acSSwapnil Jakhade 					    TX_DIAG_ACYA);
773572d6592SSwapnil Jakhade 		/*
774572d6592SSwapnil Jakhade 		 * Write 1 to register bit TX_DIAG_ACYA[0] to freeze the
775572d6592SSwapnil Jakhade 		 * current state of the analog TX driver.
776572d6592SSwapnil Jakhade 		 */
777572d6592SSwapnil Jakhade 		val |= TX_DIAG_ACYA_HBDC_MASK;
77869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
77969d114acSSwapnil Jakhade 				       TX_DIAG_ACYA, val);
780572d6592SSwapnil Jakhade 
78169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
78269d114acSSwapnil Jakhade 				       TX_TXCC_CTRL, 0x08A4);
783572d6592SSwapnil Jakhade 		val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].diag_tx_drv;
78469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
78569d114acSSwapnil Jakhade 				       DRV_DIAG_TX_DRV, val);
786572d6592SSwapnil Jakhade 		val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].mgnfs_mult;
78769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
78869d114acSSwapnil Jakhade 				       TX_TXCC_MGNFS_MULT_000,
789572d6592SSwapnil Jakhade 				       val);
790572d6592SSwapnil Jakhade 		val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].cpost_mult;
79169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
79269d114acSSwapnil Jakhade 				       TX_TXCC_CPOST_MULT_00,
793572d6592SSwapnil Jakhade 				       val);
794572d6592SSwapnil Jakhade 
79569d114acSSwapnil Jakhade 		val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane],
79669d114acSSwapnil Jakhade 					    TX_DIAG_ACYA);
797572d6592SSwapnil Jakhade 		/*
798572d6592SSwapnil Jakhade 		 * Write 0 to register bit TX_DIAG_ACYA[0] to allow the state of
799572d6592SSwapnil Jakhade 		 * analog TX driver to reflect the new programmed one.
800572d6592SSwapnil Jakhade 		 */
801572d6592SSwapnil Jakhade 		val &= ~TX_DIAG_ACYA_HBDC_MASK;
80269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
80369d114acSSwapnil Jakhade 				       TX_DIAG_ACYA, val);
804572d6592SSwapnil Jakhade 	}
805572d6592SSwapnil Jakhade };
806572d6592SSwapnil Jakhade 
807572d6592SSwapnil Jakhade static int cdns_torrent_dp_configure(struct phy *phy,
808572d6592SSwapnil Jakhade 				     union phy_configure_opts *opts)
809572d6592SSwapnil Jakhade {
810afa4ba05SSwapnil Jakhade 	struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
811afa4ba05SSwapnil Jakhade 	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
812572d6592SSwapnil Jakhade 	int ret;
813572d6592SSwapnil Jakhade 
814afa4ba05SSwapnil Jakhade 	ret = cdns_torrent_dp_verify_config(inst, &opts->dp);
815572d6592SSwapnil Jakhade 	if (ret) {
816572d6592SSwapnil Jakhade 		dev_err(&phy->dev, "invalid params for phy configure\n");
817572d6592SSwapnil Jakhade 		return ret;
818572d6592SSwapnil Jakhade 	}
819572d6592SSwapnil Jakhade 
820572d6592SSwapnil Jakhade 	if (opts->dp.set_lanes) {
821572d6592SSwapnil Jakhade 		ret = cdns_torrent_dp_set_lanes(cdns_phy, &opts->dp);
822572d6592SSwapnil Jakhade 		if (ret) {
823572d6592SSwapnil Jakhade 			dev_err(&phy->dev, "cdns_torrent_dp_set_lanes failed\n");
824572d6592SSwapnil Jakhade 			return ret;
825572d6592SSwapnil Jakhade 		}
826572d6592SSwapnil Jakhade 	}
827572d6592SSwapnil Jakhade 
828572d6592SSwapnil Jakhade 	if (opts->dp.set_rate) {
829572d6592SSwapnil Jakhade 		ret = cdns_torrent_dp_set_rate(cdns_phy, &opts->dp);
830572d6592SSwapnil Jakhade 		if (ret) {
831572d6592SSwapnil Jakhade 			dev_err(&phy->dev, "cdns_torrent_dp_set_rate failed\n");
832572d6592SSwapnil Jakhade 			return ret;
833572d6592SSwapnil Jakhade 		}
834572d6592SSwapnil Jakhade 	}
835572d6592SSwapnil Jakhade 
836572d6592SSwapnil Jakhade 	if (opts->dp.set_voltages)
837572d6592SSwapnil Jakhade 		cdns_torrent_dp_set_voltages(cdns_phy, &opts->dp);
838572d6592SSwapnil Jakhade 
839572d6592SSwapnil Jakhade 	return ret;
840572d6592SSwapnil Jakhade }
841572d6592SSwapnil Jakhade 
84292e9ccc6SSwapnil Jakhade static int cdns_torrent_dp_init(struct phy *phy)
843c589e701SYuti Amonkar {
844c589e701SYuti Amonkar 	unsigned char lane_bits;
84521c79146SSwapnil Jakhade 	int ret;
846afa4ba05SSwapnil Jakhade 	struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
847afa4ba05SSwapnil Jakhade 	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
848cba472ecSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
849c589e701SYuti Amonkar 
850e4b496a3SSwapnil Jakhade 	ret = clk_prepare_enable(cdns_phy->clk);
851e4b496a3SSwapnil Jakhade 	if (ret) {
852e4b496a3SSwapnil Jakhade 		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
853e4b496a3SSwapnil Jakhade 		return ret;
854e4b496a3SSwapnil Jakhade 	}
855e4b496a3SSwapnil Jakhade 
856e4b496a3SSwapnil Jakhade 	cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
857e4b496a3SSwapnil Jakhade 	if (!(cdns_phy->ref_clk_rate)) {
858e4b496a3SSwapnil Jakhade 		dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
859e4b496a3SSwapnil Jakhade 		clk_disable_unprepare(cdns_phy->clk);
860e4b496a3SSwapnil Jakhade 		return -EINVAL;
861e4b496a3SSwapnil Jakhade 	}
862e4b496a3SSwapnil Jakhade 
863e4b496a3SSwapnil Jakhade 	switch (cdns_phy->ref_clk_rate) {
864e4b496a3SSwapnil Jakhade 	case REF_CLK_19_2MHz:
865e4b496a3SSwapnil Jakhade 	case REF_CLK_25MHz:
866e4b496a3SSwapnil Jakhade 		/* Valid Ref Clock Rate */
867e4b496a3SSwapnil Jakhade 		break;
868e4b496a3SSwapnil Jakhade 	default:
869e4b496a3SSwapnil Jakhade 		dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n");
870e4b496a3SSwapnil Jakhade 		return -EINVAL;
871e4b496a3SSwapnil Jakhade 	}
872e4b496a3SSwapnil Jakhade 
873cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_AUX_CTRL, 0x0003); /* enable AUX */
874c589e701SYuti Amonkar 
875c589e701SYuti Amonkar 	/* PHY PMA registers configuration function */
876afa4ba05SSwapnil Jakhade 	cdns_torrent_dp_pma_cfg(cdns_phy, inst);
877c589e701SYuti Amonkar 
878c589e701SYuti Amonkar 	/*
879c589e701SYuti Amonkar 	 * Set lines power state to A0
880c589e701SYuti Amonkar 	 * Set lines pll clk enable to 0
881c589e701SYuti Amonkar 	 */
882afa4ba05SSwapnil Jakhade 	cdns_torrent_dp_set_a0_pll(cdns_phy, inst->num_lanes);
883c589e701SYuti Amonkar 
884c589e701SYuti Amonkar 	/*
885c589e701SYuti Amonkar 	 * release phy_l0*_reset_n and pma_tx_elec_idle_ln_* based on
886c589e701SYuti Amonkar 	 * used lanes
887c589e701SYuti Amonkar 	 */
888afa4ba05SSwapnil Jakhade 	lane_bits = (1 << inst->num_lanes) - 1;
889cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_RESET,
890f61b3aedSSwapnil Jakhade 			      ((0xF & ~lane_bits) << 4) | (0xF & lane_bits));
891c589e701SYuti Amonkar 
892c589e701SYuti Amonkar 	/* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
893cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
894c589e701SYuti Amonkar 
895c589e701SYuti Amonkar 	/* PHY PMA registers configuration functions */
896e4b496a3SSwapnil Jakhade 	/* Initialize PHY with max supported link rate, without SSC. */
897e4b496a3SSwapnil Jakhade 	if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
898e4b496a3SSwapnil Jakhade 		cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy,
899e4b496a3SSwapnil Jakhade 							cdns_phy->max_bit_rate,
900e4b496a3SSwapnil Jakhade 							false);
901e4b496a3SSwapnil Jakhade 	else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
902e4b496a3SSwapnil Jakhade 		cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy,
903e4b496a3SSwapnil Jakhade 						      cdns_phy->max_bit_rate,
904e4b496a3SSwapnil Jakhade 						      false);
905e4b496a3SSwapnil Jakhade 	cdns_torrent_dp_pma_cmn_rate(cdns_phy, cdns_phy->max_bit_rate,
906afa4ba05SSwapnil Jakhade 				     inst->num_lanes);
907c589e701SYuti Amonkar 
908c589e701SYuti Amonkar 	/* take out of reset */
909cba472ecSSwapnil Jakhade 	regmap_field_write(cdns_phy->phy_reset_ctrl, 0x1);
910cba472ecSSwapnil Jakhade 
911afa4ba05SSwapnil Jakhade 	cdns_torrent_phy_on(phy);
912afa4ba05SSwapnil Jakhade 
91321c79146SSwapnil Jakhade 	ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
91421c79146SSwapnil Jakhade 	if (ret)
91521c79146SSwapnil Jakhade 		return ret;
916c589e701SYuti Amonkar 
917afa4ba05SSwapnil Jakhade 	ret = cdns_torrent_dp_run(cdns_phy, inst->num_lanes);
91821c79146SSwapnil Jakhade 
91921c79146SSwapnil Jakhade 	return ret;
920c589e701SYuti Amonkar }
921c589e701SYuti Amonkar 
922e4b496a3SSwapnil Jakhade static int cdns_torrent_dp_exit(struct phy *phy)
923e4b496a3SSwapnil Jakhade {
924afa4ba05SSwapnil Jakhade 	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
925e4b496a3SSwapnil Jakhade 
926e4b496a3SSwapnil Jakhade 	clk_disable_unprepare(cdns_phy->clk);
927e4b496a3SSwapnil Jakhade 	return 0;
928e4b496a3SSwapnil Jakhade }
929e4b496a3SSwapnil Jakhade 
93092e9ccc6SSwapnil Jakhade static
93121c79146SSwapnil Jakhade int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
932c589e701SYuti Amonkar {
933c589e701SYuti Amonkar 	unsigned int reg;
934c589e701SYuti Amonkar 	int ret;
935cba472ecSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
936c589e701SYuti Amonkar 
937cba472ecSSwapnil Jakhade 	ret = regmap_read_poll_timeout(regmap, PHY_PMA_CMN_READY, reg,
938cba472ecSSwapnil Jakhade 				       reg & 1, 0, POLL_TIMEOUT_US);
93921c79146SSwapnil Jakhade 	if (ret == -ETIMEDOUT) {
940c589e701SYuti Amonkar 		dev_err(cdns_phy->dev,
941c589e701SYuti Amonkar 			"timeout waiting for PMA common ready\n");
94221c79146SSwapnil Jakhade 		return -ETIMEDOUT;
94321c79146SSwapnil Jakhade 	}
94421c79146SSwapnil Jakhade 
94521c79146SSwapnil Jakhade 	return 0;
946c589e701SYuti Amonkar }
947c589e701SYuti Amonkar 
948afa4ba05SSwapnil Jakhade static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy,
949afa4ba05SSwapnil Jakhade 				    struct cdns_torrent_inst *inst)
950c589e701SYuti Amonkar {
951c589e701SYuti Amonkar 	unsigned int i;
952c589e701SYuti Amonkar 
953e4b496a3SSwapnil Jakhade 	if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
954e4b496a3SSwapnil Jakhade 		/* PMA common configuration 19.2MHz */
955e4b496a3SSwapnil Jakhade 		cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
956e4b496a3SSwapnil Jakhade 	else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
957e4b496a3SSwapnil Jakhade 		/* PMA common configuration 25MHz */
95892e9ccc6SSwapnil Jakhade 		cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
959c589e701SYuti Amonkar 
960c589e701SYuti Amonkar 	/* PMA lane configuration to deal with multi-link operation */
961afa4ba05SSwapnil Jakhade 	for (i = 0; i < inst->num_lanes; i++)
96292e9ccc6SSwapnil Jakhade 		cdns_torrent_dp_pma_lane_cfg(cdns_phy, i);
963c589e701SYuti Amonkar }
964c589e701SYuti Amonkar 
96592e9ccc6SSwapnil Jakhade static
966e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy)
967e4b496a3SSwapnil Jakhade {
96869d114acSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_common_cdb;
96969d114acSSwapnil Jakhade 
970e4b496a3SSwapnil Jakhade 	/* refclock registers - assumes 19.2 MHz refclock */
97169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0014);
97269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLPRE_TMR, 0x0027);
97369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLLOCK_TMR, 0x00A1);
97469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLPRE_TMR, 0x0027);
97569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLLOCK_TMR, 0x00A1);
97669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_BGCAL_INIT_TMR, 0x0060);
97769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_BGCAL_ITER_TMR, 0x0060);
97869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_IBCAL_INIT_TMR, 0x0014);
97969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_TXPUCAL_INIT_TMR, 0x0018);
98069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_TXPUCAL_ITER_TMR, 0x0005);
98169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_TXPDCAL_INIT_TMR, 0x0018);
98269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_TXPDCAL_ITER_TMR, 0x0005);
98369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_RXCAL_INIT_TMR, 0x0240);
98469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_RXCAL_ITER_TMR, 0x0005);
98569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SD_CAL_INIT_TMR, 0x0002);
98669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SD_CAL_ITER_TMR, 0x0002);
98769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SD_CAL_REFTIM_START, 0x000B);
98869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SD_CAL_PLLCNT_START, 0x0137);
989e4b496a3SSwapnil Jakhade 
990e4b496a3SSwapnil Jakhade 	/* PLL registers */
99169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
99269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
99369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
99469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
99569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
99669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
99769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
99869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
99969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_INIT_TMR, 0x00C0);
100069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004);
100169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_INIT_TMR, 0x00C0);
100269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004);
100369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_REFTIM_START, 0x0260);
100469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_TCTRL, 0x0003);
100569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_REFTIM_START, 0x0260);
100669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_TCTRL, 0x0003);
1007e4b496a3SSwapnil Jakhade }
1008e4b496a3SSwapnil Jakhade 
1009e4b496a3SSwapnil Jakhade /*
1010e4b496a3SSwapnil Jakhade  * Set registers responsible for enabling and configuring SSC, with second and
1011e4b496a3SSwapnil Jakhade  * third register values provided by parameters.
1012e4b496a3SSwapnil Jakhade  */
1013e4b496a3SSwapnil Jakhade static
1014e4b496a3SSwapnil Jakhade void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy,
1015e4b496a3SSwapnil Jakhade 					u32 ctrl2_val, u32 ctrl3_val)
1016e4b496a3SSwapnil Jakhade {
101769d114acSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_common_cdb;
101869d114acSSwapnil Jakhade 
101969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
102069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
102169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl3_val);
102269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
102369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
102469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
102569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl3_val);
102669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
1027e4b496a3SSwapnil Jakhade }
1028e4b496a3SSwapnil Jakhade 
1029e4b496a3SSwapnil Jakhade static
1030e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
1031e4b496a3SSwapnil Jakhade 					     u32 rate, bool ssc)
1032e4b496a3SSwapnil Jakhade {
103369d114acSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_common_cdb;
103469d114acSSwapnil Jakhade 
1035e4b496a3SSwapnil Jakhade 	/* Assumes 19.2 MHz refclock */
1036e4b496a3SSwapnil Jakhade 	switch (rate) {
1037e4b496a3SSwapnil Jakhade 	/* Setting VCO for 10.8GHz */
1038e4b496a3SSwapnil Jakhade 	case 2700:
1039e4b496a3SSwapnil Jakhade 	case 5400:
104069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1041e4b496a3SSwapnil Jakhade 				       CMN_PLL0_INTDIV_M0, 0x0119);
104269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1043e4b496a3SSwapnil Jakhade 				       CMN_PLL0_FRACDIVL_M0, 0x4000);
104469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1045e4b496a3SSwapnil Jakhade 				       CMN_PLL0_FRACDIVH_M0, 0x0002);
104669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1047e4b496a3SSwapnil Jakhade 				       CMN_PLL0_HIGH_THR_M0, 0x00BC);
104869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1049e4b496a3SSwapnil Jakhade 				       CMN_PDIAG_PLL0_CTRL_M0, 0x0012);
105069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1051e4b496a3SSwapnil Jakhade 				       CMN_PLL1_INTDIV_M0, 0x0119);
105269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1053e4b496a3SSwapnil Jakhade 				       CMN_PLL1_FRACDIVL_M0, 0x4000);
105469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1055e4b496a3SSwapnil Jakhade 				       CMN_PLL1_FRACDIVH_M0, 0x0002);
105669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1057e4b496a3SSwapnil Jakhade 				       CMN_PLL1_HIGH_THR_M0, 0x00BC);
105869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1059e4b496a3SSwapnil Jakhade 				       CMN_PDIAG_PLL1_CTRL_M0, 0x0012);
1060e4b496a3SSwapnil Jakhade 		if (ssc)
1061e4b496a3SSwapnil Jakhade 			cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A,
1062e4b496a3SSwapnil Jakhade 							   0x006A);
1063e4b496a3SSwapnil Jakhade 		break;
1064e4b496a3SSwapnil Jakhade 	/* Setting VCO for 9.72GHz */
1065e4b496a3SSwapnil Jakhade 	case 1620:
1066e4b496a3SSwapnil Jakhade 	case 2430:
1067e4b496a3SSwapnil Jakhade 	case 3240:
106869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1069e4b496a3SSwapnil Jakhade 				       CMN_PLL0_INTDIV_M0, 0x01FA);
107069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1071e4b496a3SSwapnil Jakhade 				       CMN_PLL0_FRACDIVL_M0, 0x4000);
107269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1073e4b496a3SSwapnil Jakhade 				       CMN_PLL0_FRACDIVH_M0, 0x0002);
107469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1075e4b496a3SSwapnil Jakhade 				       CMN_PLL0_HIGH_THR_M0, 0x0152);
107669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1077e4b496a3SSwapnil Jakhade 				       CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
107869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1079e4b496a3SSwapnil Jakhade 				       CMN_PLL1_INTDIV_M0, 0x01FA);
108069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1081e4b496a3SSwapnil Jakhade 				       CMN_PLL1_FRACDIVL_M0, 0x4000);
108269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1083e4b496a3SSwapnil Jakhade 				       CMN_PLL1_FRACDIVH_M0, 0x0002);
108469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1085e4b496a3SSwapnil Jakhade 				       CMN_PLL1_HIGH_THR_M0, 0x0152);
108669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1087e4b496a3SSwapnil Jakhade 				       CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
1088e4b496a3SSwapnil Jakhade 		if (ssc)
1089e4b496a3SSwapnil Jakhade 			cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD,
1090e4b496a3SSwapnil Jakhade 							   0x0069);
1091e4b496a3SSwapnil Jakhade 		break;
1092e4b496a3SSwapnil Jakhade 	/* Setting VCO for 8.64GHz */
1093e4b496a3SSwapnil Jakhade 	case 2160:
1094e4b496a3SSwapnil Jakhade 	case 4320:
109569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1096e4b496a3SSwapnil Jakhade 				       CMN_PLL0_INTDIV_M0, 0x01C2);
109769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1098e4b496a3SSwapnil Jakhade 				       CMN_PLL0_FRACDIVL_M0, 0x0000);
109969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1100e4b496a3SSwapnil Jakhade 				       CMN_PLL0_FRACDIVH_M0, 0x0002);
110169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1102e4b496a3SSwapnil Jakhade 				       CMN_PLL0_HIGH_THR_M0, 0x012C);
110369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1104e4b496a3SSwapnil Jakhade 				       CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
110569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1106e4b496a3SSwapnil Jakhade 				       CMN_PLL1_INTDIV_M0, 0x01C2);
110769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1108e4b496a3SSwapnil Jakhade 				       CMN_PLL1_FRACDIVL_M0, 0x0000);
110969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1110e4b496a3SSwapnil Jakhade 				       CMN_PLL1_FRACDIVH_M0, 0x0002);
111169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1112e4b496a3SSwapnil Jakhade 				       CMN_PLL1_HIGH_THR_M0, 0x012C);
111369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1114e4b496a3SSwapnil Jakhade 				       CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
1115e4b496a3SSwapnil Jakhade 		if (ssc)
1116e4b496a3SSwapnil Jakhade 			cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x0536,
1117e4b496a3SSwapnil Jakhade 							   0x0069);
1118e4b496a3SSwapnil Jakhade 		break;
1119e4b496a3SSwapnil Jakhade 	/* Setting VCO for 8.1GHz */
1120e4b496a3SSwapnil Jakhade 	case 8100:
112169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1122e4b496a3SSwapnil Jakhade 				       CMN_PLL0_INTDIV_M0, 0x01A5);
112369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1124e4b496a3SSwapnil Jakhade 				       CMN_PLL0_FRACDIVL_M0, 0xE000);
112569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1126e4b496a3SSwapnil Jakhade 				       CMN_PLL0_FRACDIVH_M0, 0x0002);
112769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1128e4b496a3SSwapnil Jakhade 				       CMN_PLL0_HIGH_THR_M0, 0x011A);
112969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1130e4b496a3SSwapnil Jakhade 				       CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
113169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1132e4b496a3SSwapnil Jakhade 				       CMN_PLL1_INTDIV_M0, 0x01A5);
113369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1134e4b496a3SSwapnil Jakhade 				       CMN_PLL1_FRACDIVL_M0, 0xE000);
113569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1136e4b496a3SSwapnil Jakhade 				       CMN_PLL1_FRACDIVH_M0, 0x0002);
113769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1138e4b496a3SSwapnil Jakhade 				       CMN_PLL1_HIGH_THR_M0, 0x011A);
113969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1140e4b496a3SSwapnil Jakhade 				       CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
1141e4b496a3SSwapnil Jakhade 		if (ssc)
1142e4b496a3SSwapnil Jakhade 			cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x04D7,
1143e4b496a3SSwapnil Jakhade 							   0x006A);
1144e4b496a3SSwapnil Jakhade 		break;
1145e4b496a3SSwapnil Jakhade 	}
1146e4b496a3SSwapnil Jakhade 
1147e4b496a3SSwapnil Jakhade 	if (ssc) {
114869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1149e4b496a3SSwapnil Jakhade 				       CMN_PLL0_VCOCAL_PLLCNT_START, 0x025E);
115069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1151e4b496a3SSwapnil Jakhade 				       CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
115269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1153e4b496a3SSwapnil Jakhade 				       CMN_PLL1_VCOCAL_PLLCNT_START, 0x025E);
115469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1155e4b496a3SSwapnil Jakhade 				       CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
1156e4b496a3SSwapnil Jakhade 	} else {
115769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1158e4b496a3SSwapnil Jakhade 				       CMN_PLL0_VCOCAL_PLLCNT_START, 0x0260);
115969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1160e4b496a3SSwapnil Jakhade 				       CMN_PLL1_VCOCAL_PLLCNT_START, 0x0260);
1161e4b496a3SSwapnil Jakhade 		/* Set reset register values to disable SSC */
116269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1163e4b496a3SSwapnil Jakhade 				       CMN_PLL0_SS_CTRL1_M0, 0x0002);
116469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1165e4b496a3SSwapnil Jakhade 				       CMN_PLL0_SS_CTRL2_M0, 0x0000);
116669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1167e4b496a3SSwapnil Jakhade 				       CMN_PLL0_SS_CTRL3_M0, 0x0000);
116869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1169e4b496a3SSwapnil Jakhade 				       CMN_PLL0_SS_CTRL4_M0, 0x0000);
117069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1171e4b496a3SSwapnil Jakhade 				       CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
117269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1173e4b496a3SSwapnil Jakhade 				       CMN_PLL1_SS_CTRL1_M0, 0x0002);
117469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1175e4b496a3SSwapnil Jakhade 				       CMN_PLL1_SS_CTRL2_M0, 0x0000);
117669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1177e4b496a3SSwapnil Jakhade 				       CMN_PLL1_SS_CTRL3_M0, 0x0000);
117869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1179e4b496a3SSwapnil Jakhade 				       CMN_PLL1_SS_CTRL4_M0, 0x0000);
118069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1181e4b496a3SSwapnil Jakhade 				       CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
1182e4b496a3SSwapnil Jakhade 	}
1183e4b496a3SSwapnil Jakhade 
118469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x0099);
118569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x0099);
118669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x0099);
118769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x0099);
1188e4b496a3SSwapnil Jakhade }
1189e4b496a3SSwapnil Jakhade 
1190e4b496a3SSwapnil Jakhade static
119192e9ccc6SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
1192c589e701SYuti Amonkar {
119369d114acSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_common_cdb;
119469d114acSSwapnil Jakhade 
1195c589e701SYuti Amonkar 	/* refclock registers - assumes 25 MHz refclock */
119669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0019);
119769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLPRE_TMR, 0x0032);
119869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLLOCK_TMR, 0x00D1);
119969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLPRE_TMR, 0x0032);
120069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLLOCK_TMR, 0x00D1);
120169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_BGCAL_INIT_TMR, 0x007D);
120269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_BGCAL_ITER_TMR, 0x007D);
120369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_IBCAL_INIT_TMR, 0x0019);
120469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_TXPUCAL_INIT_TMR, 0x001E);
120569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_TXPUCAL_ITER_TMR, 0x0006);
120669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_TXPDCAL_INIT_TMR, 0x001E);
120769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_TXPDCAL_ITER_TMR, 0x0006);
120869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_RXCAL_INIT_TMR, 0x02EE);
120969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_RXCAL_ITER_TMR, 0x0006);
121069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SD_CAL_INIT_TMR, 0x0002);
121169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SD_CAL_ITER_TMR, 0x0002);
121269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SD_CAL_REFTIM_START, 0x000E);
121369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_SD_CAL_PLLCNT_START, 0x012B);
1214ccb1b89dSSwapnil Jakhade 
1215c589e701SYuti Amonkar 	/* PLL registers */
121669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
121769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
121869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
121969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
122069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
122169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
122269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
122369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
122469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_INIT_TMR, 0x00FA);
122569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004);
122669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_INIT_TMR, 0x00FA);
122769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004);
122869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_REFTIM_START, 0x0317);
122969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_TCTRL, 0x0003);
123069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_REFTIM_START, 0x0317);
123169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_TCTRL, 0x0003);
1232e4b496a3SSwapnil Jakhade }
1233e4b496a3SSwapnil Jakhade 
1234e4b496a3SSwapnil Jakhade /*
1235e4b496a3SSwapnil Jakhade  * Set registers responsible for enabling and configuring SSC, with second
1236e4b496a3SSwapnil Jakhade  * register value provided by a parameter.
1237e4b496a3SSwapnil Jakhade  */
1238e4b496a3SSwapnil Jakhade static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy,
1239e4b496a3SSwapnil Jakhade 					     u32 ctrl2_val)
1240e4b496a3SSwapnil Jakhade {
124169d114acSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_common_cdb;
124269d114acSSwapnil Jakhade 
124369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
124469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
124569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x007F);
124669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
124769d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
124869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
124969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x007F);
125069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
1251c589e701SYuti Amonkar }
1252c589e701SYuti Amonkar 
125392e9ccc6SSwapnil Jakhade static
1254e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
1255e4b496a3SSwapnil Jakhade 					   u32 rate, bool ssc)
1256c589e701SYuti Amonkar {
125769d114acSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_common_cdb;
125869d114acSSwapnil Jakhade 
1259c589e701SYuti Amonkar 	/* Assumes 25 MHz refclock */
1260e4b496a3SSwapnil Jakhade 	switch (rate) {
1261c589e701SYuti Amonkar 	/* Setting VCO for 10.8GHz */
1262c589e701SYuti Amonkar 	case 2700:
1263c589e701SYuti Amonkar 	case 5400:
126469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01B0);
126569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
126669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
126769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0120);
126869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01B0);
126969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
127069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
127169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0120);
1272e4b496a3SSwapnil Jakhade 		if (ssc)
1273e4b496a3SSwapnil Jakhade 			cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423);
1274c589e701SYuti Amonkar 		break;
1275c589e701SYuti Amonkar 	/* Setting VCO for 9.72GHz */
1276e4b496a3SSwapnil Jakhade 	case 1620:
1277c589e701SYuti Amonkar 	case 2430:
1278c589e701SYuti Amonkar 	case 3240:
127969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0184);
128069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0xCCCD);
128169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
128269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0104);
128369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0184);
128469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0xCCCD);
128569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
128669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0104);
1287e4b496a3SSwapnil Jakhade 		if (ssc)
1288e4b496a3SSwapnil Jakhade 			cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9);
1289c589e701SYuti Amonkar 		break;
1290c589e701SYuti Amonkar 	/* Setting VCO for 8.64GHz */
1291c589e701SYuti Amonkar 	case 2160:
1292c589e701SYuti Amonkar 	case 4320:
129369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0159);
129469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x999A);
129569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
129669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00E7);
129769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0159);
129869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x999A);
129969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
130069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00E7);
1301e4b496a3SSwapnil Jakhade 		if (ssc)
1302e4b496a3SSwapnil Jakhade 			cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F);
1303c589e701SYuti Amonkar 		break;
1304c589e701SYuti Amonkar 	/* Setting VCO for 8.1GHz */
1305c589e701SYuti Amonkar 	case 8100:
130669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0144);
130769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
130869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
130969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00D8);
131069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0144);
131169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
131269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
131369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00D8);
1314e4b496a3SSwapnil Jakhade 		if (ssc)
1315e4b496a3SSwapnil Jakhade 			cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x031A);
1316c589e701SYuti Amonkar 		break;
1317c589e701SYuti Amonkar 	}
1318c589e701SYuti Amonkar 
131969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
132069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
1321e4b496a3SSwapnil Jakhade 
1322e4b496a3SSwapnil Jakhade 	if (ssc) {
132369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1324e4b496a3SSwapnil Jakhade 				       CMN_PLL0_VCOCAL_PLLCNT_START, 0x0315);
132569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1326e4b496a3SSwapnil Jakhade 				       CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
132769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1328e4b496a3SSwapnil Jakhade 				       CMN_PLL1_VCOCAL_PLLCNT_START, 0x0315);
132969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1330e4b496a3SSwapnil Jakhade 				       CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
1331e4b496a3SSwapnil Jakhade 	} else {
133269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1333e4b496a3SSwapnil Jakhade 				       CMN_PLL0_VCOCAL_PLLCNT_START, 0x0317);
133469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1335e4b496a3SSwapnil Jakhade 				       CMN_PLL1_VCOCAL_PLLCNT_START, 0x0317);
1336e4b496a3SSwapnil Jakhade 		/* Set reset register values to disable SSC */
133769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0002);
133869d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL2_M0, 0x0000);
133969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL3_M0, 0x0000);
134069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0000);
134169d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1342e4b496a3SSwapnil Jakhade 				       CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
134369d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0002);
134469d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL2_M0, 0x0000);
134569d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL3_M0, 0x0000);
134669d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0000);
134769d114acSSwapnil Jakhade 		cdns_torrent_phy_write(regmap,
1348e4b496a3SSwapnil Jakhade 				       CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
1349c589e701SYuti Amonkar 	}
1350c589e701SYuti Amonkar 
135169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x00C7);
135269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x00C7);
135369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x00C7);
135469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x00C7);
1355e4b496a3SSwapnil Jakhade }
1356e4b496a3SSwapnil Jakhade 
1357e4b496a3SSwapnil Jakhade static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
1358e4b496a3SSwapnil Jakhade 					 u32 rate, u32 num_lanes)
1359c589e701SYuti Amonkar {
1360c589e701SYuti Amonkar 	unsigned int clk_sel_val = 0;
1361c589e701SYuti Amonkar 	unsigned int hsclk_div_val = 0;
1362c589e701SYuti Amonkar 	unsigned int i;
1363c589e701SYuti Amonkar 
1364c589e701SYuti Amonkar 	/* 16'h0000 for single DP link configuration */
136569d114acSSwapnil Jakhade 	regmap_field_write(cdns_phy->phy_pll_cfg, 0x0);
1366c589e701SYuti Amonkar 
1367e4b496a3SSwapnil Jakhade 	switch (rate) {
1368c589e701SYuti Amonkar 	case 1620:
1369c589e701SYuti Amonkar 		clk_sel_val = 0x0f01;
1370c589e701SYuti Amonkar 		hsclk_div_val = 2;
1371c589e701SYuti Amonkar 		break;
1372c589e701SYuti Amonkar 	case 2160:
1373c589e701SYuti Amonkar 	case 2430:
1374c589e701SYuti Amonkar 	case 2700:
1375c589e701SYuti Amonkar 		clk_sel_val = 0x0701;
1376c589e701SYuti Amonkar 		hsclk_div_val = 1;
1377c589e701SYuti Amonkar 		break;
1378c589e701SYuti Amonkar 	case 3240:
1379c589e701SYuti Amonkar 		clk_sel_val = 0x0b00;
1380c589e701SYuti Amonkar 		hsclk_div_val = 2;
1381c589e701SYuti Amonkar 		break;
1382c589e701SYuti Amonkar 	case 4320:
1383c589e701SYuti Amonkar 	case 5400:
1384c589e701SYuti Amonkar 		clk_sel_val = 0x0301;
1385c589e701SYuti Amonkar 		hsclk_div_val = 0;
1386c589e701SYuti Amonkar 		break;
1387c589e701SYuti Amonkar 	case 8100:
1388c589e701SYuti Amonkar 		clk_sel_val = 0x0200;
1389c589e701SYuti Amonkar 		hsclk_div_val = 0;
1390c589e701SYuti Amonkar 		break;
1391c589e701SYuti Amonkar 	}
1392c589e701SYuti Amonkar 
139369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_common_cdb,
1394ccb1b89dSSwapnil Jakhade 			       CMN_PDIAG_PLL0_CLK_SEL_M0, clk_sel_val);
139569d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_common_cdb,
1396e4b496a3SSwapnil Jakhade 			       CMN_PDIAG_PLL1_CLK_SEL_M0, clk_sel_val);
1397c589e701SYuti Amonkar 
1398c589e701SYuti Amonkar 	/* PMA lane configuration to deal with multi-link operation */
1399e4b496a3SSwapnil Jakhade 	for (i = 0; i < num_lanes; i++)
140069d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[i],
140169d114acSSwapnil Jakhade 				       XCVR_DIAG_HSCLK_DIV, hsclk_div_val);
1402c589e701SYuti Amonkar }
1403c589e701SYuti Amonkar 
140492e9ccc6SSwapnil Jakhade static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
1405c589e701SYuti Amonkar 					 unsigned int lane)
1406c589e701SYuti Amonkar {
1407e4b496a3SSwapnil Jakhade 	/* Per lane, refclock-dependent receiver detection setting */
1408e4b496a3SSwapnil Jakhade 	if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
140969d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
141069d114acSSwapnil Jakhade 				       TX_RCVDET_ST_TMR, 0x0780);
1411e4b496a3SSwapnil Jakhade 	else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
141269d114acSSwapnil Jakhade 		cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
141369d114acSSwapnil Jakhade 				       TX_RCVDET_ST_TMR, 0x09C4);
1414e4b496a3SSwapnil Jakhade 
1415c589e701SYuti Amonkar 	/* Writing Tx/Rx Power State Controllers registers */
141669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
141769d114acSSwapnil Jakhade 			       TX_PSC_A0, 0x00FB);
141869d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
141969d114acSSwapnil Jakhade 			       TX_PSC_A2, 0x04AA);
142069d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
142169d114acSSwapnil Jakhade 			       TX_PSC_A3, 0x04AA);
142269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
142369d114acSSwapnil Jakhade 			       RX_PSC_A0, 0x0000);
142469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
142569d114acSSwapnil Jakhade 			       RX_PSC_A2, 0x0000);
142669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
142769d114acSSwapnil Jakhade 			       RX_PSC_A3, 0x0000);
1428c589e701SYuti Amonkar 
142969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
143069d114acSSwapnil Jakhade 			       RX_PSC_CAL, 0x0000);
1431e4b496a3SSwapnil Jakhade 
143269d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
143369d114acSSwapnil Jakhade 			       RX_REE_GCSM1_CTRL, 0x0000);
143469d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
143569d114acSSwapnil Jakhade 			       RX_REE_GCSM2_CTRL, 0x0000);
143669d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
143769d114acSSwapnil Jakhade 			       RX_REE_PERGCSM_CTRL, 0x0000);
1438e4b496a3SSwapnil Jakhade 
143969d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
144069d114acSSwapnil Jakhade 			       XCVR_DIAG_BIDI_CTRL, 0x000F);
144169d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
144269d114acSSwapnil Jakhade 			       XCVR_DIAG_PLLDRC_CTRL, 0x0001);
144369d114acSSwapnil Jakhade 	cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
144469d114acSSwapnil Jakhade 			       XCVR_DIAG_HSCLK_SEL, 0x0000);
1445c589e701SYuti Amonkar }
1446c589e701SYuti Amonkar 
144721c79146SSwapnil Jakhade static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
144821c79146SSwapnil Jakhade 					   u32 num_lanes,
144921c79146SSwapnil Jakhade 					   enum phy_powerstate powerstate)
145021c79146SSwapnil Jakhade {
145121c79146SSwapnil Jakhade 	/* Register value for power state for a single byte. */
145221c79146SSwapnil Jakhade 	u32 value_part;
145321c79146SSwapnil Jakhade 	u32 value;
145421c79146SSwapnil Jakhade 	u32 mask;
145521c79146SSwapnil Jakhade 	u32 read_val;
145621c79146SSwapnil Jakhade 	u32 ret;
1457cba472ecSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
145821c79146SSwapnil Jakhade 
145921c79146SSwapnil Jakhade 	switch (powerstate) {
146021c79146SSwapnil Jakhade 	case (POWERSTATE_A0):
146121c79146SSwapnil Jakhade 		value_part = 0x01U;
146221c79146SSwapnil Jakhade 		break;
146321c79146SSwapnil Jakhade 	case (POWERSTATE_A2):
146421c79146SSwapnil Jakhade 		value_part = 0x04U;
146521c79146SSwapnil Jakhade 		break;
146621c79146SSwapnil Jakhade 	default:
146721c79146SSwapnil Jakhade 		/* Powerstate A3 */
146821c79146SSwapnil Jakhade 		value_part = 0x08U;
146921c79146SSwapnil Jakhade 		break;
147021c79146SSwapnil Jakhade 	}
147121c79146SSwapnil Jakhade 
147221c79146SSwapnil Jakhade 	/* Select values of registers and mask, depending on enabled
147321c79146SSwapnil Jakhade 	 * lane count.
147421c79146SSwapnil Jakhade 	 */
147521c79146SSwapnil Jakhade 	switch (num_lanes) {
147621c79146SSwapnil Jakhade 	/* lane 0 */
147721c79146SSwapnil Jakhade 	case (1):
147821c79146SSwapnil Jakhade 		value = value_part;
147921c79146SSwapnil Jakhade 		mask = 0x0000003FU;
148021c79146SSwapnil Jakhade 		break;
148121c79146SSwapnil Jakhade 	/* lanes 0-1 */
148221c79146SSwapnil Jakhade 	case (2):
148321c79146SSwapnil Jakhade 		value = (value_part
148421c79146SSwapnil Jakhade 			 | (value_part << 8));
148521c79146SSwapnil Jakhade 		mask = 0x00003F3FU;
148621c79146SSwapnil Jakhade 		break;
148721c79146SSwapnil Jakhade 	/* lanes 0-3, all */
148821c79146SSwapnil Jakhade 	default:
148921c79146SSwapnil Jakhade 		value = (value_part
149021c79146SSwapnil Jakhade 			 | (value_part << 8)
149121c79146SSwapnil Jakhade 			 | (value_part << 16)
149221c79146SSwapnil Jakhade 			 | (value_part << 24));
149321c79146SSwapnil Jakhade 		mask = 0x3F3F3F3FU;
149421c79146SSwapnil Jakhade 		break;
149521c79146SSwapnil Jakhade 	}
149621c79146SSwapnil Jakhade 
149721c79146SSwapnil Jakhade 	/* Set power state A<n>. */
1498cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, value);
149921c79146SSwapnil Jakhade 	/* Wait, until PHY acknowledges power state completion. */
1500cba472ecSSwapnil Jakhade 	ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_POWER_STATE_ACK,
1501cba472ecSSwapnil Jakhade 				       read_val, (read_val & mask) == value, 0,
150221c79146SSwapnil Jakhade 				       POLL_TIMEOUT_US);
1503cba472ecSSwapnil Jakhade 	cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, 0x00000000);
150421c79146SSwapnil Jakhade 	ndelay(100);
150521c79146SSwapnil Jakhade 
150621c79146SSwapnil Jakhade 	return ret;
150721c79146SSwapnil Jakhade }
150821c79146SSwapnil Jakhade 
1509572d6592SSwapnil Jakhade static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, u32 num_lanes)
1510c589e701SYuti Amonkar {
1511c589e701SYuti Amonkar 	unsigned int read_val;
1512c589e701SYuti Amonkar 	int ret;
1513cba472ecSSwapnil Jakhade 	struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg;
1514c589e701SYuti Amonkar 
1515c589e701SYuti Amonkar 	/*
1516c589e701SYuti Amonkar 	 * waiting for ACK of pma_xcvr_pllclk_en_ln_*, only for the
1517c589e701SYuti Amonkar 	 * master lane
1518c589e701SYuti Amonkar 	 */
1519cba472ecSSwapnil Jakhade 	ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_PLLCLK_EN_ACK,
1520cba472ecSSwapnil Jakhade 				       read_val, read_val & 1,
1521cba472ecSSwapnil Jakhade 				       0, POLL_TIMEOUT_US);
152221c79146SSwapnil Jakhade 	if (ret == -ETIMEDOUT) {
1523c589e701SYuti Amonkar 		dev_err(cdns_phy->dev,
1524c589e701SYuti Amonkar 			"timeout waiting for link PLL clock enable ack\n");
152521c79146SSwapnil Jakhade 		return ret;
1526c589e701SYuti Amonkar 	}
1527c589e701SYuti Amonkar 
1528c589e701SYuti Amonkar 	ndelay(100);
1529c589e701SYuti Amonkar 
1530572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes,
153121c79146SSwapnil Jakhade 					      POWERSTATE_A2);
153221c79146SSwapnil Jakhade 	if (ret)
153321c79146SSwapnil Jakhade 		return ret;
1534c589e701SYuti Amonkar 
1535572d6592SSwapnil Jakhade 	ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes,
153621c79146SSwapnil Jakhade 					      POWERSTATE_A0);
1537c589e701SYuti Amonkar 
153821c79146SSwapnil Jakhade 	return ret;
1539c589e701SYuti Amonkar }
1540c589e701SYuti Amonkar 
1541afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_on(struct phy *phy)
1542afa4ba05SSwapnil Jakhade {
1543afa4ba05SSwapnil Jakhade 	struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
1544afa4ba05SSwapnil Jakhade 	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
1545afa4ba05SSwapnil Jakhade 	int ret;
1546afa4ba05SSwapnil Jakhade 
1547afa4ba05SSwapnil Jakhade 	/* Take the PHY out of reset */
1548afa4ba05SSwapnil Jakhade 	ret = reset_control_deassert(cdns_phy->phy_rst);
1549afa4ba05SSwapnil Jakhade 	if (ret)
1550afa4ba05SSwapnil Jakhade 		return ret;
1551afa4ba05SSwapnil Jakhade 
1552afa4ba05SSwapnil Jakhade 	/* Take the PHY lane group out of reset */
1553afa4ba05SSwapnil Jakhade 	return reset_control_deassert(inst->lnk_rst);
1554afa4ba05SSwapnil Jakhade }
1555afa4ba05SSwapnil Jakhade 
1556afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_off(struct phy *phy)
1557afa4ba05SSwapnil Jakhade {
1558afa4ba05SSwapnil Jakhade 	struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
1559afa4ba05SSwapnil Jakhade 	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
1560afa4ba05SSwapnil Jakhade 	int ret;
1561afa4ba05SSwapnil Jakhade 
1562afa4ba05SSwapnil Jakhade 	ret = reset_control_assert(cdns_phy->phy_rst);
1563afa4ba05SSwapnil Jakhade 	if (ret)
1564afa4ba05SSwapnil Jakhade 		return ret;
1565afa4ba05SSwapnil Jakhade 
1566afa4ba05SSwapnil Jakhade 	return reset_control_assert(inst->lnk_rst);
1567afa4ba05SSwapnil Jakhade }
1568c589e701SYuti Amonkar 
156969d114acSSwapnil Jakhade static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base,
157069d114acSSwapnil Jakhade 				       u32 block_offset,
157169d114acSSwapnil Jakhade 				       u8 reg_offset_shift,
157269d114acSSwapnil Jakhade 				       const struct regmap_config *config)
157369d114acSSwapnil Jakhade {
157469d114acSSwapnil Jakhade 	struct cdns_regmap_cdb_context *ctx;
157569d114acSSwapnil Jakhade 
157669d114acSSwapnil Jakhade 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
157769d114acSSwapnil Jakhade 	if (!ctx)
157869d114acSSwapnil Jakhade 		return ERR_PTR(-ENOMEM);
157969d114acSSwapnil Jakhade 
158069d114acSSwapnil Jakhade 	ctx->dev = dev;
158169d114acSSwapnil Jakhade 	ctx->base = base + block_offset;
158269d114acSSwapnil Jakhade 	ctx->reg_offset_shift = reg_offset_shift;
158369d114acSSwapnil Jakhade 
158469d114acSSwapnil Jakhade 	return devm_regmap_init(dev, NULL, ctx, config);
158569d114acSSwapnil Jakhade }
158669d114acSSwapnil Jakhade 
158769d114acSSwapnil Jakhade static int cdns_regfield_init(struct cdns_torrent_phy *cdns_phy)
158869d114acSSwapnil Jakhade {
158969d114acSSwapnil Jakhade 	struct device *dev = cdns_phy->dev;
159069d114acSSwapnil Jakhade 	struct regmap_field *field;
159169d114acSSwapnil Jakhade 	struct regmap *regmap;
159269d114acSSwapnil Jakhade 
159369d114acSSwapnil Jakhade 	regmap = cdns_phy->regmap_phy_pcs_common_cdb;
159469d114acSSwapnil Jakhade 	field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg);
159569d114acSSwapnil Jakhade 	if (IS_ERR(field)) {
159669d114acSSwapnil Jakhade 		dev_err(dev, "PHY_PLL_CFG reg field init failed\n");
159769d114acSSwapnil Jakhade 		return PTR_ERR(field);
159869d114acSSwapnil Jakhade 	}
159969d114acSSwapnil Jakhade 	cdns_phy->phy_pll_cfg = field;
160069d114acSSwapnil Jakhade 
160169d114acSSwapnil Jakhade 	regmap = cdns_phy->regmap_phy_pma_common_cdb;
160269d114acSSwapnil Jakhade 	field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_2);
160369d114acSSwapnil Jakhade 	if (IS_ERR(field)) {
160469d114acSSwapnil Jakhade 		dev_err(dev, "PHY_PMA_CMN_CTRL2 reg field init failed\n");
160569d114acSSwapnil Jakhade 		return PTR_ERR(field);
160669d114acSSwapnil Jakhade 	}
160769d114acSSwapnil Jakhade 	cdns_phy->phy_pma_cmn_ctrl_2 = field;
160869d114acSSwapnil Jakhade 
160969d114acSSwapnil Jakhade 	regmap = cdns_phy->regmap_phy_pma_common_cdb;
161069d114acSSwapnil Jakhade 	field = devm_regmap_field_alloc(dev, regmap, phy_pma_pll_raw_ctrl);
161169d114acSSwapnil Jakhade 	if (IS_ERR(field)) {
161269d114acSSwapnil Jakhade 		dev_err(dev, "PHY_PMA_PLL_RAW_CTRL reg field init failed\n");
161369d114acSSwapnil Jakhade 		return PTR_ERR(field);
161469d114acSSwapnil Jakhade 	}
161569d114acSSwapnil Jakhade 	cdns_phy->phy_pma_pll_raw_ctrl = field;
161669d114acSSwapnil Jakhade 
1617cba472ecSSwapnil Jakhade 	regmap = cdns_phy->regmap_dptx_phy_reg;
1618cba472ecSSwapnil Jakhade 	field = devm_regmap_field_alloc(dev, regmap, phy_reset_ctrl);
1619cba472ecSSwapnil Jakhade 	if (IS_ERR(field)) {
1620cba472ecSSwapnil Jakhade 		dev_err(dev, "PHY_RESET reg field init failed\n");
1621cba472ecSSwapnil Jakhade 		return PTR_ERR(field);
1622cba472ecSSwapnil Jakhade 	}
1623cba472ecSSwapnil Jakhade 	cdns_phy->phy_reset_ctrl = field;
1624cba472ecSSwapnil Jakhade 
162569d114acSSwapnil Jakhade 	return 0;
162669d114acSSwapnil Jakhade }
162769d114acSSwapnil Jakhade 
162869d114acSSwapnil Jakhade static int cdns_regmap_init_torrent_dp(struct cdns_torrent_phy *cdns_phy,
162969d114acSSwapnil Jakhade 				       void __iomem *sd_base,
163069d114acSSwapnil Jakhade 				       void __iomem *base,
163169d114acSSwapnil Jakhade 				       u8 block_offset_shift,
163269d114acSSwapnil Jakhade 				       u8 reg_offset_shift)
163369d114acSSwapnil Jakhade {
163469d114acSSwapnil Jakhade 	struct device *dev = cdns_phy->dev;
163569d114acSSwapnil Jakhade 	struct regmap *regmap;
163669d114acSSwapnil Jakhade 	u32 block_offset;
163769d114acSSwapnil Jakhade 	int i;
163869d114acSSwapnil Jakhade 
163969d114acSSwapnil Jakhade 	for (i = 0; i < MAX_NUM_LANES; i++) {
164069d114acSSwapnil Jakhade 		block_offset = TORRENT_TX_LANE_CDB_OFFSET(i, block_offset_shift,
164169d114acSSwapnil Jakhade 							  reg_offset_shift);
164269d114acSSwapnil Jakhade 		regmap = cdns_regmap_init(dev, sd_base, block_offset,
164369d114acSSwapnil Jakhade 					  reg_offset_shift,
164469d114acSSwapnil Jakhade 					  &cdns_torrent_tx_lane_cdb_config[i]);
164569d114acSSwapnil Jakhade 		if (IS_ERR(regmap)) {
164669d114acSSwapnil Jakhade 			dev_err(dev, "Failed to init tx lane CDB regmap\n");
164769d114acSSwapnil Jakhade 			return PTR_ERR(regmap);
164869d114acSSwapnil Jakhade 		}
164969d114acSSwapnil Jakhade 		cdns_phy->regmap_tx_lane_cdb[i] = regmap;
165069d114acSSwapnil Jakhade 
165169d114acSSwapnil Jakhade 		block_offset = TORRENT_RX_LANE_CDB_OFFSET(i, block_offset_shift,
165269d114acSSwapnil Jakhade 							  reg_offset_shift);
165369d114acSSwapnil Jakhade 		regmap = cdns_regmap_init(dev, sd_base, block_offset,
165469d114acSSwapnil Jakhade 					  reg_offset_shift,
165569d114acSSwapnil Jakhade 					  &cdns_torrent_rx_lane_cdb_config[i]);
165669d114acSSwapnil Jakhade 		if (IS_ERR(regmap)) {
165769d114acSSwapnil Jakhade 			dev_err(dev, "Failed to init rx lane CDB regmap\n");
165869d114acSSwapnil Jakhade 			return PTR_ERR(regmap);
165969d114acSSwapnil Jakhade 		}
166069d114acSSwapnil Jakhade 		cdns_phy->regmap_rx_lane_cdb[i] = regmap;
166169d114acSSwapnil Jakhade 	}
166269d114acSSwapnil Jakhade 
166369d114acSSwapnil Jakhade 	block_offset = TORRENT_COMMON_CDB_OFFSET;
166469d114acSSwapnil Jakhade 	regmap = cdns_regmap_init(dev, sd_base, block_offset,
166569d114acSSwapnil Jakhade 				  reg_offset_shift,
166669d114acSSwapnil Jakhade 				  &cdns_torrent_common_cdb_config);
166769d114acSSwapnil Jakhade 	if (IS_ERR(regmap)) {
166869d114acSSwapnil Jakhade 		dev_err(dev, "Failed to init common CDB regmap\n");
166969d114acSSwapnil Jakhade 		return PTR_ERR(regmap);
167069d114acSSwapnil Jakhade 	}
167169d114acSSwapnil Jakhade 	cdns_phy->regmap_common_cdb = regmap;
167269d114acSSwapnil Jakhade 
167369d114acSSwapnil Jakhade 	block_offset = TORRENT_PHY_PCS_COMMON_OFFSET(block_offset_shift);
167469d114acSSwapnil Jakhade 	regmap = cdns_regmap_init(dev, sd_base, block_offset,
167569d114acSSwapnil Jakhade 				  reg_offset_shift,
167669d114acSSwapnil Jakhade 				  &cdns_torrent_phy_pcs_cmn_cdb_config);
167769d114acSSwapnil Jakhade 	if (IS_ERR(regmap)) {
167869d114acSSwapnil Jakhade 		dev_err(dev, "Failed to init PHY PCS common CDB regmap\n");
167969d114acSSwapnil Jakhade 		return PTR_ERR(regmap);
168069d114acSSwapnil Jakhade 	}
168169d114acSSwapnil Jakhade 	cdns_phy->regmap_phy_pcs_common_cdb = regmap;
168269d114acSSwapnil Jakhade 
168369d114acSSwapnil Jakhade 	block_offset = TORRENT_PHY_PMA_COMMON_OFFSET(block_offset_shift);
168469d114acSSwapnil Jakhade 	regmap = cdns_regmap_init(dev, sd_base, block_offset,
168569d114acSSwapnil Jakhade 				  reg_offset_shift,
168669d114acSSwapnil Jakhade 				  &cdns_torrent_phy_pma_cmn_cdb_config);
168769d114acSSwapnil Jakhade 	if (IS_ERR(regmap)) {
168869d114acSSwapnil Jakhade 		dev_err(dev, "Failed to init PHY PMA common CDB regmap\n");
168969d114acSSwapnil Jakhade 		return PTR_ERR(regmap);
169069d114acSSwapnil Jakhade 	}
169169d114acSSwapnil Jakhade 	cdns_phy->regmap_phy_pma_common_cdb = regmap;
169269d114acSSwapnil Jakhade 
1693cba472ecSSwapnil Jakhade 	block_offset = TORRENT_DPTX_PHY_OFFSET;
1694cba472ecSSwapnil Jakhade 	regmap = cdns_regmap_init(dev, base, block_offset,
1695cba472ecSSwapnil Jakhade 				  reg_offset_shift,
1696cba472ecSSwapnil Jakhade 				  &cdns_torrent_dptx_phy_config);
1697cba472ecSSwapnil Jakhade 	if (IS_ERR(regmap)) {
1698cba472ecSSwapnil Jakhade 		dev_err(dev, "Failed to init DPTX PHY regmap\n");
1699cba472ecSSwapnil Jakhade 		return PTR_ERR(regmap);
1700cba472ecSSwapnil Jakhade 	}
1701cba472ecSSwapnil Jakhade 	cdns_phy->regmap_dptx_phy_reg = regmap;
1702cba472ecSSwapnil Jakhade 
170369d114acSSwapnil Jakhade 	return 0;
170469d114acSSwapnil Jakhade }
170569d114acSSwapnil Jakhade 
170692e9ccc6SSwapnil Jakhade static int cdns_torrent_phy_probe(struct platform_device *pdev)
1707c589e701SYuti Amonkar {
1708c589e701SYuti Amonkar 	struct resource *regs;
170992e9ccc6SSwapnil Jakhade 	struct cdns_torrent_phy *cdns_phy;
1710c589e701SYuti Amonkar 	struct device *dev = &pdev->dev;
1711c589e701SYuti Amonkar 	struct phy_provider *phy_provider;
1712*29d1fd2fSSwapnil Jakhade 	const struct cdns_torrent_data *data;
1713afa4ba05SSwapnil Jakhade 	struct device_node *child;
1714afa4ba05SSwapnil Jakhade 	int ret, subnodes, node = 0, i;
171569d114acSSwapnil Jakhade 
171669d114acSSwapnil Jakhade 	/* Get init data for this PHY */
1717*29d1fd2fSSwapnil Jakhade 	data = of_device_get_match_data(dev);
1718*29d1fd2fSSwapnil Jakhade 	if (!data)
171969d114acSSwapnil Jakhade 		return -EINVAL;
172069d114acSSwapnil Jakhade 
1721c589e701SYuti Amonkar 	cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
1722c589e701SYuti Amonkar 	if (!cdns_phy)
1723c589e701SYuti Amonkar 		return -ENOMEM;
1724c589e701SYuti Amonkar 
1725afa4ba05SSwapnil Jakhade 	dev_set_drvdata(dev, cdns_phy);
1726afa4ba05SSwapnil Jakhade 	cdns_phy->dev = dev;
1727*29d1fd2fSSwapnil Jakhade 	cdns_phy->init_data = data;
1728c589e701SYuti Amonkar 
1729afa4ba05SSwapnil Jakhade 	cdns_phy->phy_rst = devm_reset_control_get_exclusive_by_index(dev, 0);
1730afa4ba05SSwapnil Jakhade 	if (IS_ERR(cdns_phy->phy_rst)) {
1731afa4ba05SSwapnil Jakhade 		dev_err(dev, "%s: failed to get reset\n",
1732afa4ba05SSwapnil Jakhade 			dev->of_node->full_name);
1733afa4ba05SSwapnil Jakhade 		return PTR_ERR(cdns_phy->phy_rst);
1734afa4ba05SSwapnil Jakhade 	}
1735afa4ba05SSwapnil Jakhade 
1736afa4ba05SSwapnil Jakhade 	cdns_phy->clk = devm_clk_get(dev, "refclk");
1737afa4ba05SSwapnil Jakhade 	if (IS_ERR(cdns_phy->clk)) {
1738afa4ba05SSwapnil Jakhade 		dev_err(dev, "phy ref clock not found\n");
1739afa4ba05SSwapnil Jakhade 		return PTR_ERR(cdns_phy->clk);
1740c589e701SYuti Amonkar 	}
1741c589e701SYuti Amonkar 
1742c589e701SYuti Amonkar 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
174369d114acSSwapnil Jakhade 	cdns_phy->sd_base = devm_ioremap_resource(&pdev->dev, regs);
174469d114acSSwapnil Jakhade 	if (IS_ERR(cdns_phy->sd_base))
174569d114acSSwapnil Jakhade 		return PTR_ERR(cdns_phy->sd_base);
174669d114acSSwapnil Jakhade 
1747afa4ba05SSwapnil Jakhade 	subnodes = of_get_available_child_count(dev->of_node);
1748afa4ba05SSwapnil Jakhade 	if (subnodes == 0) {
1749afa4ba05SSwapnil Jakhade 		dev_err(dev, "No available link subnodes found\n");
1750afa4ba05SSwapnil Jakhade 		return -EINVAL;
1751afa4ba05SSwapnil Jakhade 	} else if (subnodes != 1) {
1752afa4ba05SSwapnil Jakhade 		dev_err(dev, "Driver supports only one link subnode.\n");
1753afa4ba05SSwapnil Jakhade 		return -EINVAL;
1754afa4ba05SSwapnil Jakhade 	}
1755c589e701SYuti Amonkar 
1756afa4ba05SSwapnil Jakhade 	for_each_available_child_of_node(dev->of_node, child) {
1757afa4ba05SSwapnil Jakhade 		struct phy *gphy;
1758c589e701SYuti Amonkar 
1759afa4ba05SSwapnil Jakhade 		cdns_phy->phys[node].lnk_rst =
1760afa4ba05SSwapnil Jakhade 				of_reset_control_array_get_exclusive(child);
1761afa4ba05SSwapnil Jakhade 		if (IS_ERR(cdns_phy->phys[node].lnk_rst)) {
1762afa4ba05SSwapnil Jakhade 			dev_err(dev, "%s: failed to get reset\n",
1763afa4ba05SSwapnil Jakhade 				child->full_name);
1764afa4ba05SSwapnil Jakhade 			ret = PTR_ERR(cdns_phy->phys[node].lnk_rst);
1765afa4ba05SSwapnil Jakhade 			goto put_lnk_rst;
1766afa4ba05SSwapnil Jakhade 		}
1767c589e701SYuti Amonkar 
1768afa4ba05SSwapnil Jakhade 		if (of_property_read_u32(child, "reg",
1769afa4ba05SSwapnil Jakhade 					 &cdns_phy->phys[node].mlane)) {
1770afa4ba05SSwapnil Jakhade 			dev_err(dev, "%s: No \"reg\"-property.\n",
1771afa4ba05SSwapnil Jakhade 				child->full_name);
1772afa4ba05SSwapnil Jakhade 			ret = -EINVAL;
1773afa4ba05SSwapnil Jakhade 			goto put_child;
1774afa4ba05SSwapnil Jakhade 		}
1775afa4ba05SSwapnil Jakhade 
1776afa4ba05SSwapnil Jakhade 		if (cdns_phy->phys[node].mlane != 0) {
1777afa4ba05SSwapnil Jakhade 			dev_err(dev,
1778afa4ba05SSwapnil Jakhade 				"%s: Driver supports only lane-0 as master lane.\n",
1779afa4ba05SSwapnil Jakhade 				child->full_name);
1780afa4ba05SSwapnil Jakhade 			ret = -EINVAL;
1781afa4ba05SSwapnil Jakhade 			goto put_child;
1782afa4ba05SSwapnil Jakhade 		}
1783afa4ba05SSwapnil Jakhade 
1784afa4ba05SSwapnil Jakhade 		if (of_property_read_u32(child, "cdns,phy-type",
1785afa4ba05SSwapnil Jakhade 					 &cdns_phy->phys[node].phy_type)) {
1786afa4ba05SSwapnil Jakhade 			dev_err(dev, "%s: No \"cdns,phy-type\"-property.\n",
1787afa4ba05SSwapnil Jakhade 				child->full_name);
1788afa4ba05SSwapnil Jakhade 			ret = -EINVAL;
1789afa4ba05SSwapnil Jakhade 			goto put_child;
1790afa4ba05SSwapnil Jakhade 		}
1791afa4ba05SSwapnil Jakhade 
1792afa4ba05SSwapnil Jakhade 		cdns_phy->phys[node].num_lanes = DEFAULT_NUM_LANES;
1793afa4ba05SSwapnil Jakhade 		of_property_read_u32(child, "cdns,num-lanes",
1794afa4ba05SSwapnil Jakhade 				     &cdns_phy->phys[node].num_lanes);
1795afa4ba05SSwapnil Jakhade 
1796afa4ba05SSwapnil Jakhade 		if (cdns_phy->phys[node].phy_type == PHY_TYPE_DP) {
1797afa4ba05SSwapnil Jakhade 			switch (cdns_phy->phys[node].num_lanes) {
1798c589e701SYuti Amonkar 			case 1:
1799c589e701SYuti Amonkar 			case 2:
1800c589e701SYuti Amonkar 			case 4:
1801c589e701SYuti Amonkar 			/* valid number of lanes */
1802c589e701SYuti Amonkar 				break;
1803c589e701SYuti Amonkar 			default:
1804c589e701SYuti Amonkar 				dev_err(dev, "unsupported number of lanes: %d\n",
1805afa4ba05SSwapnil Jakhade 					cdns_phy->phys[node].num_lanes);
1806afa4ba05SSwapnil Jakhade 				ret = -EINVAL;
1807afa4ba05SSwapnil Jakhade 				goto put_child;
1808c589e701SYuti Amonkar 			}
1809c589e701SYuti Amonkar 
1810c589e701SYuti Amonkar 			cdns_phy->max_bit_rate = DEFAULT_MAX_BIT_RATE;
1811afa4ba05SSwapnil Jakhade 			of_property_read_u32(child, "cdns,max-bit-rate",
1812afa4ba05SSwapnil Jakhade 					     &cdns_phy->max_bit_rate);
1813c589e701SYuti Amonkar 
1814c589e701SYuti Amonkar 			switch (cdns_phy->max_bit_rate) {
1815e4b496a3SSwapnil Jakhade 			case 1620:
1816c589e701SYuti Amonkar 			case 2160:
1817c589e701SYuti Amonkar 			case 2430:
1818c589e701SYuti Amonkar 			case 2700:
1819c589e701SYuti Amonkar 			case 3240:
1820c589e701SYuti Amonkar 			case 4320:
1821c589e701SYuti Amonkar 			case 5400:
1822c589e701SYuti Amonkar 			case 8100:
1823c589e701SYuti Amonkar 			/* valid bit rate */
1824c589e701SYuti Amonkar 				break;
1825c589e701SYuti Amonkar 			default:
1826c589e701SYuti Amonkar 				dev_err(dev, "unsupported max bit rate: %dMbps\n",
1827c589e701SYuti Amonkar 					cdns_phy->max_bit_rate);
1828afa4ba05SSwapnil Jakhade 				ret = -EINVAL;
1829afa4ba05SSwapnil Jakhade 				goto put_child;
1830c589e701SYuti Amonkar 			}
1831c589e701SYuti Amonkar 
1832afa4ba05SSwapnil Jakhade 			/* DPTX registers */
1833afa4ba05SSwapnil Jakhade 			regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1834afa4ba05SSwapnil Jakhade 			cdns_phy->base = devm_ioremap_resource(&pdev->dev,
1835afa4ba05SSwapnil Jakhade 							       regs);
1836afa4ba05SSwapnil Jakhade 			if (IS_ERR(cdns_phy->base)) {
1837afa4ba05SSwapnil Jakhade 				ret = PTR_ERR(cdns_phy->base);
1838afa4ba05SSwapnil Jakhade 				goto put_child;
1839e4b496a3SSwapnil Jakhade 			}
1840e4b496a3SSwapnil Jakhade 
1841afa4ba05SSwapnil Jakhade 			gphy = devm_phy_create(dev, child,
1842afa4ba05SSwapnil Jakhade 					       &cdns_torrent_phy_ops);
1843afa4ba05SSwapnil Jakhade 			if (IS_ERR(gphy)) {
1844afa4ba05SSwapnil Jakhade 				ret = PTR_ERR(gphy);
1845afa4ba05SSwapnil Jakhade 				goto put_child;
1846afa4ba05SSwapnil Jakhade 			}
1847afa4ba05SSwapnil Jakhade 
1848afa4ba05SSwapnil Jakhade 			dev_info(dev, "%d lanes, max bit rate %d.%03d Gbps\n",
1849afa4ba05SSwapnil Jakhade 				 cdns_phy->phys[node].num_lanes,
1850afa4ba05SSwapnil Jakhade 				 cdns_phy->max_bit_rate / 1000,
1851afa4ba05SSwapnil Jakhade 				 cdns_phy->max_bit_rate % 1000);
18520ffcc378SSwapnil Jakhade 
18530ffcc378SSwapnil Jakhade 			gphy->attrs.bus_width = cdns_phy->phys[node].num_lanes;
18540ffcc378SSwapnil Jakhade 			gphy->attrs.max_link_rate = cdns_phy->max_bit_rate;
18550ffcc378SSwapnil Jakhade 			gphy->attrs.mode = PHY_MODE_DP;
1856afa4ba05SSwapnil Jakhade 		} else {
1857afa4ba05SSwapnil Jakhade 			dev_err(dev, "Driver supports only PHY_TYPE_DP\n");
1858afa4ba05SSwapnil Jakhade 			ret = -ENOTSUPP;
1859afa4ba05SSwapnil Jakhade 			goto put_child;
1860afa4ba05SSwapnil Jakhade 		}
1861afa4ba05SSwapnil Jakhade 		cdns_phy->phys[node].phy = gphy;
1862afa4ba05SSwapnil Jakhade 		phy_set_drvdata(gphy, &cdns_phy->phys[node]);
1863afa4ba05SSwapnil Jakhade 
1864afa4ba05SSwapnil Jakhade 		node++;
1865afa4ba05SSwapnil Jakhade 	}
1866afa4ba05SSwapnil Jakhade 	cdns_phy->nsubnodes = node;
1867c589e701SYuti Amonkar 
186869d114acSSwapnil Jakhade 	ret = cdns_regmap_init_torrent_dp(cdns_phy, cdns_phy->sd_base,
186969d114acSSwapnil Jakhade 					  cdns_phy->base,
187069d114acSSwapnil Jakhade 					  data->block_offset_shift,
187169d114acSSwapnil Jakhade 					  data->reg_offset_shift);
187269d114acSSwapnil Jakhade 	if (ret)
1873afa4ba05SSwapnil Jakhade 		goto put_lnk_rst;
187469d114acSSwapnil Jakhade 
187569d114acSSwapnil Jakhade 	ret = cdns_regfield_init(cdns_phy);
187669d114acSSwapnil Jakhade 	if (ret)
1877afa4ba05SSwapnil Jakhade 		goto put_lnk_rst;
187869d114acSSwapnil Jakhade 
1879c589e701SYuti Amonkar 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1880afa4ba05SSwapnil Jakhade 	if (IS_ERR(phy_provider)) {
1881afa4ba05SSwapnil Jakhade 		ret = PTR_ERR(phy_provider);
1882afa4ba05SSwapnil Jakhade 		goto put_lnk_rst;
1883afa4ba05SSwapnil Jakhade 	}
1884c589e701SYuti Amonkar 
1885afa4ba05SSwapnil Jakhade 	return 0;
1886c589e701SYuti Amonkar 
1887afa4ba05SSwapnil Jakhade put_child:
1888afa4ba05SSwapnil Jakhade 	node++;
1889afa4ba05SSwapnil Jakhade put_lnk_rst:
1890afa4ba05SSwapnil Jakhade 	for (i = 0; i < node; i++)
1891afa4ba05SSwapnil Jakhade 		reset_control_put(cdns_phy->phys[i].lnk_rst);
1892afa4ba05SSwapnil Jakhade 	of_node_put(child);
1893afa4ba05SSwapnil Jakhade 	return ret;
1894afa4ba05SSwapnil Jakhade }
1895afa4ba05SSwapnil Jakhade 
1896afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_remove(struct platform_device *pdev)
1897afa4ba05SSwapnil Jakhade {
1898afa4ba05SSwapnil Jakhade 	struct cdns_torrent_phy *cdns_phy = platform_get_drvdata(pdev);
1899afa4ba05SSwapnil Jakhade 	int i;
1900afa4ba05SSwapnil Jakhade 
1901afa4ba05SSwapnil Jakhade 	reset_control_assert(cdns_phy->phy_rst);
1902afa4ba05SSwapnil Jakhade 	for (i = 0; i < cdns_phy->nsubnodes; i++) {
1903afa4ba05SSwapnil Jakhade 		reset_control_assert(cdns_phy->phys[i].lnk_rst);
1904afa4ba05SSwapnil Jakhade 		reset_control_put(cdns_phy->phys[i].lnk_rst);
1905afa4ba05SSwapnil Jakhade 	}
1906afa4ba05SSwapnil Jakhade 
1907afa4ba05SSwapnil Jakhade 	return 0;
1908c589e701SYuti Amonkar }
1909c589e701SYuti Amonkar 
191069d114acSSwapnil Jakhade static const struct cdns_torrent_data cdns_map_torrent = {
191169d114acSSwapnil Jakhade 	.block_offset_shift = 0x2,
191269d114acSSwapnil Jakhade 	.reg_offset_shift = 0x2,
191369d114acSSwapnil Jakhade };
191469d114acSSwapnil Jakhade 
1915597bf3f1SSwapnil Jakhade static const struct cdns_torrent_data ti_j721e_map_torrent = {
1916597bf3f1SSwapnil Jakhade 	.block_offset_shift = 0x0,
1917597bf3f1SSwapnil Jakhade 	.reg_offset_shift = 0x1,
1918597bf3f1SSwapnil Jakhade };
1919597bf3f1SSwapnil Jakhade 
192092e9ccc6SSwapnil Jakhade static const struct of_device_id cdns_torrent_phy_of_match[] = {
1921c589e701SYuti Amonkar 	{
192269d114acSSwapnil Jakhade 		.compatible = "cdns,torrent-phy",
192369d114acSSwapnil Jakhade 		.data = &cdns_map_torrent,
1924c589e701SYuti Amonkar 	},
1925597bf3f1SSwapnil Jakhade 	{
1926597bf3f1SSwapnil Jakhade 		.compatible = "ti,j721e-serdes-10g",
1927597bf3f1SSwapnil Jakhade 		.data = &ti_j721e_map_torrent,
1928597bf3f1SSwapnil Jakhade 	},
1929c589e701SYuti Amonkar 	{}
1930c589e701SYuti Amonkar };
193192e9ccc6SSwapnil Jakhade MODULE_DEVICE_TABLE(of, cdns_torrent_phy_of_match);
1932c589e701SYuti Amonkar 
193392e9ccc6SSwapnil Jakhade static struct platform_driver cdns_torrent_phy_driver = {
193492e9ccc6SSwapnil Jakhade 	.probe	= cdns_torrent_phy_probe,
1935afa4ba05SSwapnil Jakhade 	.remove = cdns_torrent_phy_remove,
1936c589e701SYuti Amonkar 	.driver = {
193792e9ccc6SSwapnil Jakhade 		.name	= "cdns-torrent-phy",
193892e9ccc6SSwapnil Jakhade 		.of_match_table	= cdns_torrent_phy_of_match,
1939c589e701SYuti Amonkar 	}
1940c589e701SYuti Amonkar };
194192e9ccc6SSwapnil Jakhade module_platform_driver(cdns_torrent_phy_driver);
1942c589e701SYuti Amonkar 
1943c589e701SYuti Amonkar MODULE_AUTHOR("Cadence Design Systems, Inc.");
194492e9ccc6SSwapnil Jakhade MODULE_DESCRIPTION("Cadence Torrent PHY driver");
1945c589e701SYuti Amonkar MODULE_LICENSE("GPL v2");
1946