xref: /linux/drivers/phy/cadence/phy-cadence-sierra.c (revision 871002d788817eb4cd0cd03101d284c3db06ed74)
144d30d62SAlan Douglas // SPDX-License-Identifier: GPL-2.0
244d30d62SAlan Douglas /*
344d30d62SAlan Douglas  * Cadence Sierra PHY Driver
444d30d62SAlan Douglas  *
544d30d62SAlan Douglas  * Copyright (c) 2018 Cadence Design Systems
644d30d62SAlan Douglas  * Author: Alan Douglas <adouglas@cadence.com>
744d30d62SAlan Douglas  *
844d30d62SAlan Douglas  */
944d30d62SAlan Douglas #include <linux/clk.h>
1044d30d62SAlan Douglas #include <linux/delay.h>
1144d30d62SAlan Douglas #include <linux/err.h>
1244d30d62SAlan Douglas #include <linux/io.h>
1344d30d62SAlan Douglas #include <linux/module.h>
1444d30d62SAlan Douglas #include <linux/phy/phy.h>
1544d30d62SAlan Douglas #include <linux/platform_device.h>
1644d30d62SAlan Douglas #include <linux/pm_runtime.h>
1744d30d62SAlan Douglas #include <linux/regmap.h>
1844d30d62SAlan Douglas #include <linux/reset.h>
1944d30d62SAlan Douglas #include <linux/slab.h>
2044d30d62SAlan Douglas #include <linux/of.h>
2144d30d62SAlan Douglas #include <linux/of_platform.h>
2244d30d62SAlan Douglas #include <dt-bindings/phy/phy.h>
2344d30d62SAlan Douglas 
2444d30d62SAlan Douglas /* PHY register offsets */
25380f5708SKishon Vijay Abraham I #define SIERRA_COMMON_CDB_OFFSET			0x0
26380f5708SKishon Vijay Abraham I #define SIERRA_MACRO_ID_REG				0x0
27*871002d7SAnil Varughese #define SIERRA_CMN_PLLLC_MODE_PREG			0x48
28*871002d7SAnil Varughese #define SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG		0x49
29*871002d7SAnil Varughese #define SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG		0x4A
30*871002d7SAnil Varughese #define SIERRA_CMN_PLLLC_LOCK_CNTSTART_PREG		0x4B
31*871002d7SAnil Varughese #define SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG		0x4F
32*871002d7SAnil Varughese #define SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG		0x50
33*871002d7SAnil Varughese #define SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG	0x62
34380f5708SKishon Vijay Abraham I 
35380f5708SKishon Vijay Abraham I #define SIERRA_LANE_CDB_OFFSET(ln, block_offset, reg_offset)	\
36380f5708SKishon Vijay Abraham I 				((0x4000 << (block_offset)) + \
37380f5708SKishon Vijay Abraham I 				 (((ln) << 9) << (reg_offset)))
38aead5fd6SKishon Vijay Abraham I 
39aead5fd6SKishon Vijay Abraham I #define SIERRA_DET_STANDEC_A_PREG			0x000
40aead5fd6SKishon Vijay Abraham I #define SIERRA_DET_STANDEC_B_PREG			0x001
41aead5fd6SKishon Vijay Abraham I #define SIERRA_DET_STANDEC_C_PREG			0x002
42aead5fd6SKishon Vijay Abraham I #define SIERRA_DET_STANDEC_D_PREG			0x003
43aead5fd6SKishon Vijay Abraham I #define SIERRA_DET_STANDEC_E_PREG			0x004
44*871002d7SAnil Varughese #define SIERRA_PSM_LANECAL_DLY_A1_RESETS_PREG		0x008
45*871002d7SAnil Varughese #define SIERRA_PSM_A0IN_TMR_PREG			0x009
46aead5fd6SKishon Vijay Abraham I #define SIERRA_PSM_DIAG_PREG				0x015
47aead5fd6SKishon Vijay Abraham I #define SIERRA_PSC_TX_A0_PREG				0x028
48aead5fd6SKishon Vijay Abraham I #define SIERRA_PSC_TX_A1_PREG				0x029
49aead5fd6SKishon Vijay Abraham I #define SIERRA_PSC_TX_A2_PREG				0x02A
50aead5fd6SKishon Vijay Abraham I #define SIERRA_PSC_TX_A3_PREG				0x02B
51aead5fd6SKishon Vijay Abraham I #define SIERRA_PSC_RX_A0_PREG				0x030
52aead5fd6SKishon Vijay Abraham I #define SIERRA_PSC_RX_A1_PREG				0x031
53aead5fd6SKishon Vijay Abraham I #define SIERRA_PSC_RX_A2_PREG				0x032
54aead5fd6SKishon Vijay Abraham I #define SIERRA_PSC_RX_A3_PREG				0x033
55aead5fd6SKishon Vijay Abraham I #define SIERRA_PLLCTRL_SUBRATE_PREG			0x03A
56aead5fd6SKishon Vijay Abraham I #define SIERRA_PLLCTRL_GEN_D_PREG			0x03E
57*871002d7SAnil Varughese #define SIERRA_PLLCTRL_CPGAIN_MODE_PREG			0x03F
58*871002d7SAnil Varughese #define SIERRA_CLKPATH_BIASTRIM_PREG			0x04B
59*871002d7SAnil Varughese #define SIERRA_DFE_BIASTRIM_PREG			0x04C
60aead5fd6SKishon Vijay Abraham I #define SIERRA_DRVCTRL_ATTEN_PREG			0x06A
61aead5fd6SKishon Vijay Abraham I #define SIERRA_CLKPATHCTRL_TMR_PREG			0x081
62*871002d7SAnil Varughese #define SIERRA_RX_CREQ_FLTR_A_MODE3_PREG		0x085
63*871002d7SAnil Varughese #define SIERRA_RX_CREQ_FLTR_A_MODE2_PREG		0x086
64aead5fd6SKishon Vijay Abraham I #define SIERRA_RX_CREQ_FLTR_A_MODE1_PREG		0x087
65aead5fd6SKishon Vijay Abraham I #define SIERRA_RX_CREQ_FLTR_A_MODE0_PREG		0x088
66aead5fd6SKishon Vijay Abraham I #define SIERRA_CREQ_CCLKDET_MODE01_PREG			0x08E
67aead5fd6SKishon Vijay Abraham I #define SIERRA_RX_CTLE_MAINTENANCE_PREG			0x091
68aead5fd6SKishon Vijay Abraham I #define SIERRA_CREQ_FSMCLK_SEL_PREG			0x092
69*871002d7SAnil Varughese #define SIERRA_CREQ_EQ_CTRL_PREG			0x093
70*871002d7SAnil Varughese #define SIERRA_CREQ_SPARE_PREG				0x096
71*871002d7SAnil Varughese #define SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG		0x097
72aead5fd6SKishon Vijay Abraham I #define SIERRA_CTLELUT_CTRL_PREG			0x098
73aead5fd6SKishon Vijay Abraham I #define SIERRA_DFE_ECMP_RATESEL_PREG			0x0C0
74aead5fd6SKishon Vijay Abraham I #define SIERRA_DFE_SMP_RATESEL_PREG			0x0C1
75*871002d7SAnil Varughese #define SIERRA_DEQ_PHALIGN_CTRL				0x0C4
76*871002d7SAnil Varughese #define SIERRA_DEQ_CONCUR_CTRL1_PREG			0x0C8
77*871002d7SAnil Varughese #define SIERRA_DEQ_CONCUR_CTRL2_PREG			0x0C9
78*871002d7SAnil Varughese #define SIERRA_DEQ_EPIPWR_CTRL2_PREG			0x0CD
79*871002d7SAnil Varughese #define SIERRA_DEQ_FAST_MAINT_CYCLES_PREG		0x0CE
80*871002d7SAnil Varughese #define SIERRA_DEQ_ERRCMP_CTRL_PREG			0x0D0
81*871002d7SAnil Varughese #define SIERRA_DEQ_OFFSET_CTRL_PREG			0x0D8
82*871002d7SAnil Varughese #define SIERRA_DEQ_GAIN_CTRL_PREG			0x0E0
83aead5fd6SKishon Vijay Abraham I #define SIERRA_DEQ_VGATUNE_CTRL_PREG			0x0E1
84*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT0				0x0E8
85*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT1				0x0E9
86*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT2				0x0EA
87*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT3				0x0EB
88*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT4				0x0EC
89*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT5				0x0ED
90*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT6				0x0EE
91*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT7				0x0EF
92*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT8				0x0F0
93*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT9				0x0F1
94*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT10				0x0F2
95*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT11				0x0F3
96*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT12				0x0F4
97*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT13				0x0F5
98*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT14				0x0F6
99*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT15				0x0F7
100*871002d7SAnil Varughese #define SIERRA_DEQ_GLUT16				0x0F8
101*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT0				0x108
102*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT1				0x109
103*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT2				0x10A
104*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT3				0x10B
105*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT4				0x10C
106*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT5				0x10D
107*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT6				0x10E
108*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT7				0x10F
109*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT8				0x110
110*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT9				0x111
111*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT10				0x112
112*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT11				0x113
113*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT12				0x114
114*871002d7SAnil Varughese #define SIERRA_DEQ_ALUT13				0x115
115*871002d7SAnil Varughese #define SIERRA_DEQ_DFETAP_CTRL_PREG			0x128
116*871002d7SAnil Varughese #define SIERRA_DFE_EN_1010_IGNORE_PREG			0x134
117*871002d7SAnil Varughese #define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG		0x150
118*871002d7SAnil Varughese #define SIERRA_DEQ_TAU_CTRL2_PREG			0x151
119*871002d7SAnil Varughese #define SIERRA_DEQ_PICTRL_PREG				0x161
120*871002d7SAnil Varughese #define SIERRA_CPICAL_TMRVAL_MODE1_PREG			0x170
121*871002d7SAnil Varughese #define SIERRA_CPICAL_TMRVAL_MODE0_PREG			0x171
122*871002d7SAnil Varughese #define SIERRA_CPICAL_PICNT_MODE1_PREG			0x174
123aead5fd6SKishon Vijay Abraham I #define SIERRA_CPI_OUTBUF_RATESEL_PREG			0x17C
124*871002d7SAnil Varughese #define SIERRA_CPICAL_RES_STARTCODE_MODE23_PREG		0x183
125*871002d7SAnil Varughese #define SIERRA_LFPSDET_SUPPORT_PREG			0x188
126aead5fd6SKishon Vijay Abraham I #define SIERRA_LFPSFILT_NS_PREG				0x18A
127aead5fd6SKishon Vijay Abraham I #define SIERRA_LFPSFILT_RD_PREG				0x18B
128aead5fd6SKishon Vijay Abraham I #define SIERRA_LFPSFILT_MP_PREG				0x18C
129*871002d7SAnil Varughese #define SIERRA_SIGDET_SUPPORT_PREG			0x190
130aead5fd6SKishon Vijay Abraham I #define SIERRA_SDFILT_H2L_A_PREG			0x191
131*871002d7SAnil Varughese #define SIERRA_SDFILT_L2H_PREG				0x193
132*871002d7SAnil Varughese #define SIERRA_RXBUFFER_CTLECTRL_PREG			0x19E
133*871002d7SAnil Varughese #define SIERRA_RXBUFFER_RCDFECTRL_PREG			0x19F
134*871002d7SAnil Varughese #define SIERRA_RXBUFFER_DFECTRL_PREG			0x1A0
135*871002d7SAnil Varughese #define SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG		0x14F
136*871002d7SAnil Varughese #define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG		0x150
137380f5708SKishon Vijay Abraham I 
138380f5708SKishon Vijay Abraham I #define SIERRA_PHY_CONFIG_CTRL_OFFSET(block_offset)	\
139380f5708SKishon Vijay Abraham I 				      (0xc000 << (block_offset))
140380f5708SKishon Vijay Abraham I #define SIERRA_PHY_PLL_CFG				0xe
14144d30d62SAlan Douglas 
14244d30d62SAlan Douglas #define SIERRA_MACRO_ID					0x00007364
14344d30d62SAlan Douglas #define SIERRA_MAX_LANES				4
14444d30d62SAlan Douglas 
145380f5708SKishon Vijay Abraham I static const struct reg_field macro_id_type =
146380f5708SKishon Vijay Abraham I 				REG_FIELD(SIERRA_MACRO_ID_REG, 0, 15);
147380f5708SKishon Vijay Abraham I static const struct reg_field phy_pll_cfg_1 =
148380f5708SKishon Vijay Abraham I 				REG_FIELD(SIERRA_PHY_PLL_CFG, 1, 1);
149380f5708SKishon Vijay Abraham I 
15044d30d62SAlan Douglas struct cdns_sierra_inst {
15144d30d62SAlan Douglas 	struct phy *phy;
15244d30d62SAlan Douglas 	u32 phy_type;
15344d30d62SAlan Douglas 	u32 num_lanes;
15444d30d62SAlan Douglas 	u32 mlane;
15544d30d62SAlan Douglas 	struct reset_control *lnk_rst;
15644d30d62SAlan Douglas };
15744d30d62SAlan Douglas 
15844d30d62SAlan Douglas struct cdns_reg_pairs {
15944d30d62SAlan Douglas 	u16 val;
16044d30d62SAlan Douglas 	u32 off;
16144d30d62SAlan Douglas };
16244d30d62SAlan Douglas 
16344d30d62SAlan Douglas struct cdns_sierra_data {
16444d30d62SAlan Douglas 		u32 id_value;
165380f5708SKishon Vijay Abraham I 		u8 block_offset_shift;
166380f5708SKishon Vijay Abraham I 		u8 reg_offset_shift;
167*871002d7SAnil Varughese 		u32 pcie_cmn_regs;
168*871002d7SAnil Varughese 		u32 pcie_ln_regs;
169*871002d7SAnil Varughese 		u32 usb_cmn_regs;
170*871002d7SAnil Varughese 		u32 usb_ln_regs;
171*871002d7SAnil Varughese 		struct cdns_reg_pairs *pcie_cmn_vals;
172*871002d7SAnil Varughese 		struct cdns_reg_pairs *pcie_ln_vals;
173*871002d7SAnil Varughese 		struct cdns_reg_pairs *usb_cmn_vals;
174*871002d7SAnil Varughese 		struct cdns_reg_pairs *usb_ln_vals;
17544d30d62SAlan Douglas };
17644d30d62SAlan Douglas 
177380f5708SKishon Vijay Abraham I struct cdns_regmap_cdb_context {
17844d30d62SAlan Douglas 	struct device *dev;
17944d30d62SAlan Douglas 	void __iomem *base;
180380f5708SKishon Vijay Abraham I 	u8 reg_offset_shift;
181380f5708SKishon Vijay Abraham I };
182380f5708SKishon Vijay Abraham I 
183380f5708SKishon Vijay Abraham I struct cdns_sierra_phy {
184380f5708SKishon Vijay Abraham I 	struct device *dev;
185380f5708SKishon Vijay Abraham I 	struct regmap *regmap;
18644d30d62SAlan Douglas 	struct cdns_sierra_data *init_data;
18744d30d62SAlan Douglas 	struct cdns_sierra_inst phys[SIERRA_MAX_LANES];
18844d30d62SAlan Douglas 	struct reset_control *phy_rst;
18944d30d62SAlan Douglas 	struct reset_control *apb_rst;
190380f5708SKishon Vijay Abraham I 	struct regmap *regmap_lane_cdb[SIERRA_MAX_LANES];
191380f5708SKishon Vijay Abraham I 	struct regmap *regmap_phy_config_ctrl;
192380f5708SKishon Vijay Abraham I 	struct regmap *regmap_common_cdb;
193380f5708SKishon Vijay Abraham I 	struct regmap_field *macro_id_type;
194380f5708SKishon Vijay Abraham I 	struct regmap_field *phy_pll_cfg_1;
19544d30d62SAlan Douglas 	struct clk *clk;
19644d30d62SAlan Douglas 	int nsubnodes;
19744d30d62SAlan Douglas 	bool autoconf;
19844d30d62SAlan Douglas };
19944d30d62SAlan Douglas 
200380f5708SKishon Vijay Abraham I static int cdns_regmap_write(void *context, unsigned int reg, unsigned int val)
201380f5708SKishon Vijay Abraham I {
202380f5708SKishon Vijay Abraham I 	struct cdns_regmap_cdb_context *ctx = context;
203380f5708SKishon Vijay Abraham I 	u32 offset = reg << ctx->reg_offset_shift;
204380f5708SKishon Vijay Abraham I 
205380f5708SKishon Vijay Abraham I 	writew(val, ctx->base + offset);
206380f5708SKishon Vijay Abraham I 
207380f5708SKishon Vijay Abraham I 	return 0;
208380f5708SKishon Vijay Abraham I }
209380f5708SKishon Vijay Abraham I 
210380f5708SKishon Vijay Abraham I static int cdns_regmap_read(void *context, unsigned int reg, unsigned int *val)
211380f5708SKishon Vijay Abraham I {
212380f5708SKishon Vijay Abraham I 	struct cdns_regmap_cdb_context *ctx = context;
213380f5708SKishon Vijay Abraham I 	u32 offset = reg << ctx->reg_offset_shift;
214380f5708SKishon Vijay Abraham I 
215380f5708SKishon Vijay Abraham I 	*val = readw(ctx->base + offset);
216380f5708SKishon Vijay Abraham I 	return 0;
217380f5708SKishon Vijay Abraham I }
218380f5708SKishon Vijay Abraham I 
219380f5708SKishon Vijay Abraham I #define SIERRA_LANE_CDB_REGMAP_CONF(n) \
220380f5708SKishon Vijay Abraham I { \
221380f5708SKishon Vijay Abraham I 	.name = "sierra_lane" n "_cdb", \
222380f5708SKishon Vijay Abraham I 	.reg_stride = 1, \
223380f5708SKishon Vijay Abraham I 	.fast_io = true, \
224380f5708SKishon Vijay Abraham I 	.reg_write = cdns_regmap_write, \
225380f5708SKishon Vijay Abraham I 	.reg_read = cdns_regmap_read, \
226380f5708SKishon Vijay Abraham I }
227380f5708SKishon Vijay Abraham I 
228380f5708SKishon Vijay Abraham I static struct regmap_config cdns_sierra_lane_cdb_config[] = {
229380f5708SKishon Vijay Abraham I 	SIERRA_LANE_CDB_REGMAP_CONF("0"),
230380f5708SKishon Vijay Abraham I 	SIERRA_LANE_CDB_REGMAP_CONF("1"),
231380f5708SKishon Vijay Abraham I 	SIERRA_LANE_CDB_REGMAP_CONF("2"),
232380f5708SKishon Vijay Abraham I 	SIERRA_LANE_CDB_REGMAP_CONF("3"),
233380f5708SKishon Vijay Abraham I };
234380f5708SKishon Vijay Abraham I 
235380f5708SKishon Vijay Abraham I static struct regmap_config cdns_sierra_common_cdb_config = {
236380f5708SKishon Vijay Abraham I 	.name = "sierra_common_cdb",
237380f5708SKishon Vijay Abraham I 	.reg_stride = 1,
238380f5708SKishon Vijay Abraham I 	.fast_io = true,
239380f5708SKishon Vijay Abraham I 	.reg_write = cdns_regmap_write,
240380f5708SKishon Vijay Abraham I 	.reg_read = cdns_regmap_read,
241380f5708SKishon Vijay Abraham I };
242380f5708SKishon Vijay Abraham I 
243380f5708SKishon Vijay Abraham I static struct regmap_config cdns_sierra_phy_config_ctrl_config = {
244380f5708SKishon Vijay Abraham I 	.name = "sierra_phy_config_ctrl",
245380f5708SKishon Vijay Abraham I 	.reg_stride = 1,
246380f5708SKishon Vijay Abraham I 	.fast_io = true,
247380f5708SKishon Vijay Abraham I 	.reg_write = cdns_regmap_write,
248380f5708SKishon Vijay Abraham I 	.reg_read = cdns_regmap_read,
249380f5708SKishon Vijay Abraham I };
250380f5708SKishon Vijay Abraham I 
251cedcc2e2SKishon Vijay Abraham I static int cdns_sierra_phy_init(struct phy *gphy)
25244d30d62SAlan Douglas {
25344d30d62SAlan Douglas 	struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
25444d30d62SAlan Douglas 	struct cdns_sierra_phy *phy = dev_get_drvdata(gphy->dev.parent);
255380f5708SKishon Vijay Abraham I 	struct regmap *regmap = phy->regmap;
25644d30d62SAlan Douglas 	int i, j;
257*871002d7SAnil Varughese 	struct cdns_reg_pairs *cmn_vals, *ln_vals;
258*871002d7SAnil Varughese 	u32 num_cmn_regs, num_ln_regs;
25944d30d62SAlan Douglas 
260cedcc2e2SKishon Vijay Abraham I 	/* Initialise the PHY registers, unless auto configured */
261cedcc2e2SKishon Vijay Abraham I 	if (phy->autoconf)
262cedcc2e2SKishon Vijay Abraham I 		return 0;
263cedcc2e2SKishon Vijay Abraham I 
26444d30d62SAlan Douglas 	if (ins->phy_type == PHY_TYPE_PCIE) {
265*871002d7SAnil Varughese 		num_cmn_regs = phy->init_data->pcie_cmn_regs;
266*871002d7SAnil Varughese 		num_ln_regs = phy->init_data->pcie_ln_regs;
267*871002d7SAnil Varughese 		cmn_vals = phy->init_data->pcie_cmn_vals;
268*871002d7SAnil Varughese 		ln_vals = phy->init_data->pcie_ln_vals;
26944d30d62SAlan Douglas 	} else if (ins->phy_type == PHY_TYPE_USB3) {
270*871002d7SAnil Varughese 		num_cmn_regs = phy->init_data->usb_cmn_regs;
271*871002d7SAnil Varughese 		num_ln_regs = phy->init_data->usb_ln_regs;
272*871002d7SAnil Varughese 		cmn_vals = phy->init_data->usb_cmn_vals;
273*871002d7SAnil Varughese 		ln_vals = phy->init_data->usb_ln_vals;
27444d30d62SAlan Douglas 	} else {
275cedcc2e2SKishon Vijay Abraham I 		return -EINVAL;
27644d30d62SAlan Douglas 	}
277*871002d7SAnil Varughese 
278*871002d7SAnil Varughese 	regmap = phy->regmap_common_cdb;
279*871002d7SAnil Varughese 	for (j = 0; j < num_cmn_regs ; j++)
280*871002d7SAnil Varughese 		regmap_write(regmap, cmn_vals[j].off, cmn_vals[j].val);
281*871002d7SAnil Varughese 
282380f5708SKishon Vijay Abraham I 	for (i = 0; i < ins->num_lanes; i++) {
283*871002d7SAnil Varughese 		for (j = 0; j < num_ln_regs ; j++) {
284380f5708SKishon Vijay Abraham I 			regmap = phy->regmap_lane_cdb[i + ins->mlane];
285*871002d7SAnil Varughese 			regmap_write(regmap, ln_vals[j].off, ln_vals[j].val);
286380f5708SKishon Vijay Abraham I 		}
287380f5708SKishon Vijay Abraham I 	}
288cedcc2e2SKishon Vijay Abraham I 
289cedcc2e2SKishon Vijay Abraham I 	return 0;
29044d30d62SAlan Douglas }
29144d30d62SAlan Douglas 
29244d30d62SAlan Douglas static int cdns_sierra_phy_on(struct phy *gphy)
29344d30d62SAlan Douglas {
29444d30d62SAlan Douglas 	struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
29544d30d62SAlan Douglas 
29644d30d62SAlan Douglas 	/* Take the PHY lane group out of reset */
29744d30d62SAlan Douglas 	return reset_control_deassert(ins->lnk_rst);
29844d30d62SAlan Douglas }
29944d30d62SAlan Douglas 
30044d30d62SAlan Douglas static int cdns_sierra_phy_off(struct phy *gphy)
30144d30d62SAlan Douglas {
30244d30d62SAlan Douglas 	struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
30344d30d62SAlan Douglas 
30444d30d62SAlan Douglas 	return reset_control_assert(ins->lnk_rst);
30544d30d62SAlan Douglas }
30644d30d62SAlan Douglas 
30744d30d62SAlan Douglas static const struct phy_ops ops = {
308cedcc2e2SKishon Vijay Abraham I 	.init		= cdns_sierra_phy_init,
30944d30d62SAlan Douglas 	.power_on	= cdns_sierra_phy_on,
31044d30d62SAlan Douglas 	.power_off	= cdns_sierra_phy_off,
31144d30d62SAlan Douglas 	.owner		= THIS_MODULE,
31244d30d62SAlan Douglas };
31344d30d62SAlan Douglas 
31444d30d62SAlan Douglas static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
31544d30d62SAlan Douglas 				    struct device_node *child)
31644d30d62SAlan Douglas {
31744d30d62SAlan Douglas 	if (of_property_read_u32(child, "reg", &inst->mlane))
31844d30d62SAlan Douglas 		return -EINVAL;
31944d30d62SAlan Douglas 
32044d30d62SAlan Douglas 	if (of_property_read_u32(child, "cdns,num-lanes", &inst->num_lanes))
32144d30d62SAlan Douglas 		return -EINVAL;
32244d30d62SAlan Douglas 
32344d30d62SAlan Douglas 	if (of_property_read_u32(child, "cdns,phy-type", &inst->phy_type))
32444d30d62SAlan Douglas 		return -EINVAL;
32544d30d62SAlan Douglas 
32644d30d62SAlan Douglas 	return 0;
32744d30d62SAlan Douglas }
32844d30d62SAlan Douglas 
32944d30d62SAlan Douglas static const struct of_device_id cdns_sierra_id_table[];
33044d30d62SAlan Douglas 
331380f5708SKishon Vijay Abraham I static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base,
332380f5708SKishon Vijay Abraham I 				       u32 block_offset, u8 reg_offset_shift,
333380f5708SKishon Vijay Abraham I 				       const struct regmap_config *config)
334380f5708SKishon Vijay Abraham I {
335380f5708SKishon Vijay Abraham I 	struct cdns_regmap_cdb_context *ctx;
336380f5708SKishon Vijay Abraham I 
337380f5708SKishon Vijay Abraham I 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
338380f5708SKishon Vijay Abraham I 	if (!ctx)
339380f5708SKishon Vijay Abraham I 		return ERR_PTR(-ENOMEM);
340380f5708SKishon Vijay Abraham I 
341380f5708SKishon Vijay Abraham I 	ctx->dev = dev;
342380f5708SKishon Vijay Abraham I 	ctx->base = base + block_offset;
343380f5708SKishon Vijay Abraham I 	ctx->reg_offset_shift = reg_offset_shift;
344380f5708SKishon Vijay Abraham I 
345380f5708SKishon Vijay Abraham I 	return devm_regmap_init(dev, NULL, ctx, config);
346380f5708SKishon Vijay Abraham I }
347380f5708SKishon Vijay Abraham I 
348380f5708SKishon Vijay Abraham I static int cdns_regfield_init(struct cdns_sierra_phy *sp)
349380f5708SKishon Vijay Abraham I {
350380f5708SKishon Vijay Abraham I 	struct device *dev = sp->dev;
351380f5708SKishon Vijay Abraham I 	struct regmap_field *field;
352380f5708SKishon Vijay Abraham I 	struct regmap *regmap;
353380f5708SKishon Vijay Abraham I 
354380f5708SKishon Vijay Abraham I 	regmap = sp->regmap_common_cdb;
355380f5708SKishon Vijay Abraham I 	field = devm_regmap_field_alloc(dev, regmap, macro_id_type);
356380f5708SKishon Vijay Abraham I 	if (IS_ERR(field)) {
357380f5708SKishon Vijay Abraham I 		dev_err(dev, "MACRO_ID_TYPE reg field init failed\n");
358380f5708SKishon Vijay Abraham I 		return PTR_ERR(field);
359380f5708SKishon Vijay Abraham I 	}
360380f5708SKishon Vijay Abraham I 	sp->macro_id_type = field;
361380f5708SKishon Vijay Abraham I 
362380f5708SKishon Vijay Abraham I 	regmap = sp->regmap_phy_config_ctrl;
363380f5708SKishon Vijay Abraham I 	field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg_1);
364380f5708SKishon Vijay Abraham I 	if (IS_ERR(field)) {
365380f5708SKishon Vijay Abraham I 		dev_err(dev, "PHY_PLL_CFG_1 reg field init failed\n");
366380f5708SKishon Vijay Abraham I 		return PTR_ERR(field);
367380f5708SKishon Vijay Abraham I 	}
368380f5708SKishon Vijay Abraham I 	sp->phy_pll_cfg_1 = field;
369380f5708SKishon Vijay Abraham I 
370380f5708SKishon Vijay Abraham I 	return 0;
371380f5708SKishon Vijay Abraham I }
372380f5708SKishon Vijay Abraham I 
373380f5708SKishon Vijay Abraham I static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp,
374380f5708SKishon Vijay Abraham I 				   void __iomem *base, u8 block_offset_shift,
375380f5708SKishon Vijay Abraham I 				   u8 reg_offset_shift)
376380f5708SKishon Vijay Abraham I {
377380f5708SKishon Vijay Abraham I 	struct device *dev = sp->dev;
378380f5708SKishon Vijay Abraham I 	struct regmap *regmap;
379380f5708SKishon Vijay Abraham I 	u32 block_offset;
380380f5708SKishon Vijay Abraham I 	int i;
381380f5708SKishon Vijay Abraham I 
382380f5708SKishon Vijay Abraham I 	for (i = 0; i < SIERRA_MAX_LANES; i++) {
383380f5708SKishon Vijay Abraham I 		block_offset = SIERRA_LANE_CDB_OFFSET(i, block_offset_shift,
384380f5708SKishon Vijay Abraham I 						      reg_offset_shift);
385380f5708SKishon Vijay Abraham I 		regmap = cdns_regmap_init(dev, base, block_offset,
386380f5708SKishon Vijay Abraham I 					  reg_offset_shift,
387380f5708SKishon Vijay Abraham I 					  &cdns_sierra_lane_cdb_config[i]);
388380f5708SKishon Vijay Abraham I 		if (IS_ERR(regmap)) {
389380f5708SKishon Vijay Abraham I 			dev_err(dev, "Failed to init lane CDB regmap\n");
390380f5708SKishon Vijay Abraham I 			return PTR_ERR(regmap);
391380f5708SKishon Vijay Abraham I 		}
392380f5708SKishon Vijay Abraham I 		sp->regmap_lane_cdb[i] = regmap;
393380f5708SKishon Vijay Abraham I 	}
394380f5708SKishon Vijay Abraham I 
395380f5708SKishon Vijay Abraham I 	regmap = cdns_regmap_init(dev, base, SIERRA_COMMON_CDB_OFFSET,
396380f5708SKishon Vijay Abraham I 				  reg_offset_shift,
397380f5708SKishon Vijay Abraham I 				  &cdns_sierra_common_cdb_config);
398380f5708SKishon Vijay Abraham I 	if (IS_ERR(regmap)) {
399380f5708SKishon Vijay Abraham I 		dev_err(dev, "Failed to init common CDB regmap\n");
400380f5708SKishon Vijay Abraham I 		return PTR_ERR(regmap);
401380f5708SKishon Vijay Abraham I 	}
402380f5708SKishon Vijay Abraham I 	sp->regmap_common_cdb = regmap;
403380f5708SKishon Vijay Abraham I 
404380f5708SKishon Vijay Abraham I 	block_offset = SIERRA_PHY_CONFIG_CTRL_OFFSET(block_offset_shift);
405380f5708SKishon Vijay Abraham I 	regmap = cdns_regmap_init(dev, base, block_offset, reg_offset_shift,
406380f5708SKishon Vijay Abraham I 				  &cdns_sierra_phy_config_ctrl_config);
407380f5708SKishon Vijay Abraham I 	if (IS_ERR(regmap)) {
408380f5708SKishon Vijay Abraham I 		dev_err(dev, "Failed to init PHY config and control regmap\n");
409380f5708SKishon Vijay Abraham I 		return PTR_ERR(regmap);
410380f5708SKishon Vijay Abraham I 	}
411380f5708SKishon Vijay Abraham I 	sp->regmap_phy_config_ctrl = regmap;
412380f5708SKishon Vijay Abraham I 
413380f5708SKishon Vijay Abraham I 	return 0;
414380f5708SKishon Vijay Abraham I }
415380f5708SKishon Vijay Abraham I 
41644d30d62SAlan Douglas static int cdns_sierra_phy_probe(struct platform_device *pdev)
41744d30d62SAlan Douglas {
41844d30d62SAlan Douglas 	struct cdns_sierra_phy *sp;
41944d30d62SAlan Douglas 	struct phy_provider *phy_provider;
42044d30d62SAlan Douglas 	struct device *dev = &pdev->dev;
42144d30d62SAlan Douglas 	const struct of_device_id *match;
422380f5708SKishon Vijay Abraham I 	struct cdns_sierra_data *data;
423380f5708SKishon Vijay Abraham I 	unsigned int id_value;
42444d30d62SAlan Douglas 	struct resource *res;
42544d30d62SAlan Douglas 	int i, ret, node = 0;
426380f5708SKishon Vijay Abraham I 	void __iomem *base;
42744d30d62SAlan Douglas 	struct device_node *dn = dev->of_node, *child;
42844d30d62SAlan Douglas 
42944d30d62SAlan Douglas 	if (of_get_child_count(dn) == 0)
43044d30d62SAlan Douglas 		return -ENODEV;
43144d30d62SAlan Douglas 
432380f5708SKishon Vijay Abraham I 	/* Get init data for this PHY */
433380f5708SKishon Vijay Abraham I 	match = of_match_device(cdns_sierra_id_table, dev);
434380f5708SKishon Vijay Abraham I 	if (!match)
435380f5708SKishon Vijay Abraham I 		return -EINVAL;
436380f5708SKishon Vijay Abraham I 
437380f5708SKishon Vijay Abraham I 	data = (struct cdns_sierra_data *)match->data;
438380f5708SKishon Vijay Abraham I 
43944d30d62SAlan Douglas 	sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL);
44044d30d62SAlan Douglas 	if (!sp)
44144d30d62SAlan Douglas 		return -ENOMEM;
44244d30d62SAlan Douglas 	dev_set_drvdata(dev, sp);
44344d30d62SAlan Douglas 	sp->dev = dev;
444380f5708SKishon Vijay Abraham I 	sp->init_data = data;
44544d30d62SAlan Douglas 
44644d30d62SAlan Douglas 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
447380f5708SKishon Vijay Abraham I 	base = devm_ioremap_resource(dev, res);
448380f5708SKishon Vijay Abraham I 	if (IS_ERR(base)) {
44944d30d62SAlan Douglas 		dev_err(dev, "missing \"reg\"\n");
450380f5708SKishon Vijay Abraham I 		return PTR_ERR(base);
45144d30d62SAlan Douglas 	}
45244d30d62SAlan Douglas 
453380f5708SKishon Vijay Abraham I 	ret = cdns_regmap_init_blocks(sp, base, data->block_offset_shift,
454380f5708SKishon Vijay Abraham I 				      data->reg_offset_shift);
455380f5708SKishon Vijay Abraham I 	if (ret)
456380f5708SKishon Vijay Abraham I 		return ret;
457380f5708SKishon Vijay Abraham I 
458380f5708SKishon Vijay Abraham I 	ret = cdns_regfield_init(sp);
459380f5708SKishon Vijay Abraham I 	if (ret)
460380f5708SKishon Vijay Abraham I 		return ret;
46144d30d62SAlan Douglas 
46244d30d62SAlan Douglas 	platform_set_drvdata(pdev, sp);
46344d30d62SAlan Douglas 
464372428dbSKishon Vijay Abraham I 	sp->clk = devm_clk_get_optional(dev, "phy_clk");
46544d30d62SAlan Douglas 	if (IS_ERR(sp->clk)) {
46644d30d62SAlan Douglas 		dev_err(dev, "failed to get clock phy_clk\n");
46744d30d62SAlan Douglas 		return PTR_ERR(sp->clk);
46844d30d62SAlan Douglas 	}
46944d30d62SAlan Douglas 
47044d30d62SAlan Douglas 	sp->phy_rst = devm_reset_control_get(dev, "sierra_reset");
47144d30d62SAlan Douglas 	if (IS_ERR(sp->phy_rst)) {
47244d30d62SAlan Douglas 		dev_err(dev, "failed to get reset\n");
47344d30d62SAlan Douglas 		return PTR_ERR(sp->phy_rst);
47444d30d62SAlan Douglas 	}
47544d30d62SAlan Douglas 
476372428dbSKishon Vijay Abraham I 	sp->apb_rst = devm_reset_control_get_optional(dev, "sierra_apb");
47744d30d62SAlan Douglas 	if (IS_ERR(sp->apb_rst)) {
47844d30d62SAlan Douglas 		dev_err(dev, "failed to get apb reset\n");
47944d30d62SAlan Douglas 		return PTR_ERR(sp->apb_rst);
48044d30d62SAlan Douglas 	}
48144d30d62SAlan Douglas 
48244d30d62SAlan Douglas 	ret = clk_prepare_enable(sp->clk);
48344d30d62SAlan Douglas 	if (ret)
48444d30d62SAlan Douglas 		return ret;
48544d30d62SAlan Douglas 
48644d30d62SAlan Douglas 	/* Enable APB */
48744d30d62SAlan Douglas 	reset_control_deassert(sp->apb_rst);
48844d30d62SAlan Douglas 
48944d30d62SAlan Douglas 	/* Check that PHY is present */
490380f5708SKishon Vijay Abraham I 	regmap_field_read(sp->macro_id_type, &id_value);
491380f5708SKishon Vijay Abraham I 	if  (sp->init_data->id_value != id_value) {
49244d30d62SAlan Douglas 		ret = -EINVAL;
49344d30d62SAlan Douglas 		goto clk_disable;
49444d30d62SAlan Douglas 	}
49544d30d62SAlan Douglas 
49644d30d62SAlan Douglas 	sp->autoconf = of_property_read_bool(dn, "cdns,autoconf");
49744d30d62SAlan Douglas 
49844d30d62SAlan Douglas 	for_each_available_child_of_node(dn, child) {
49944d30d62SAlan Douglas 		struct phy *gphy;
50044d30d62SAlan Douglas 
50144d30d62SAlan Douglas 		sp->phys[node].lnk_rst =
50244d30d62SAlan Douglas 			of_reset_control_get_exclusive_by_index(child, 0);
50344d30d62SAlan Douglas 
50444d30d62SAlan Douglas 		if (IS_ERR(sp->phys[node].lnk_rst)) {
50544d30d62SAlan Douglas 			dev_err(dev, "failed to get reset %s\n",
50644d30d62SAlan Douglas 				child->full_name);
50744d30d62SAlan Douglas 			ret = PTR_ERR(sp->phys[node].lnk_rst);
50844d30d62SAlan Douglas 			goto put_child2;
50944d30d62SAlan Douglas 		}
51044d30d62SAlan Douglas 
51144d30d62SAlan Douglas 		if (!sp->autoconf) {
51244d30d62SAlan Douglas 			ret = cdns_sierra_get_optional(&sp->phys[node], child);
51344d30d62SAlan Douglas 			if (ret) {
51444d30d62SAlan Douglas 				dev_err(dev, "missing property in node %s\n",
51544d30d62SAlan Douglas 					child->name);
51644d30d62SAlan Douglas 				goto put_child;
51744d30d62SAlan Douglas 			}
51844d30d62SAlan Douglas 		}
51944d30d62SAlan Douglas 
52044d30d62SAlan Douglas 		gphy = devm_phy_create(dev, child, &ops);
52144d30d62SAlan Douglas 
52244d30d62SAlan Douglas 		if (IS_ERR(gphy)) {
52344d30d62SAlan Douglas 			ret = PTR_ERR(gphy);
52444d30d62SAlan Douglas 			goto put_child;
52544d30d62SAlan Douglas 		}
52644d30d62SAlan Douglas 		sp->phys[node].phy = gphy;
52744d30d62SAlan Douglas 		phy_set_drvdata(gphy, &sp->phys[node]);
52844d30d62SAlan Douglas 
52944d30d62SAlan Douglas 		node++;
53044d30d62SAlan Douglas 	}
53144d30d62SAlan Douglas 	sp->nsubnodes = node;
53244d30d62SAlan Douglas 
53344d30d62SAlan Douglas 	/* If more than one subnode, configure the PHY as multilink */
53444d30d62SAlan Douglas 	if (!sp->autoconf && sp->nsubnodes > 1)
535380f5708SKishon Vijay Abraham I 		regmap_field_write(sp->phy_pll_cfg_1, 0x1);
53644d30d62SAlan Douglas 
53744d30d62SAlan Douglas 	pm_runtime_enable(dev);
53844d30d62SAlan Douglas 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
53944d30d62SAlan Douglas 	reset_control_deassert(sp->phy_rst);
54044d30d62SAlan Douglas 	return PTR_ERR_OR_ZERO(phy_provider);
54144d30d62SAlan Douglas 
54244d30d62SAlan Douglas put_child:
54344d30d62SAlan Douglas 	node++;
54444d30d62SAlan Douglas put_child2:
54544d30d62SAlan Douglas 	for (i = 0; i < node; i++)
54644d30d62SAlan Douglas 		reset_control_put(sp->phys[i].lnk_rst);
54744d30d62SAlan Douglas 	of_node_put(child);
54844d30d62SAlan Douglas clk_disable:
54944d30d62SAlan Douglas 	clk_disable_unprepare(sp->clk);
55044d30d62SAlan Douglas 	reset_control_assert(sp->apb_rst);
55144d30d62SAlan Douglas 	return ret;
55244d30d62SAlan Douglas }
55344d30d62SAlan Douglas 
55444d30d62SAlan Douglas static int cdns_sierra_phy_remove(struct platform_device *pdev)
55544d30d62SAlan Douglas {
55644d30d62SAlan Douglas 	struct cdns_sierra_phy *phy = dev_get_drvdata(pdev->dev.parent);
55744d30d62SAlan Douglas 	int i;
55844d30d62SAlan Douglas 
55944d30d62SAlan Douglas 	reset_control_assert(phy->phy_rst);
56044d30d62SAlan Douglas 	reset_control_assert(phy->apb_rst);
56144d30d62SAlan Douglas 	pm_runtime_disable(&pdev->dev);
56244d30d62SAlan Douglas 
56344d30d62SAlan Douglas 	/*
56444d30d62SAlan Douglas 	 * The device level resets will be put automatically.
56544d30d62SAlan Douglas 	 * Need to put the subnode resets here though.
56644d30d62SAlan Douglas 	 */
56744d30d62SAlan Douglas 	for (i = 0; i < phy->nsubnodes; i++) {
56844d30d62SAlan Douglas 		reset_control_assert(phy->phys[i].lnk_rst);
56944d30d62SAlan Douglas 		reset_control_put(phy->phys[i].lnk_rst);
57044d30d62SAlan Douglas 	}
57144d30d62SAlan Douglas 	return 0;
57244d30d62SAlan Douglas }
57344d30d62SAlan Douglas 
574*871002d7SAnil Varughese /* refclk100MHz_32b_PCIe_cmn_pll_ext_ssc */
575*871002d7SAnil Varughese static struct cdns_reg_pairs cdns_pcie_cmn_regs_ext_ssc[] = {
576*871002d7SAnil Varughese 	{0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
577*871002d7SAnil Varughese 	{0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
578*871002d7SAnil Varughese 	{0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG},
579*871002d7SAnil Varughese 	{0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
580*871002d7SAnil Varughese 	{0x1B1B, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG}
581*871002d7SAnil Varughese };
582*871002d7SAnil Varughese 
583*871002d7SAnil Varughese /* refclk100MHz_32b_PCIe_ln_ext_ssc */
584*871002d7SAnil Varughese static struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = {
585*871002d7SAnil Varughese 	{0x813E, SIERRA_CLKPATHCTRL_TMR_PREG},
586*871002d7SAnil Varughese 	{0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG},
587*871002d7SAnil Varughese 	{0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG},
588*871002d7SAnil Varughese 	{0x808F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
589*871002d7SAnil Varughese 	{0x808F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
590*871002d7SAnil Varughese 	{0x033C, SIERRA_RX_CTLE_MAINTENANCE_PREG},
591*871002d7SAnil Varughese 	{0x44CC, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG}
592*871002d7SAnil Varughese };
593*871002d7SAnil Varughese 
594*871002d7SAnil Varughese /* refclk100MHz_20b_USB_cmn_pll_ext_ssc */
595*871002d7SAnil Varughese static struct cdns_reg_pairs cdns_usb_cmn_regs_ext_ssc[] = {
596*871002d7SAnil Varughese 	{0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG},
597*871002d7SAnil Varughese 	{0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG},
598*871002d7SAnil Varughese 	{0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG},
599*871002d7SAnil Varughese 	{0x0000, SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG}
600*871002d7SAnil Varughese };
601*871002d7SAnil Varughese 
602*871002d7SAnil Varughese /* refclk100MHz_20b_USB_ln_ext_ssc */
603*871002d7SAnil Varughese static struct cdns_reg_pairs cdns_usb_ln_regs_ext_ssc[] = {
604aead5fd6SKishon Vijay Abraham I 	{0xFE0A, SIERRA_DET_STANDEC_A_PREG},
605aead5fd6SKishon Vijay Abraham I 	{0x000F, SIERRA_DET_STANDEC_B_PREG},
606*871002d7SAnil Varughese 	{0x00A5, SIERRA_DET_STANDEC_C_PREG},
607*871002d7SAnil Varughese 	{0x69ad, SIERRA_DET_STANDEC_D_PREG},
608aead5fd6SKishon Vijay Abraham I 	{0x0241, SIERRA_DET_STANDEC_E_PREG},
609*871002d7SAnil Varughese 	{0x0010, SIERRA_PSM_LANECAL_DLY_A1_RESETS_PREG},
610*871002d7SAnil Varughese 	{0x0014, SIERRA_PSM_A0IN_TMR_PREG},
611aead5fd6SKishon Vijay Abraham I 	{0xCF00, SIERRA_PSM_DIAG_PREG},
612aead5fd6SKishon Vijay Abraham I 	{0x001F, SIERRA_PSC_TX_A0_PREG},
613aead5fd6SKishon Vijay Abraham I 	{0x0007, SIERRA_PSC_TX_A1_PREG},
614aead5fd6SKishon Vijay Abraham I 	{0x0003, SIERRA_PSC_TX_A2_PREG},
615aead5fd6SKishon Vijay Abraham I 	{0x0003, SIERRA_PSC_TX_A3_PREG},
616aead5fd6SKishon Vijay Abraham I 	{0x0FFF, SIERRA_PSC_RX_A0_PREG},
617*871002d7SAnil Varughese 	{0x0619, SIERRA_PSC_RX_A1_PREG},
618aead5fd6SKishon Vijay Abraham I 	{0x0003, SIERRA_PSC_RX_A2_PREG},
619aead5fd6SKishon Vijay Abraham I 	{0x0001, SIERRA_PSC_RX_A3_PREG},
620aead5fd6SKishon Vijay Abraham I 	{0x0001, SIERRA_PLLCTRL_SUBRATE_PREG},
621aead5fd6SKishon Vijay Abraham I 	{0x0406, SIERRA_PLLCTRL_GEN_D_PREG},
622*871002d7SAnil Varughese 	{0x5233, SIERRA_PLLCTRL_CPGAIN_MODE_PREG},
623*871002d7SAnil Varughese 	{0x00CA, SIERRA_CLKPATH_BIASTRIM_PREG},
624*871002d7SAnil Varughese 	{0x2512, SIERRA_DFE_BIASTRIM_PREG},
625aead5fd6SKishon Vijay Abraham I 	{0x0000, SIERRA_DRVCTRL_ATTEN_PREG},
626*871002d7SAnil Varughese 	{0x873E, SIERRA_CLKPATHCTRL_TMR_PREG},
627*871002d7SAnil Varughese 	{0x03CF, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG},
628*871002d7SAnil Varughese 	{0x01CE, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG},
629aead5fd6SKishon Vijay Abraham I 	{0x7B3C, SIERRA_CREQ_CCLKDET_MODE01_PREG},
630*871002d7SAnil Varughese 	{0x033F, SIERRA_RX_CTLE_MAINTENANCE_PREG},
631aead5fd6SKishon Vijay Abraham I 	{0x3232, SIERRA_CREQ_FSMCLK_SEL_PREG},
632*871002d7SAnil Varughese 	{0x0000, SIERRA_CREQ_EQ_CTRL_PREG},
633*871002d7SAnil Varughese 	{0x8000, SIERRA_CREQ_SPARE_PREG},
634*871002d7SAnil Varughese 	{0xCC44, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG},
635*871002d7SAnil Varughese 	{0x8453, SIERRA_CTLELUT_CTRL_PREG},
636*871002d7SAnil Varughese 	{0x4110, SIERRA_DFE_ECMP_RATESEL_PREG},
637*871002d7SAnil Varughese 	{0x4110, SIERRA_DFE_SMP_RATESEL_PREG},
638*871002d7SAnil Varughese 	{0x0002, SIERRA_DEQ_PHALIGN_CTRL},
639*871002d7SAnil Varughese 	{0x3200, SIERRA_DEQ_CONCUR_CTRL1_PREG},
640*871002d7SAnil Varughese 	{0x5064, SIERRA_DEQ_CONCUR_CTRL2_PREG},
641*871002d7SAnil Varughese 	{0x0030, SIERRA_DEQ_EPIPWR_CTRL2_PREG},
642*871002d7SAnil Varughese 	{0x0048, SIERRA_DEQ_FAST_MAINT_CYCLES_PREG},
643*871002d7SAnil Varughese 	{0x5A5A, SIERRA_DEQ_ERRCMP_CTRL_PREG},
644*871002d7SAnil Varughese 	{0x02F5, SIERRA_DEQ_OFFSET_CTRL_PREG},
645*871002d7SAnil Varughese 	{0x02F5, SIERRA_DEQ_GAIN_CTRL_PREG},
646*871002d7SAnil Varughese 	{0x9A8A, SIERRA_DEQ_VGATUNE_CTRL_PREG},
647*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT0},
648*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT1},
649*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT2},
650*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT3},
651*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT4},
652*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT5},
653*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT6},
654*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT7},
655*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT8},
656*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT9},
657*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT10},
658*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT11},
659*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT12},
660*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT13},
661*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT14},
662*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT15},
663*871002d7SAnil Varughese 	{0x0014, SIERRA_DEQ_GLUT16},
664*871002d7SAnil Varughese 	{0x0BAE, SIERRA_DEQ_ALUT0},
665*871002d7SAnil Varughese 	{0x0AEB, SIERRA_DEQ_ALUT1},
666*871002d7SAnil Varughese 	{0x0A28, SIERRA_DEQ_ALUT2},
667*871002d7SAnil Varughese 	{0x0965, SIERRA_DEQ_ALUT3},
668*871002d7SAnil Varughese 	{0x08A2, SIERRA_DEQ_ALUT4},
669*871002d7SAnil Varughese 	{0x07DF, SIERRA_DEQ_ALUT5},
670*871002d7SAnil Varughese 	{0x071C, SIERRA_DEQ_ALUT6},
671*871002d7SAnil Varughese 	{0x0659, SIERRA_DEQ_ALUT7},
672*871002d7SAnil Varughese 	{0x0596, SIERRA_DEQ_ALUT8},
673*871002d7SAnil Varughese 	{0x0514, SIERRA_DEQ_ALUT9},
674*871002d7SAnil Varughese 	{0x0492, SIERRA_DEQ_ALUT10},
675*871002d7SAnil Varughese 	{0x0410, SIERRA_DEQ_ALUT11},
676*871002d7SAnil Varughese 	{0x038E, SIERRA_DEQ_ALUT12},
677*871002d7SAnil Varughese 	{0x030C, SIERRA_DEQ_ALUT13},
678*871002d7SAnil Varughese 	{0x03F4, SIERRA_DEQ_DFETAP_CTRL_PREG},
679*871002d7SAnil Varughese 	{0x0001, SIERRA_DFE_EN_1010_IGNORE_PREG},
680*871002d7SAnil Varughese 	{0x3C01, SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG},
681*871002d7SAnil Varughese 	{0x3C40, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG},
682*871002d7SAnil Varughese 	{0x1C08, SIERRA_DEQ_TAU_CTRL2_PREG},
683*871002d7SAnil Varughese 	{0x0033, SIERRA_DEQ_PICTRL_PREG},
684*871002d7SAnil Varughese 	{0x0400, SIERRA_CPICAL_TMRVAL_MODE1_PREG},
685*871002d7SAnil Varughese 	{0x0330, SIERRA_CPICAL_TMRVAL_MODE0_PREG},
686*871002d7SAnil Varughese 	{0x01FF, SIERRA_CPICAL_PICNT_MODE1_PREG},
687aead5fd6SKishon Vijay Abraham I 	{0x0009, SIERRA_CPI_OUTBUF_RATESEL_PREG},
688*871002d7SAnil Varughese 	{0x3232, SIERRA_CPICAL_RES_STARTCODE_MODE23_PREG},
689*871002d7SAnil Varughese 	{0x0005, SIERRA_LFPSDET_SUPPORT_PREG},
690aead5fd6SKishon Vijay Abraham I 	{0x000F, SIERRA_LFPSFILT_NS_PREG},
691aead5fd6SKishon Vijay Abraham I 	{0x0009, SIERRA_LFPSFILT_RD_PREG},
692aead5fd6SKishon Vijay Abraham I 	{0x0001, SIERRA_LFPSFILT_MP_PREG},
693aead5fd6SKishon Vijay Abraham I 	{0x8013, SIERRA_SDFILT_H2L_A_PREG},
694*871002d7SAnil Varughese 	{0x8009, SIERRA_SDFILT_L2H_PREG},
695*871002d7SAnil Varughese 	{0x0024, SIERRA_RXBUFFER_CTLECTRL_PREG},
696*871002d7SAnil Varughese 	{0x0020, SIERRA_RXBUFFER_RCDFECTRL_PREG},
697*871002d7SAnil Varughese 	{0x4243, SIERRA_RXBUFFER_DFECTRL_PREG}
69844d30d62SAlan Douglas };
69944d30d62SAlan Douglas 
70044d30d62SAlan Douglas static const struct cdns_sierra_data cdns_map_sierra = {
70144d30d62SAlan Douglas 	SIERRA_MACRO_ID,
702380f5708SKishon Vijay Abraham I 	0x2,
703380f5708SKishon Vijay Abraham I 	0x2,
704*871002d7SAnil Varughese 	ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
705*871002d7SAnil Varughese 	ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
706*871002d7SAnil Varughese 	ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
707*871002d7SAnil Varughese 	ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
708*871002d7SAnil Varughese 	cdns_pcie_cmn_regs_ext_ssc,
709*871002d7SAnil Varughese 	cdns_pcie_ln_regs_ext_ssc,
710*871002d7SAnil Varughese 	cdns_usb_cmn_regs_ext_ssc,
711*871002d7SAnil Varughese 	cdns_usb_ln_regs_ext_ssc,
71244d30d62SAlan Douglas };
71344d30d62SAlan Douglas 
714367da978SKishon Vijay Abraham I static const struct cdns_sierra_data cdns_ti_map_sierra = {
715367da978SKishon Vijay Abraham I 	SIERRA_MACRO_ID,
716367da978SKishon Vijay Abraham I 	0x0,
717367da978SKishon Vijay Abraham I 	0x1,
718*871002d7SAnil Varughese 	ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
719*871002d7SAnil Varughese 	ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
720*871002d7SAnil Varughese 	ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
721*871002d7SAnil Varughese 	ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
722*871002d7SAnil Varughese 	cdns_pcie_cmn_regs_ext_ssc,
723*871002d7SAnil Varughese 	cdns_pcie_ln_regs_ext_ssc,
724*871002d7SAnil Varughese 	cdns_usb_cmn_regs_ext_ssc,
725*871002d7SAnil Varughese 	cdns_usb_ln_regs_ext_ssc,
726367da978SKishon Vijay Abraham I };
727367da978SKishon Vijay Abraham I 
72844d30d62SAlan Douglas static const struct of_device_id cdns_sierra_id_table[] = {
72944d30d62SAlan Douglas 	{
73044d30d62SAlan Douglas 		.compatible = "cdns,sierra-phy-t0",
73144d30d62SAlan Douglas 		.data = &cdns_map_sierra,
73244d30d62SAlan Douglas 	},
733367da978SKishon Vijay Abraham I 	{
734367da978SKishon Vijay Abraham I 		.compatible = "ti,sierra-phy-t0",
735367da978SKishon Vijay Abraham I 		.data = &cdns_ti_map_sierra,
736367da978SKishon Vijay Abraham I 	},
73744d30d62SAlan Douglas 	{}
73844d30d62SAlan Douglas };
73944d30d62SAlan Douglas MODULE_DEVICE_TABLE(of, cdns_sierra_id_table);
74044d30d62SAlan Douglas 
74144d30d62SAlan Douglas static struct platform_driver cdns_sierra_driver = {
74244d30d62SAlan Douglas 	.probe		= cdns_sierra_phy_probe,
74344d30d62SAlan Douglas 	.remove		= cdns_sierra_phy_remove,
74444d30d62SAlan Douglas 	.driver		= {
74544d30d62SAlan Douglas 		.name	= "cdns-sierra-phy",
74644d30d62SAlan Douglas 		.of_match_table = cdns_sierra_id_table,
74744d30d62SAlan Douglas 	},
74844d30d62SAlan Douglas };
74944d30d62SAlan Douglas module_platform_driver(cdns_sierra_driver);
75044d30d62SAlan Douglas 
75144d30d62SAlan Douglas MODULE_ALIAS("platform:cdns_sierra");
75244d30d62SAlan Douglas MODULE_AUTHOR("Cadence Design Systems");
75344d30d62SAlan Douglas MODULE_DESCRIPTION("CDNS sierra phy driver");
75444d30d62SAlan Douglas MODULE_LICENSE("GPL v2");
755