1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) Marvell International Ltd. and its affiliates
4  */
5 
6 #include <common.h>
7 #include <spl.h>
8 #include <asm/io.h>
9 #include <asm/arch/cpu.h>
10 #include <asm/arch/soc.h>
11 #include <linux/delay.h>
12 
13 #include "high_speed_env_spec.h"
14 #include "sys_env_lib.h"
15 #include "ctrl_pex.h"
16 
17 
18 
19 /*
20  * serdes_seq_db - holds all serdes sequences, their size and the
21  * relevant index in the data array initialized in serdes_seq_init
22  */
23 struct cfg_seq serdes_seq_db[SERDES_LAST_SEQ];
24 
25 #define	SERDES_VERSION		"2.0"
26 #define ENDED_OK		"High speed PHY - Ended Successfully\n"
27 
28 #define LINK_WAIT_CNTR		100
29 #define LINK_WAIT_SLEEP		100
30 
31 #define MAX_UNIT_NUMB		4
32 #define TOPOLOGY_TEST_OK	0
33 #define WRONG_NUMBER_OF_UNITS	1
34 #define SERDES_ALREADY_IN_USE	2
35 #define UNIT_NUMBER_VIOLATION	3
36 
37 /*
38  * serdes_lane_in_use_count contains the exact amount of serdes lanes
39  * needed per type
40  */
41 u8 serdes_lane_in_use_count[MAX_UNITS_ID][MAX_UNIT_NUMB] = {
42 	/* 0  1  2  3  */
43 	{  1, 1, 1, 1 },	/* PEX     */
44 	{  1, 1, 1, 1 },	/* ETH_GIG */
45 	{  1, 1, 0, 0 },	/* USB3H   */
46 	{  1, 1, 1, 0 },	/* USB3D   */
47 	{  1, 1, 1, 1 },	/* SATA    */
48 	{  1, 0, 0, 0 },	/* QSGMII  */
49 	{  4, 0, 0, 0 },	/* XAUI    */
50 	{  2, 0, 0, 0 }		/* RXAUI   */
51 };
52 
53 /*
54  * serdes_unit_count count unit number.
55  * (i.e a single XAUI is counted as 1 unit)
56  */
57 u8 serdes_unit_count[MAX_UNITS_ID] = { 0 };
58 
59 /* Selector mapping for A380-A0 and A390-Z1 */
60 u8 selectors_serdes_rev2_map[LAST_SERDES_TYPE][MAX_SERDES_LANES] = {
61 	/* 0      1      2       3       4       5       6 */
62 	{ 0x1,   0x1,    NA,	 NA,	 NA,	 NA,     NA  }, /* PEX0 */
63 	{ NA,    NA,     0x1,	 NA,	 0x1,	 NA,     0x1 }, /* PEX1 */
64 	{ NA,    NA,     NA,	 NA,	 0x7,	 0x1,    NA  }, /* PEX2 */
65 	{ NA,    NA,     NA,	 0x1,	 NA,	 NA,     NA  }, /* PEX3 */
66 	{ 0x2,   0x3,    NA,	 NA,	 NA,	 NA,     NA  }, /* SATA0 */
67 	{ NA,    NA,     0x3,	 NA,	 NA,	 NA,     NA  }, /* SATA1 */
68 	{ NA,    NA,     NA,	 NA,	 0x6,	 0x2,    NA  }, /* SATA2 */
69 	{ NA,	 NA,     NA,	 0x3,	 NA,	 NA,     NA  }, /* SATA3 */
70 	{ 0x3,   0x4,    NA,     NA,	 NA,	 NA,     NA  }, /* SGMII0 */
71 	{ NA,    0x5,    0x4,    NA,	 0x3,	 NA,     NA  }, /* SGMII1 */
72 	{ NA,    NA,     NA,	 0x4,	 NA,	 0x3,    NA  }, /* SGMII2 */
73 	{ NA,    0x7,    NA,	 NA,	 NA,	 NA,     NA  }, /* QSGMII */
74 	{ NA,    0x6,    NA,	 NA,	 0x4,	 NA,     NA  }, /* USB3_HOST0 */
75 	{ NA,    NA,     NA,	 0x5,	 NA,	 0x4,    NA  }, /* USB3_HOST1 */
76 	{ NA,    NA,     NA,	 0x6,	 0x5,	 0x5,    NA  }, /* USB3_DEVICE */
77 	{ 0x0,   0x0,    0x0,	 0x0,	 0x0,	 0x0,    NA  }  /* DEFAULT_SERDES */
78 };
79 
80 /* Selector mapping for PEX by 4 confiuration */
81 u8 common_phys_selectors_pex_by4_lanes[] = { 0x1, 0x2, 0x2, 0x2 };
82 
83 static const char *const serdes_type_to_string[] = {
84 	"PCIe0",
85 	"PCIe1",
86 	"PCIe2",
87 	"PCIe3",
88 	"SATA0",
89 	"SATA1",
90 	"SATA2",
91 	"SATA3",
92 	"SGMII0",
93 	"SGMII1",
94 	"SGMII2",
95 	"QSGMII",
96 	"USB3 HOST0",
97 	"USB3 HOST1",
98 	"USB3 DEVICE",
99 	"SGMII3",
100 	"XAUI",
101 	"RXAUI",
102 	"DEFAULT SERDES",
103 	"LAST_SERDES_TYPE"
104 };
105 
106 struct serdes_unit_data {
107 	u8 serdes_unit_id;
108 	u8 serdes_unit_num;
109 };
110 
111 static struct serdes_unit_data serdes_type_to_unit_info[] = {
112 	{PEX_UNIT_ID, 0,},
113 	{PEX_UNIT_ID, 1,},
114 	{PEX_UNIT_ID, 2,},
115 	{PEX_UNIT_ID, 3,},
116 	{SATA_UNIT_ID, 0,},
117 	{SATA_UNIT_ID, 1,},
118 	{SATA_UNIT_ID, 2,},
119 	{SATA_UNIT_ID, 3,},
120 	{ETH_GIG_UNIT_ID, 0,},
121 	{ETH_GIG_UNIT_ID, 1,},
122 	{ETH_GIG_UNIT_ID, 2,},
123 	{QSGMII_UNIT_ID, 0,},
124 	{USB3H_UNIT_ID, 0,},
125 	{USB3H_UNIT_ID, 1,},
126 	{USB3D_UNIT_ID, 0,},
127 	{ETH_GIG_UNIT_ID, 3,},
128 	{XAUI_UNIT_ID, 0,},
129 	{RXAUI_UNIT_ID, 0,},
130 };
131 
132 /* Sequences DB */
133 
134 /*
135  * SATA and SGMII
136  */
137 
138 struct op_params sata_port0_power_up_params[] = {
139 	/*
140 	 * unit_base_reg, unit_offset, mask, SATA data, wait_time,
141 	 * num_of_loops
142 	 */
143 	/* Access to reg 0x48(OOB param 1) */
144 	{SATA_VENDOR_PORT_0_REG_ADDR, 0x38000, 0xffffffff, {0x48,}, 0, 0},
145 	/* OOB Com_wake and Com_reset spacing upper limit data */
146 	{SATA_VENDOR_PORT_0_REG_DATA, 0x38000, 0xf03f, {0x6018,}, 0, 0},
147 	/* Access to reg 0xa(PHY Control) */
148 	{SATA_VENDOR_PORT_0_REG_ADDR, 0x38000, 0xffffffff, {0xa,}, 0, 0},
149 	/* Rx clk and Tx clk select non-inverted mode */
150 	{SATA_VENDOR_PORT_0_REG_DATA, 0x38000, 0x3000, {0x0,}, 0, 0},
151 	/* Power Down Sata addr */
152 	{SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x0,}, 0, 0},
153 	/* Power Down Sata Port 0 */
154 	{SATA_CTRL_REG_IND_DATA, 0x38000, 0xffff00ff, {0xc40040,}, 0, 0},
155 };
156 
157 struct op_params sata_port1_power_up_params[] = {
158 	/*
159 	 * unit_base_reg, unit_offset, mask, SATA data, wait_time,
160 	 * num_of_loops
161 	 */
162 	/* Access to reg 0x48(OOB param 1) */
163 	{SATA_VENDOR_PORT_1_REG_ADDR, 0x38000, 0xffffffff, {0x48,}, 0, 0},
164 	/* OOB Com_wake and Com_reset spacing upper limit data */
165 	{SATA_VENDOR_PORT_1_REG_DATA, 0x38000, 0xf03f, {0x6018,}, 0, 0},
166 	/* Access to reg 0xa(PHY Control) */
167 	{SATA_VENDOR_PORT_1_REG_ADDR, 0x38000, 0xffffffff, {0xa,}, 0, 0},
168 	/* Rx clk and Tx clk select non-inverted mode */
169 	{SATA_VENDOR_PORT_1_REG_DATA, 0x38000, 0x3000, {0x0,}, 0, 0},
170 	/* Power Down Sata addr */
171 	{SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x0,}, 0, 0},
172 	/* Power Down Sata Port 1 */
173 	{SATA_CTRL_REG_IND_DATA, 0x38000, 0xffffff00, {0xc44000,}, 0, 0},
174 };
175 
176 /* SATA and SGMII - power up seq */
177 struct op_params sata_and_sgmii_power_up_params[] = {
178 	/*
179 	 * unit_base_reg, unit_offset, mask, SATA data, SGMII data,
180 	 * wait_time, num_of_loops
181 	 */
182 	/* Power Up */
183 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x90006, {0x80002, 0x80002},
184 	 0, 0},
185 	/* Unreset */
186 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x7800, {0x6000, 0x6000}, 0, 0},
187 	/* Phy Selector */
188 	{POWER_AND_PLL_CTRL_REG, 0x800, 0x0e0, {0x0, 0x80}, 0, 0},
189 	/* Ref clock source select */
190 	{MISC_REG, 0x800, 0x440, {0x440, 0x400}, 0, 0}
191 };
192 
193 /* SATA and SGMII - speed config seq */
194 struct op_params sata_and_sgmii_speed_config_params[] = {
195 	/*
196 	 * unit_base_reg, unit_offset, mask, SATA data,
197 	 * SGMII (1.25G), SGMII (3.125G), wait_time, num_of_loops
198 	 */
199 	/* Baud Rate */
200 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x3fc00000,
201 	 {0x8800000, 0x19800000, 0x22000000}, 0, 0},
202 	/* Select Baud Rate for SATA only */
203 	{INTERFACE_REG, 0x800, 0xc00, {0x800, NO_DATA, NO_DATA}, 0, 0},
204 	/* Phy Gen RX and TX */
205 	{ISOLATE_REG, 0x800, 0xff, {NO_DATA, 0x66, 0x66}, 0, 0},
206 	/* Bus Width */
207 	{LOOPBACK_REG, 0x800, 0xe, {0x4, 0x2, 0x2}, 0, 0}
208 };
209 
210 /* SATA and SGMII - TX config seq */
211 struct op_params sata_and_sgmii_tx_config_params1[] = {
212 	/*
213 	 * unitunit_base_reg, unit_offset, mask, SATA data, SGMII data,
214 	 * wait_time, num_of_loops
215 	 */
216 	{GLUE_REG, 0x800, 0x1800, {NO_DATA, 0x800}, 0, 0},
217 	/* Sft Reset pulse */
218 	{RESET_DFE_REG, 0x800, 0x401, {0x401, 0x401}, 0, 0},
219 	/* Sft Reset pulse */
220 	{RESET_DFE_REG, 0x800, 0x401, {0x0, 0x0}, 0, 0},
221 	/* Power up PLL, RX and TX */
222 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0xf0000, {0x70000, 0x70000},
223 	 0, 0}
224 };
225 
226 struct op_params sata_port0_tx_config_params[] = {
227 	/*
228 	 * unit_base_reg, unit_offset, mask, SATA data, wait_time,
229 	 * num_of_loops
230 	 */
231 	/* Power Down Sata addr */
232 	{SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x0}, 0, 0},
233 	/* Power Down Sata  Port 0 */
234 	{SATA_CTRL_REG_IND_DATA, 0x38000, 0xffff00ff, {0xc40000}, 0, 0},
235 	/* Regret bit addr */
236 	{SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x4}, 0, 0},
237 	/* Regret bit data */
238 	{SATA_CTRL_REG_IND_DATA, 0x38000, 0xffffffff, {0x80}, 0, 0}
239 };
240 
241 struct op_params sata_port1_tx_config_params[] = {
242 	/*
243 	 * unit_base_reg, unit_offset, mask, SATA data, wait_time,
244 	 * num_of_loops
245 	 */
246 	/* Power Down Sata addr */
247 	{SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x0}, 0, 0},
248 	/* Power Down Sata Port 1 */
249 	{SATA_CTRL_REG_IND_DATA, 0x38000, 0xffffff00, {0xc40000}, 0, 0},
250 	/* Regret bit addr */
251 	{SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x4}, 0, 0},
252 	/* Regret bit data */
253 	{SATA_CTRL_REG_IND_DATA, 0x38000, 0xffffffff, {0x80}, 0, 0}
254 };
255 
256 struct op_params sata_and_sgmii_tx_config_serdes_rev1_params2[] = {
257 	/*
258 	 * unit_base_reg, unit_offset, mask, SATA data, SGMII data,
259 	 * wait_time, num_of_loops
260 	 */
261 	/* Wait for PHY power up sequence to finish */
262 	{COMMON_PHY_STATUS1_REG, 0x28, 0xc, {0xc, 0xc}, 10, 1000},
263 	/* Wait for PHY power up sequence to finish */
264 	{COMMON_PHY_STATUS1_REG, 0x28, 0x1, {0x1, 0x1}, 1, 1000}
265 };
266 
267 struct op_params sata_and_sgmii_tx_config_serdes_rev2_params2[] = {
268 	/*
269 	 * unit_base_reg, unit_offset, mask, SATA data, SGMII data,
270 	 * wait_time, num_of_loops
271 	 */
272 	/* Wait for PHY power up sequence to finish */
273 	{COMMON_PHY_STATUS1_REG, 0x28, 0xc, {0xc, 0xc}, 10, 1000},
274 	/* Assert Rx Init for SGMII */
275 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x40000000, {NA, 0x40000000},
276 	 0, 0},
277 	/* Assert Rx Init for SATA */
278 	{ISOLATE_REG, 0x800, 0x400, {0x400, NA}, 0, 0},
279 	/* Wait for PHY power up sequence to finish */
280 	{COMMON_PHY_STATUS1_REG, 0x28, 0x1, {0x1, 0x1}, 1, 1000},
281 	/* De-assert Rx Init for SGMII */
282 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x40000000, {NA, 0x0}, 0, 0},
283 	/* De-assert Rx Init for SATA */
284 	{ISOLATE_REG, 0x800, 0x400, {0x0, NA}, 0, 0},
285 	/* os_ph_offset_force (align 90) */
286 	{RX_REG3, 0x800, 0xff, {0xde, NO_DATA}, 0, 0},
287 	/* Set os_ph_valid */
288 	{RX_REG3, 0x800, 0x100, {0x100, NO_DATA}, 0, 0},
289 	/* Unset os_ph_valid */
290 	{RX_REG3, 0x800, 0x100, {0x0, NO_DATA}, 0, 0},
291 };
292 
293 struct op_params sata_electrical_config_serdes_rev1_params[] = {
294 	/*
295 	 * unit_base_reg, unit_offset, mask, SATA data, wait_time,
296 	 * num_of_loops
297 	 */
298 	/* enable SSC and DFE update enable */
299 	{COMMON_PHY_CONFIGURATION4_REG, 0x28, 0x400008, {0x400000,}, 0, 0},
300 	/* tximpcal_th and rximpcal_th */
301 	{VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x4000,}, 0, 0},
302 	/* SQ_THRESH and FFE Setting */
303 	{SQUELCH_FFE_SETTING_REG, 0x800, 0xfff, {0x6cf,}, 0, 0},
304 	/* G1_TX SLEW, EMPH1 and AMP */
305 	{G1_SETTINGS_0_REG, 0x800, 0xffff, {0x8a32,}, 0, 0},
306 	/* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
307 	{G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9,}, 0, 0},
308 	/* G2_TX SLEW, EMPH1 and AMP */
309 	{G2_SETTINGS_0_REG, 0x800, 0xffff, {0x8b5c,}, 0, 0},
310 	/* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
311 	{G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2,}, 0, 0},
312 	/* G3_TX SLEW, EMPH1 and AMP */
313 	{G3_SETTINGS_0_REG, 0x800, 0xffff, {0xe6e,}, 0, 0},
314 	/* G3_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
315 	{G3_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2,}, 0, 0},
316 	/* Cal rxclkalign90 ext enable and Cal os ph ext */
317 	{CAL_REG6, 0x800, 0xff00, {0xdd00,}, 0, 0},
318 	/* Dtl Clamping disable and Dtl clamping Sel(6000ppm) */
319 	{RX_REG2, 0x800, 0xf0, {0x70,}, 0, 0},
320 };
321 
322 struct op_params sata_electrical_config_serdes_rev2_params[] = {
323 	/*
324 	 * unit_base_reg, unit_offset, mask, SATA data, wait_time,
325 	 * num_of_loops
326 	 */
327 	/* SQ_THRESH and FFE Setting */
328 	{SQUELCH_FFE_SETTING_REG, 0x800, 0xf00, {0x600}, 0, 0},
329 	/* enable SSC and DFE update enable */
330 	{COMMON_PHY_CONFIGURATION4_REG, 0x28, 0x400008, {0x400000}, 0, 0},
331 	/* G1_TX SLEW, EMPH1 and AMP */
332 	{G1_SETTINGS_0_REG, 0x800, 0xffff, {0x8a32}, 0, 0},
333 	/* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
334 	{G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
335 	/* G2_TX SLEW, EMPH1 and AMP */
336 	{G2_SETTINGS_0_REG, 0x800, 0xffff, {0x8b5c}, 0, 0},
337 	/* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
338 	{G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2}, 0, 0},
339 	/* G3_TX SLEW, EMPH1 and AMP */
340 	{G3_SETTINGS_0_REG, 0x800, 0xffff, {0xe6e}, 0, 0},
341 	/*
342 	 * G3_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI & DFE_En Gen3,
343 	 * DC wander calibration dis
344 	 */
345 	{G3_SETTINGS_1_REG, 0x800, 0x47ff, {0x7d2}, 0, 0},
346 	/* Bit[12]=0x0 idle_sync_en */
347 	{PCIE_REG0, 0x800, 0x1000, {0x0}, 0, 0},
348 	/* Dtl Clamping disable and Dtl clamping Sel(6000ppm) */
349 	{RX_REG2, 0x800, 0xf0, {0x70,}, 0, 0},
350 	/* tximpcal_th and rximpcal_th */
351 	{VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000}, 0, 0},
352 	/* DFE_STEP_FINE_FX[3:0] =0xa */
353 	{DFE_REG0, 0x800, 0xa00f, {0x800a}, 0, 0},
354 	/* DFE_EN and Dis Update control from pin disable */
355 	{DFE_REG3, 0x800, 0xc000, {0x0}, 0, 0},
356 	/* FFE Force FFE_REs and cap settings for Gen1 */
357 	{G1_SETTINGS_3_REG, 0x800, 0xff, {0xcf}, 0, 0},
358 	/* FFE Force FFE_REs and cap settings for Gen2 */
359 	{G2_SETTINGS_3_REG, 0x800, 0xff, {0xbf}, 0, 0},
360 	/* FE Force FFE_REs=4 and cap settings for Gen3n */
361 	{G3_SETTINGS_3_REG, 0x800, 0xff, {0xcf}, 0, 0},
362 	/* Set DFE Gen 3 Resolution to 3 */
363 	{G3_SETTINGS_4_REG, 0x800, 0x300, {0x300}, 0, 0},
364 };
365 
366 struct op_params sgmii_electrical_config_serdes_rev1_params[] = {
367 	/*
368 	 * unit_base_reg, unit_offset, mask, SGMII (1.25G), SGMII (3.125G),
369 	 * wait_time, num_of_loops
370 	 */
371 	/* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
372 	{G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9, 0x3c9}, 0, 0},
373 	/* SQ_THRESH and FFE Setting */
374 	{SQUELCH_FFE_SETTING_REG, 0x800, 0xfff, {0x8f, 0xbf}, 0, 0},
375 	/* tximpcal_th and rximpcal_th */
376 	{VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x4000, 0x4000}, 0, 0},
377 };
378 
379 struct op_params sgmii_electrical_config_serdes_rev2_params[] = {
380 	/*
381 	 * unit_base_reg, unit_offset, mask, SGMII (1.25G), SGMII (3.125G),
382 	 * wait_time, num_of_loops
383 	 */
384 	/* Set Slew_rate, Emph and Amp */
385 	{G1_SETTINGS_0_REG, 0x800, 0xffff, {0x8fa, 0x8fa}, 0, 0},
386 	/* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
387 	{G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9, 0x3c9}, 0, 0},
388 	/* DTL_FLOOP_EN */
389 	{RX_REG2, 0x800, 0x4, {0x0, 0x0}, 0, 0},
390 	/* G1 FFE Setting Force, RES and CAP */
391 	{G1_SETTINGS_3_REG, 0x800, 0xff, {0x8f, 0xbf}, 0, 0},
392 	/* tximpcal_th and rximpcal_th */
393 	{VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000, 0x3000}, 0, 0},
394 };
395 
396 /*
397  * PEX and USB3
398  */
399 
400 /* PEX and USB3 - power up seq for Serdes Rev 1.2 */
401 struct op_params pex_and_usb3_power_up_serdes_rev1_params[] = {
402 	/*
403 	 * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
404 	 * wait_time, num_of_loops
405 	 */
406 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x3fc7f806,
407 	 {0x4471804, 0x4479804}, 0, 0},
408 	{COMMON_PHY_CONFIGURATION2_REG, 0x28, 0x5c, {0x58, 0x58}, 0, 0},
409 	{COMMON_PHY_CONFIGURATION4_REG, 0x28, 0x3, {0x1, 0x1}, 0, 0},
410 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x7800, {0x6000, 0xe000}, 0, 0},
411 	{GLOBAL_CLK_CTRL, 0x800, 0xd, {0x5, 0x1}, 0, 0},
412 	/* Ref clock source select */
413 	{MISC_REG, 0x800, 0x4c0, {0x80, 0x4c0}, 0, 0}
414 };
415 
416 /* PEX and USB3 - power up seq for Serdes Rev 2.1 */
417 struct op_params pex_and_usb3_power_up_serdes_rev2_params[] = {
418 	/*
419 	 * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
420 	 * wait_time, num_of_loops
421 	 */
422 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x3fc7f806,
423 	 {0x4471804, 0x4479804}, 0, 0},
424 	{COMMON_PHY_CONFIGURATION2_REG, 0x28, 0x5c, {0x58, 0x58}, 0, 0},
425 	{COMMON_PHY_CONFIGURATION4_REG, 0x28, 0x3, {0x1, 0x1}, 0, 0},
426 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x7800, {0x6000, 0xe000}, 0, 0},
427 	{GLOBAL_CLK_CTRL, 0x800, 0xd, {0x5, 0x1}, 0, 0},
428 	{GLOBAL_MISC_CTRL, 0x800, 0xc0, {0x0, NO_DATA}, 0, 0},
429 	/* Ref clock source select */
430 	{MISC_REG, 0x800, 0x4c0, {0x80, 0x4c0}, 0, 0}
431 };
432 
433 /* PEX and USB3 - speed config seq */
434 struct op_params pex_and_usb3_speed_config_params[] = {
435 	/*
436 	 * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
437 	 * wait_time, num_of_loops
438 	 */
439 	/* Maximal PHY Generation Setting */
440 	{INTERFACE_REG, 0x800, 0xc00, {0x400, 0x400, 0x400, 0x400, 0x400},
441 	 0, 0},
442 };
443 
444 struct op_params usb3_electrical_config_serdes_rev1_params[] = {
445 	/* Spread Spectrum Clock Enable */
446 	{LANE_CFG4_REG, 0x800, 0x80, {0x80}, 0, 0},
447 	/* G2_TX_SSC_AMP[6:0]=4.5k_p_pM and TX emphasis mode=m_v */
448 	{G2_SETTINGS_2_REG, 0x800, 0xfe40, {0x4440}, 0, 0},
449 	/* tximpcal_th and rximpcal_th */
450 	{VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x4000}, 0, 0},
451 	/* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
452 	{G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2}, 0, 0},
453 	/* FFE Setting Force, RES and CAP */
454 	{SQUELCH_FFE_SETTING_REG, 0x800, 0xff, {0xef}, 0, 0},
455 	/* Dtl Clamping disable and Dtl-clamping-Sel(6000ppm) */
456 	{RX_REG2, 0x800, 0xf0, {0x70}, 0, 0},
457 	/* cal_rxclkalign90_ext_en and cal_os_ph_ext */
458 	{CAL_REG6, 0x800, 0xff00, {0xd500}, 0, 0},
459 	/* vco_cal_vth_sel */
460 	{REF_REG0, 0x800, 0x38, {0x20}, 0, 0},
461 };
462 
463 struct op_params usb3_electrical_config_serdes_rev2_params[] = {
464 	/* Spread Spectrum Clock Enable */
465 	{LANE_CFG4_REG, 0x800, 0x80, {0x80}, 0, 0},
466 	/* G2_TX_SSC_AMP[6:0]=4.5k_p_pM and TX emphasis mode=m_v */
467 	{G2_SETTINGS_2_REG, 0x800, 0xfe40, {0x4440}, 0, 0},
468 	/* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
469 	{G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2}, 0, 0},
470 	/* Dtl Clamping disable and Dtl-clamping-Sel(6000ppm) */
471 	{RX_REG2, 0x800, 0xf0, {0x70}, 0, 0},
472 	/* vco_cal_vth_sel */
473 	{REF_REG0, 0x800, 0x38, {0x20}, 0, 0},
474 	/* Spread Spectrum Clock Enable */
475 	{LANE_CFG5_REG, 0x800, 0x4, {0x4}, 0, 0},
476 };
477 
478 /* PEX and USB3 - TX config seq */
479 
480 /*
481  * For PEXx1: the pex_and_usb3_tx_config_params1/2/3 configurations should run
482  *            one by one on the lane.
483  * For PEXx4: the pex_and_usb3_tx_config_params1/2/3 configurations should run
484  *            by setting each sequence for all 4 lanes.
485  */
486 struct op_params pex_and_usb3_tx_config_params1[] = {
487 	/*
488 	 * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
489 	 * wait_time, num_of_loops
490 	 */
491 	{GLOBAL_CLK_CTRL, 0x800, 0x1, {0x0, 0x0}, 0, 0},
492 	/* 10ms delay */
493 	{0x0, 0x0, 0x0, {0x0, 0x0}, 10, 0},
494 	/* os_ph_offset_force (align 90) */
495 	{RX_REG3, 0x800, 0xff, {0xdc, NO_DATA}, 0, 0},
496 	/* Set os_ph_valid */
497 	{RX_REG3, 0x800, 0x100, {0x100, NO_DATA}, 0, 0},
498 	/* Unset os_ph_valid */
499 	{RX_REG3, 0x800, 0x100, {0x0, NO_DATA}, 0, 0},
500 };
501 
502 struct op_params pex_and_usb3_tx_config_params2[] = {
503 	/*
504 	 * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
505 	 * wait_time, num_of_loops
506 	 */
507 	/* Sft Reset pulse */
508 	{RESET_DFE_REG, 0x800, 0x401, {0x401, 0x401}, 0, 0},
509 };
510 
511 struct op_params pex_and_usb3_tx_config_params3[] = {
512 	/*
513 	 * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
514 	 * wait_time, num_of_loops
515 	 */
516 	/* Sft Reset pulse */
517 	{RESET_DFE_REG, 0x800, 0x401, {0x0, 0x0}, 0, 0},
518 	/* 10ms delay */
519 	{0x0, 0x0, 0x0, {0x0, 0x0}, 10, 0}
520 };
521 
522 /* PEX by 4 config seq */
523 struct op_params pex_by4_config_params[] = {
524 	/* unit_base_reg, unit_offset, mask, data, wait_time, num_of_loops */
525 	{GLOBAL_CLK_SRC_HI, 0x800, 0x7, {0x5, 0x0, 0x0, 0x2}, 0, 0},
526 	/* Lane Alignment enable */
527 	{LANE_ALIGN_REG0, 0x800, 0x1000, {0x0, 0x0, 0x0, 0x0}, 0, 0},
528 	/* Max PLL phy config */
529 	{CALIBRATION_CTRL_REG, 0x800, 0x1000, {0x1000, 0x1000, 0x1000, 0x1000},
530 	 0, 0},
531 	/* Max PLL pipe config */
532 	{LANE_CFG1_REG, 0x800, 0x600, {0x600, 0x600, 0x600, 0x600}, 0, 0},
533 };
534 
535 /* USB3 device donfig seq */
536 struct op_params usb3_device_config_params[] = {
537 	/* unit_base_reg, unit_offset, mask, data, wait_time, num_of_loops */
538 	{LANE_CFG4_REG, 0x800, 0x200, {0x200}, 0, 0}
539 };
540 
541 /* PEX - electrical configuration seq Rev 1.2 */
542 struct op_params pex_electrical_config_serdes_rev1_params[] = {
543 	/*
544 	 * unit_base_reg, unit_offset, mask, PEX data, wait_time,
545 	 * num_of_loops
546 	 */
547 	/* G1_TX_SLEW_CTRL_EN and G1_TX_SLEW_RATE */
548 	{G1_SETTINGS_0_REG, 0x800, 0xf000, {0xb000}, 0, 0},
549 	/* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
550 	{G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
551 	/* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
552 	{G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
553 	/* CFG_DFE_EN_SEL */
554 	{LANE_CFG4_REG, 0x800, 0x8, {0x8}, 0, 0},
555 	/* FFE Setting Force, RES and CAP */
556 	{SQUELCH_FFE_SETTING_REG, 0x800, 0xff, {0xaf}, 0, 0},
557 	/* tximpcal_th and rximpcal_th */
558 	{VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000}, 0, 0},
559 	/* cal_rxclkalign90_ext_en and cal_os_ph_ext */
560 	{CAL_REG6, 0x800, 0xff00, {0xdc00}, 0, 0},
561 };
562 
563 /* PEX - electrical configuration seq Rev 2.1 */
564 struct op_params pex_electrical_config_serdes_rev2_params[] = {
565 	/*
566 	 * unit_base_reg, unit_offset, mask, PEX data, wait_time,
567 	 * num_of_loops
568 	 */
569 	/* G1_TX_SLEW_CTRL_EN and G1_TX_SLEW_RATE */
570 	{G1_SETTINGS_0_REG, 0x800, 0xf000, {0xb000}, 0, 0},
571 	/* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
572 	{G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
573 	/* G1 FFE Setting Force, RES and CAP */
574 	{G1_SETTINGS_3_REG, 0x800, 0xff, {0xcf}, 0, 0},
575 	/* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
576 	{G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
577 	/* G2 FFE Setting Force, RES and CAP */
578 	{G2_SETTINGS_3_REG, 0x800, 0xff, {0xaf}, 0, 0},
579 	/* G2 DFE resolution value */
580 	{G2_SETTINGS_4_REG, 0x800, 0x300, {0x300}, 0, 0},
581 	/* DFE resolution force */
582 	{DFE_REG0, 0x800, 0x8000, {0x8000}, 0, 0},
583 	/* Tx amplitude for Tx Margin 0 */
584 	{PCIE_REG1, 0x800, 0xf80, {0xd00}, 0, 0},
585 	/* Tx_Emph value for -3.5d_b and -6d_b */
586 	{PCIE_REG3, 0x800, 0xff00, {0xaf00}, 0, 0},
587 	/* CFG_DFE_EN_SEL */
588 	{LANE_CFG4_REG, 0x800, 0x8, {0x8}, 0, 0},
589 	/* tximpcal_th and rximpcal_th */
590 	{VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000}, 0, 0},
591 	/* Force receiver detected */
592 	{LANE_CFG0_REG, 0x800, 0x8000, {0x8000}, 0, 0},
593 };
594 
595 /* PEX - configuration seq for REF_CLOCK_25MHz */
596 struct op_params pex_config_ref_clock25_m_hz[] = {
597 	/*
598 	 * unit_base_reg, unit_offset, mask, PEX data, wait_time,
599 	 * num_of_loops
600 	 */
601 	/* Bits[4:0]=0x2 - REF_FREF_SEL */
602 	{POWER_AND_PLL_CTRL_REG, 0x800, 0x1f, {0x2}, 0, 0},
603 	/* Bit[10]=0x1   - REFCLK_SEL */
604 	{MISC_REG, 0x800, 0x400, {0x400}, 0, 0},
605 	/* Bits[7:0]=0x7 - CFG_PM_RXDLOZ_WAIT */
606 	{GLOBAL_PM_CTRL, 0x800, 0xff, {0x7}, 0, 0},
607 };
608 
609 /* PEX - configuration seq for REF_CLOCK_40MHz */
610 struct op_params pex_config_ref_clock40_m_hz[] = {
611 	/*
612 	 * unit_base_reg, unit_offset, mask, PEX data, wait_time,
613 	 * num_of_loops
614 	 */
615 	/* Bits[4:0]=0x3 - REF_FREF_SEL */
616 	{POWER_AND_PLL_CTRL_REG, 0x800, 0x1f, {0x3}, 0, 0},
617 	/* Bits[10]=0x1  - REFCLK_SEL */
618 	{MISC_REG, 0x800, 0x400, {0x400}, 0, 0},
619 	/* Bits[7:0]=0xc - CFG_PM_RXDLOZ_WAIT */
620 	{GLOBAL_PM_CTRL, 0x800, 0xff, {0xc}, 0, 0},
621 };
622 
623 /* PEX - configuration seq for REF_CLOCK_100MHz */
624 struct op_params pex_config_ref_clock100_m_hz[] = {
625 	/*
626 	 * unit_base_reg, unit_offset, mask, PEX data, wait_time,
627 	 * num_of_loops
628 	 */
629 	/* Bits[4:0]=0x0  - REF_FREF_SEL */
630 	{POWER_AND_PLL_CTRL_REG, 0x800, 0x1f, {0x0}, 0, 0},
631 	/* Bit[10]=0x0    - REFCLK_SEL */
632 	{MISC_REG, 0x800, 0x400, {0x0}, 0, 0},
633 	/* Bits[7:0]=0x1e - CFG_PM_RXDLOZ_WAIT */
634 	{GLOBAL_PM_CTRL, 0x800, 0xff, {0x1e}, 0, 0},
635 };
636 
637 /*
638  *    USB2
639  */
640 
641 struct op_params usb2_power_up_params[] = {
642 	/*
643 	 * unit_base_reg, unit_offset, mask, USB2 data, wait_time,
644 	 * num_of_loops
645 	 */
646 	/* Init phy 0 */
647 	{0x18440, 0x0 /*NA*/, 0xffffffff, {0x62}, 0, 0},
648 	/* Init phy 1 */
649 	{0x18444, 0x0 /*NA*/, 0xffffffff, {0x62}, 0, 0},
650 	/* Init phy 2 */
651 	{0x18448, 0x0 /*NA*/, 0xffffffff, {0x62}, 0, 0},
652 	/* Phy offset 0x0 - PLL_CONTROL0  */
653 	{0xc0000, 0x0 /*NA*/, 0xffffffff, {0x40605205}, 0, 0},
654 	{0xc001c, 0x0 /*NA*/, 0xffffffff, {0x39f16ce}, 0, 0},
655 	{0xc201c, 0x0 /*NA*/, 0xffffffff, {0x39f16ce}, 0, 0},
656 	{0xc401c, 0x0 /*NA*/, 0xffffffff, {0x39f16ce}, 0, 0},
657 	/* Phy offset 0x1 - PLL_CONTROL1 */
658 	{0xc0004, 0x0 /*NA*/, 0x1, {0x1}, 0, 0},
659 	/* Phy0 register 3  - TX Channel control 0 */
660 	{0xc000c, 0x0 /*NA*/, 0x1000000, {0x1000000}, 0, 0},
661 	/* Phy0 register 3  - TX Channel control 0 */
662 	{0xc200c, 0x0 /*NA*/, 0x1000000, {0x1000000}, 0, 0},
663 	/* Phy0 register 3  - TX Channel control 0 */
664 	{0xc400c, 0x0 /*NA*/, 0x1000000, {0x1000000}, 0, 0},
665 	/* Decrease the amplitude of the low speed eye to meet the spec */
666 	{0xc000c, 0x0 /*NA*/, 0xf000, {0x1000}, 0, 0},
667 	{0xc200c, 0x0 /*NA*/, 0xf000, {0x1000}, 0, 0},
668 	{0xc400c, 0x0 /*NA*/, 0xf000, {0x1000}, 0, 0},
669 	/* Change the High speed impedance threshold */
670 	{0xc0008, 0x0 /*NA*/, 0x700, {CONFIG_ARMADA_38X_HS_IMPEDANCE_THRESH << 8}, 0, 0},
671 	{0xc2008, 0x0 /*NA*/, 0x700, {CONFIG_ARMADA_38X_HS_IMPEDANCE_THRESH << 8}, 0, 0},
672 	{0xc4008, 0x0 /*NA*/, 0x700, {CONFIG_ARMADA_38X_HS_IMPEDANCE_THRESH << 8}, 0, 0},
673 	/* Change the squelch level of the receiver to meet the receiver electrical measurements (squelch and receiver sensitivity tests) */
674 	{0xc0014, 0x0 /*NA*/, 0xf, {0x8}, 0, 0},
675 	{0xc2014, 0x0 /*NA*/, 0xf, {0x8}, 0, 0},
676 	{0xc4014, 0x0 /*NA*/, 0xf, {0x8}, 0, 0},
677 	/* Check PLLCAL_DONE is set and IMPCAL_DONE is set */
678 	{0xc0008, 0x0 /*NA*/, 0x80800000, {0x80800000}, 1, 1000},
679 	/* Check REG_SQCAL_DONE  is set */
680 	{0xc0018, 0x0 /*NA*/, 0x80000000, {0x80000000}, 1, 1000},
681 	/* Check PLL_READY  is set */
682 	{0xc0000, 0x0 /*NA*/, 0x80000000, {0x80000000}, 1, 1000},
683 	/* Start calibrate of high seed impedance */
684 	{0xc0008, 0x0 /*NA*/, 0x2000, {0x2000}, 0, 0},
685 	{0x0, 0x0 /*NA*/, 0x0, {0x0}, 10, 0},
686 	/* De-assert  the calibration signal */
687 	{0xc0008, 0x0 /*NA*/, 0x2000, {0x0}, 0, 0},
688 };
689 
690 /*
691  *    QSGMII
692  */
693 
694 /* QSGMII - power up seq */
695 struct op_params qsgmii_port_power_up_params[] = {
696 	/*
697 	 * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
698 	 * num_of_loops
699 	 */
700 	/* Connect the QSGMII to Gigabit Ethernet units */
701 	{QSGMII_CONTROL_REG1, 0x0, 0x40000000, {0x40000000}, 0, 0},
702 	/* Power Up */
703 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0xf0006, {0x80002}, 0, 0},
704 	/* Unreset */
705 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x7800, {0x6000}, 0, 0},
706 	/* Phy Selector */
707 	{POWER_AND_PLL_CTRL_REG, 0x800, 0xff, {0xfc81}, 0, 0},
708 	/* Ref clock source select */
709 	{MISC_REG, 0x800, 0x4c0, {0x480}, 0, 0}
710 };
711 
712 /* QSGMII - speed config seq */
713 struct op_params qsgmii_port_speed_config_params[] = {
714 	/*
715 	 * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
716 	 * num_of_loops
717 	 */
718 	/* Baud Rate */
719 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x3fc00000, {0xcc00000}, 0, 0},
720 	/* Phy Gen RX and TX */
721 	{ISOLATE_REG, 0x800, 0xff, {0x33}, 0, 0},
722 	/* Bus Width */
723 	{LOOPBACK_REG, 0x800, 0xe, {0x2}, 0, 0}
724 };
725 
726 /* QSGMII - Select electrical param seq */
727 struct op_params qsgmii_port_electrical_config_params[] = {
728 	/*
729 	 * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
730 	 * num_of_loops
731 	 */
732 	/* Slew rate and emphasis */
733 	{G1_SETTINGS_0_REG, 0x800, 0x8000, {0x0}, 0, 0}
734 };
735 
736 /* QSGMII - TX config seq */
737 struct op_params qsgmii_port_tx_config_params1[] = {
738 	/*
739 	 * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
740 	 * num_of_loops
741 	 */
742 	{GLUE_REG, 0x800, 0x1800, {0x800}, 0, 0},
743 	/* Sft Reset pulse */
744 	{RESET_DFE_REG, 0x800, 0x401, {0x401}, 0, 0},
745 	/* Sft Reset pulse */
746 	{RESET_DFE_REG, 0x800, 0x401, {0x0}, 0, 0},
747 	/* Lane align */
748 	{LANE_ALIGN_REG0, 0x800, 0x1000, {0x1000}, 0, 0},
749 	/* Power up PLL, RX and TX */
750 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x70000, {0x70000}, 0, 0},
751 	/* Tx driver output idle */
752 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x80000, {0x80000}, 0, 0}
753 };
754 
755 struct op_params qsgmii_port_tx_config_params2[] = {
756 	/*
757 	 * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
758 	 * num_of_loops
759 	 */
760 	/* Wait for PHY power up sequence to finish */
761 	{COMMON_PHY_STATUS1_REG, 0x28, 0xc, {0xc}, 10, 1000},
762 	/* Assert Rx Init and Tx driver output valid */
763 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x40080000, {0x40000000}, 0, 0},
764 	/* Wait for PHY power up sequence to finish */
765 	{COMMON_PHY_STATUS1_REG, 0x28, 0x1, {0x1}, 1, 1000},
766 	/* De-assert Rx Init */
767 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x40000000, {0x0}, 0, 0}
768 };
769 
770 /* SERDES_POWER_DOWN */
771 struct op_params serdes_power_down_params[] = {
772 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, (0xf << 11), {(0x3 << 11)},
773 	 0, 0},
774 	{COMMON_PHY_CONFIGURATION1_REG, 0x28, (0x7 << 16), {0}, 0, 0}
775 };
776 
777 /*
778  * hws_ctrl_serdes_rev_get
779  *
780  * DESCRIPTION: Get the Serdes revision number
781  *
782  * INPUT: config_field - Field description enum
783  *
784  * OUTPUT: None
785  *
786  * RETURN:
787  *		8bit Serdes revision number
788  */
hws_ctrl_serdes_rev_get(void)789 u8 hws_ctrl_serdes_rev_get(void)
790 {
791 	/* for A38x-Z1 */
792 	if (sys_env_device_rev_get() == MV_88F68XX_Z1_ID)
793 		return MV_SERDES_REV_1_2;
794 
795 	/* for A39x-Z1, A38x-A0 */
796 	return MV_SERDES_REV_2_1;
797 }
798 
hws_serdes_topology_verify(enum serdes_type serdes_type,u32 serdes_id,enum serdes_mode serdes_mode)799 u32 hws_serdes_topology_verify(enum serdes_type serdes_type, u32 serdes_id,
800 			       enum serdes_mode serdes_mode)
801 {
802 	u32 test_result = 0;
803 	u8 serd_max_num, unit_numb;
804 	enum unit_id unit_id;
805 
806 	if (serdes_type > RXAUI) {
807 		printf("%s: Warning: Wrong serdes type %s serdes#%d\n",
808 		       __func__, serdes_type_to_string[serdes_type], serdes_id);
809 		return MV_FAIL;
810 	}
811 
812 	unit_id = serdes_type_to_unit_info[serdes_type].serdes_unit_id;
813 	unit_numb = serdes_type_to_unit_info[serdes_type].serdes_unit_num;
814 	serd_max_num = sys_env_unit_max_num_get(unit_id);
815 
816 	/* if didn't exceed amount of required Serdes lanes for current type */
817 	if (serdes_lane_in_use_count[unit_id][unit_numb] != 0) {
818 		/* update amount of required Serdes lanes for current type */
819 		serdes_lane_in_use_count[unit_id][unit_numb]--;
820 
821 		/*
822 		 * If reached the exact amount of required Serdes lanes for
823 		 * current type
824 		 */
825 		if (serdes_lane_in_use_count[unit_id][unit_numb] == 0) {
826 			if (((serdes_type <= PEX3)) &&
827 			    ((serdes_mode == PEX_END_POINT_X4) ||
828 			     (serdes_mode == PEX_ROOT_COMPLEX_X4))) {
829 				/* PCiex4 uses 2 SerDes */
830 				serdes_unit_count[PEX_UNIT_ID] += 2;
831 			} else {
832 				serdes_unit_count[unit_id]++;
833 			}
834 
835 			/* test SoC unit count limitation */
836 			if (serdes_unit_count[unit_id] > serd_max_num) {
837 				test_result = WRONG_NUMBER_OF_UNITS;
838 			} else if (unit_numb >= serd_max_num) {
839 				/* test SoC unit number limitation */
840 				test_result = UNIT_NUMBER_VIOLATION;
841 			}
842 		}
843 	} else {
844 		test_result = SERDES_ALREADY_IN_USE;
845 	}
846 
847 	if (test_result == SERDES_ALREADY_IN_USE) {
848 		printf("%s: Error: serdes lane %d is configured to type %s: type already in use\n",
849 		       __func__, serdes_id,
850 		       serdes_type_to_string[serdes_type]);
851 		return MV_FAIL;
852 	} else if (test_result == WRONG_NUMBER_OF_UNITS) {
853 		printf("%s: Warning: serdes lane %d is set to type %s.\n",
854 		       __func__, serdes_id,
855 		       serdes_type_to_string[serdes_type]);
856 		printf("%s: Maximum supported lanes are already set to this type (limit = %d)\n",
857 		       __func__, serd_max_num);
858 		return MV_FAIL;
859 	} else if (test_result == UNIT_NUMBER_VIOLATION) {
860 		printf("%s: Warning: serdes lane %d type is %s: current device support only %d units of this type.\n",
861 		       __func__, serdes_id,
862 		       serdes_type_to_string[serdes_type],
863 		       serd_max_num);
864 		return MV_FAIL;
865 	}
866 
867 	return MV_OK;
868 }
869 
hws_serdes_xaui_topology_verify(void)870 void hws_serdes_xaui_topology_verify(void)
871 {
872 	/*
873 	 * If XAUI is in use - serdes_lane_in_use_count has to be = 0;
874 	 * if it is not in use hast be = 4
875 	 */
876 	if ((serdes_lane_in_use_count[XAUI_UNIT_ID][0] != 0) &&
877 	    (serdes_lane_in_use_count[XAUI_UNIT_ID][0] != 4)) {
878 		printf("%s: Warning: wrong number of lanes is set to XAUI - %d\n",
879 		       __func__, serdes_lane_in_use_count[XAUI_UNIT_ID][0]);
880 		printf("%s: XAUI has to be defined on 4 lanes\n", __func__);
881 	}
882 
883 	/*
884 	 * If RXAUI is in use - serdes_lane_in_use_count has to be = 0;
885 	 * if it is not in use hast be = 2
886 	 */
887 	if ((serdes_lane_in_use_count[RXAUI_UNIT_ID][0] != 0) &&
888 	    (serdes_lane_in_use_count[RXAUI_UNIT_ID][0] != 2)) {
889 		printf("%s: Warning: wrong number of lanes is set to RXAUI - %d\n",
890 		       __func__, serdes_lane_in_use_count[RXAUI_UNIT_ID][0]);
891 		printf("%s: RXAUI has to be defined on 2 lanes\n", __func__);
892 	}
893 }
894 
hws_serdes_seq_db_init(void)895 int hws_serdes_seq_db_init(void)
896 {
897 	u8 serdes_rev = hws_ctrl_serdes_rev_get();
898 
899 	DEBUG_INIT_FULL_S("\n### serdes_seq38x_init ###\n");
900 
901 	if (serdes_rev == MV_SERDES_REV_NA) {
902 		printf("hws_serdes_seq_db_init: serdes revision number is not supported\n");
903 		return MV_NOT_SUPPORTED;
904 	}
905 
906 	/* SATA_PORT_0_ONLY_POWER_UP_SEQ sequence init */
907 	serdes_seq_db[SATA_PORT_0_ONLY_POWER_UP_SEQ].op_params_ptr =
908 	    sata_port0_power_up_params;
909 	serdes_seq_db[SATA_PORT_0_ONLY_POWER_UP_SEQ].cfg_seq_size =
910 	    sizeof(sata_port0_power_up_params) / sizeof(struct op_params);
911 	serdes_seq_db[SATA_PORT_0_ONLY_POWER_UP_SEQ].data_arr_idx = SATA;
912 
913 	/* SATA_PORT_1_ONLY_POWER_UP_SEQ sequence init */
914 	serdes_seq_db[SATA_PORT_1_ONLY_POWER_UP_SEQ].op_params_ptr =
915 	    sata_port1_power_up_params;
916 	serdes_seq_db[SATA_PORT_1_ONLY_POWER_UP_SEQ].cfg_seq_size =
917 	    sizeof(sata_port1_power_up_params) / sizeof(struct op_params);
918 	serdes_seq_db[SATA_PORT_1_ONLY_POWER_UP_SEQ].data_arr_idx = SATA;
919 
920 	/* SATA_POWER_UP_SEQ sequence init */
921 	serdes_seq_db[SATA_POWER_UP_SEQ].op_params_ptr =
922 	    sata_and_sgmii_power_up_params;
923 	serdes_seq_db[SATA_POWER_UP_SEQ].cfg_seq_size =
924 	    sizeof(sata_and_sgmii_power_up_params) / sizeof(struct op_params);
925 	serdes_seq_db[SATA_POWER_UP_SEQ].data_arr_idx = SATA;
926 
927 	/* SATA_1_5_SPEED_CONFIG_SEQ sequence init */
928 	serdes_seq_db[SATA_1_5_SPEED_CONFIG_SEQ].op_params_ptr =
929 	    sata_and_sgmii_speed_config_params;
930 	serdes_seq_db[SATA_1_5_SPEED_CONFIG_SEQ].cfg_seq_size =
931 	    sizeof(sata_and_sgmii_speed_config_params) /
932 		sizeof(struct op_params);
933 	serdes_seq_db[SATA_1_5_SPEED_CONFIG_SEQ].data_arr_idx = SATA;
934 
935 	/* SATA_3_SPEED_CONFIG_SEQ sequence init */
936 	serdes_seq_db[SATA_3_SPEED_CONFIG_SEQ].op_params_ptr =
937 	    sata_and_sgmii_speed_config_params;
938 	serdes_seq_db[SATA_3_SPEED_CONFIG_SEQ].cfg_seq_size =
939 	    sizeof(sata_and_sgmii_speed_config_params) /
940 		sizeof(struct op_params);
941 	serdes_seq_db[SATA_3_SPEED_CONFIG_SEQ].data_arr_idx = SATA;
942 
943 	/* SATA_6_SPEED_CONFIG_SEQ sequence init */
944 	serdes_seq_db[SATA_6_SPEED_CONFIG_SEQ].op_params_ptr =
945 	    sata_and_sgmii_speed_config_params;
946 	serdes_seq_db[SATA_6_SPEED_CONFIG_SEQ].cfg_seq_size =
947 	    sizeof(sata_and_sgmii_speed_config_params) /
948 		sizeof(struct op_params);
949 	serdes_seq_db[SATA_6_SPEED_CONFIG_SEQ].data_arr_idx = SATA;
950 
951 	/* SATA_ELECTRICAL_CONFIG_SEQ seq sequence init */
952 	if (serdes_rev == MV_SERDES_REV_1_2) {
953 		serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
954 		    sata_electrical_config_serdes_rev1_params;
955 		serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
956 		    sizeof(sata_electrical_config_serdes_rev1_params) /
957 		    sizeof(struct op_params);
958 	} else {
959 		serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
960 		    sata_electrical_config_serdes_rev2_params;
961 		serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
962 		    sizeof(sata_electrical_config_serdes_rev2_params) /
963 		    sizeof(struct op_params);
964 	}
965 	serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].data_arr_idx = SATA;
966 
967 	/* SATA_TX_CONFIG_SEQ sequence init */
968 	serdes_seq_db[SATA_TX_CONFIG_SEQ1].op_params_ptr =
969 	    sata_and_sgmii_tx_config_params1;
970 	serdes_seq_db[SATA_TX_CONFIG_SEQ1].cfg_seq_size =
971 	    sizeof(sata_and_sgmii_tx_config_params1) / sizeof(struct op_params);
972 	serdes_seq_db[SATA_TX_CONFIG_SEQ1].data_arr_idx = SATA;
973 
974 	/* SATA_PORT_0_ONLY_TX_CONFIG_SEQ sequence init */
975 	serdes_seq_db[SATA_PORT_0_ONLY_TX_CONFIG_SEQ].op_params_ptr =
976 	    sata_port0_tx_config_params;
977 	serdes_seq_db[SATA_PORT_0_ONLY_TX_CONFIG_SEQ].cfg_seq_size =
978 	    sizeof(sata_port0_tx_config_params) / sizeof(struct op_params);
979 	serdes_seq_db[SATA_PORT_0_ONLY_TX_CONFIG_SEQ].data_arr_idx = SATA;
980 
981 	/* SATA_PORT_1_ONLY_TX_CONFIG_SEQ sequence init */
982 	serdes_seq_db[SATA_PORT_1_ONLY_TX_CONFIG_SEQ].op_params_ptr =
983 	    sata_port1_tx_config_params;
984 	serdes_seq_db[SATA_PORT_1_ONLY_TX_CONFIG_SEQ].cfg_seq_size =
985 	    sizeof(sata_port1_tx_config_params) / sizeof(struct op_params);
986 	serdes_seq_db[SATA_PORT_1_ONLY_TX_CONFIG_SEQ].data_arr_idx = SATA;
987 
988 	/* SATA_TX_CONFIG_SEQ2 sequence init */
989 	if (serdes_rev == MV_SERDES_REV_1_2) {
990 		serdes_seq_db[SATA_TX_CONFIG_SEQ2].op_params_ptr =
991 		    sata_and_sgmii_tx_config_serdes_rev1_params2;
992 		serdes_seq_db[SATA_TX_CONFIG_SEQ2].cfg_seq_size =
993 		    sizeof(sata_and_sgmii_tx_config_serdes_rev1_params2) /
994 		    sizeof(struct op_params);
995 	} else {
996 		serdes_seq_db[SATA_TX_CONFIG_SEQ2].op_params_ptr =
997 		    sata_and_sgmii_tx_config_serdes_rev2_params2;
998 		serdes_seq_db[SATA_TX_CONFIG_SEQ2].cfg_seq_size =
999 		    sizeof(sata_and_sgmii_tx_config_serdes_rev2_params2) /
1000 		    sizeof(struct op_params);
1001 	}
1002 	serdes_seq_db[SATA_TX_CONFIG_SEQ2].data_arr_idx = SATA;
1003 
1004 	/* SGMII_POWER_UP_SEQ sequence init */
1005 	serdes_seq_db[SGMII_POWER_UP_SEQ].op_params_ptr =
1006 	    sata_and_sgmii_power_up_params;
1007 	serdes_seq_db[SGMII_POWER_UP_SEQ].cfg_seq_size =
1008 	    sizeof(sata_and_sgmii_power_up_params) / sizeof(struct op_params);
1009 	serdes_seq_db[SGMII_POWER_UP_SEQ].data_arr_idx = SGMII;
1010 
1011 	/* SGMII_1_25_SPEED_CONFIG_SEQ sequence init */
1012 	serdes_seq_db[SGMII_1_25_SPEED_CONFIG_SEQ].op_params_ptr =
1013 	    sata_and_sgmii_speed_config_params;
1014 	serdes_seq_db[SGMII_1_25_SPEED_CONFIG_SEQ].cfg_seq_size =
1015 	    sizeof(sata_and_sgmii_speed_config_params) /
1016 		sizeof(struct op_params);
1017 	serdes_seq_db[SGMII_1_25_SPEED_CONFIG_SEQ].data_arr_idx = SGMII;
1018 
1019 	/* SGMII_3_125_SPEED_CONFIG_SEQ sequence init */
1020 	serdes_seq_db[SGMII_3_125_SPEED_CONFIG_SEQ].op_params_ptr =
1021 	    sata_and_sgmii_speed_config_params;
1022 	serdes_seq_db[SGMII_3_125_SPEED_CONFIG_SEQ].cfg_seq_size =
1023 	    sizeof(sata_and_sgmii_speed_config_params) /
1024 		sizeof(struct op_params);
1025 	serdes_seq_db[SGMII_3_125_SPEED_CONFIG_SEQ].data_arr_idx = SGMII_3_125;
1026 
1027 	/* SGMII_ELECTRICAL_CONFIG_SEQ seq sequence init */
1028 	if (serdes_rev == MV_SERDES_REV_1_2) {
1029 		serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
1030 		    sgmii_electrical_config_serdes_rev1_params;
1031 		serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
1032 		    sizeof(sgmii_electrical_config_serdes_rev1_params) /
1033 		    sizeof(struct op_params);
1034 	} else {
1035 		serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
1036 		    sgmii_electrical_config_serdes_rev2_params;
1037 		serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
1038 		    sizeof(sgmii_electrical_config_serdes_rev2_params) /
1039 		    sizeof(struct op_params);
1040 	}
1041 	serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].data_arr_idx = SGMII;
1042 
1043 	/* SGMII_TX_CONFIG_SEQ sequence init */
1044 	serdes_seq_db[SGMII_TX_CONFIG_SEQ1].op_params_ptr =
1045 	    sata_and_sgmii_tx_config_params1;
1046 	serdes_seq_db[SGMII_TX_CONFIG_SEQ1].cfg_seq_size =
1047 	    sizeof(sata_and_sgmii_tx_config_params1) / sizeof(struct op_params);
1048 	serdes_seq_db[SGMII_TX_CONFIG_SEQ1].data_arr_idx = SGMII;
1049 
1050 	/* SGMII_TX_CONFIG_SEQ sequence init */
1051 	if (serdes_rev == MV_SERDES_REV_1_2) {
1052 		serdes_seq_db[SGMII_TX_CONFIG_SEQ2].op_params_ptr =
1053 		    sata_and_sgmii_tx_config_serdes_rev1_params2;
1054 		serdes_seq_db[SGMII_TX_CONFIG_SEQ2].cfg_seq_size =
1055 		    sizeof(sata_and_sgmii_tx_config_serdes_rev1_params2) /
1056 		    sizeof(struct op_params);
1057 	} else {
1058 		serdes_seq_db[SGMII_TX_CONFIG_SEQ2].op_params_ptr =
1059 		    sata_and_sgmii_tx_config_serdes_rev2_params2;
1060 		serdes_seq_db[SGMII_TX_CONFIG_SEQ2].cfg_seq_size =
1061 		    sizeof(sata_and_sgmii_tx_config_serdes_rev2_params2) /
1062 		    sizeof(struct op_params);
1063 	}
1064 	serdes_seq_db[SGMII_TX_CONFIG_SEQ2].data_arr_idx = SGMII;
1065 
1066 	/* PEX_POWER_UP_SEQ sequence init */
1067 	if (serdes_rev == MV_SERDES_REV_1_2) {
1068 		serdes_seq_db[PEX_POWER_UP_SEQ].op_params_ptr =
1069 		    pex_and_usb3_power_up_serdes_rev1_params;
1070 		serdes_seq_db[PEX_POWER_UP_SEQ].cfg_seq_size =
1071 		    sizeof(pex_and_usb3_power_up_serdes_rev1_params) /
1072 		    sizeof(struct op_params);
1073 	} else {
1074 		serdes_seq_db[PEX_POWER_UP_SEQ].op_params_ptr =
1075 		    pex_and_usb3_power_up_serdes_rev2_params;
1076 		serdes_seq_db[PEX_POWER_UP_SEQ].cfg_seq_size =
1077 		    sizeof(pex_and_usb3_power_up_serdes_rev2_params) /
1078 		    sizeof(struct op_params);
1079 	}
1080 	serdes_seq_db[PEX_POWER_UP_SEQ].data_arr_idx = PEX;
1081 
1082 	/* PEX_2_5_SPEED_CONFIG_SEQ sequence init */
1083 	serdes_seq_db[PEX_2_5_SPEED_CONFIG_SEQ].op_params_ptr =
1084 	    pex_and_usb3_speed_config_params;
1085 	serdes_seq_db[PEX_2_5_SPEED_CONFIG_SEQ].cfg_seq_size =
1086 	    sizeof(pex_and_usb3_speed_config_params) / sizeof(struct op_params);
1087 	serdes_seq_db[PEX_2_5_SPEED_CONFIG_SEQ].data_arr_idx =
1088 		PEXSERDES_SPEED_2_5_GBPS;
1089 
1090 	/* PEX_5_SPEED_CONFIG_SEQ sequence init */
1091 	serdes_seq_db[PEX_5_SPEED_CONFIG_SEQ].op_params_ptr =
1092 	    pex_and_usb3_speed_config_params;
1093 	serdes_seq_db[PEX_5_SPEED_CONFIG_SEQ].cfg_seq_size =
1094 	    sizeof(pex_and_usb3_speed_config_params) / sizeof(struct op_params);
1095 	serdes_seq_db[PEX_5_SPEED_CONFIG_SEQ].data_arr_idx =
1096 		PEXSERDES_SPEED_5_GBPS;
1097 
1098 	/* PEX_ELECTRICAL_CONFIG_SEQ seq sequence init */
1099 	if (serdes_rev == MV_SERDES_REV_1_2) {
1100 		serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
1101 		    pex_electrical_config_serdes_rev1_params;
1102 		serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
1103 		    sizeof(pex_electrical_config_serdes_rev1_params) /
1104 		    sizeof(struct op_params);
1105 	} else {
1106 		serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
1107 		    pex_electrical_config_serdes_rev2_params;
1108 		serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
1109 		    sizeof(pex_electrical_config_serdes_rev2_params) /
1110 		    sizeof(struct op_params);
1111 	}
1112 	serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].data_arr_idx = PEX;
1113 
1114 	/* PEX_TX_CONFIG_SEQ1 sequence init */
1115 	serdes_seq_db[PEX_TX_CONFIG_SEQ1].op_params_ptr =
1116 	    pex_and_usb3_tx_config_params1;
1117 	serdes_seq_db[PEX_TX_CONFIG_SEQ1].cfg_seq_size =
1118 	    sizeof(pex_and_usb3_tx_config_params1) / sizeof(struct op_params);
1119 	serdes_seq_db[PEX_TX_CONFIG_SEQ1].data_arr_idx = PEX;
1120 
1121 	/* PEX_TX_CONFIG_SEQ2 sequence init */
1122 	serdes_seq_db[PEX_TX_CONFIG_SEQ2].op_params_ptr =
1123 	    pex_and_usb3_tx_config_params2;
1124 	serdes_seq_db[PEX_TX_CONFIG_SEQ2].cfg_seq_size =
1125 	    sizeof(pex_and_usb3_tx_config_params2) / sizeof(struct op_params);
1126 	serdes_seq_db[PEX_TX_CONFIG_SEQ2].data_arr_idx = PEX;
1127 
1128 	/* PEX_TX_CONFIG_SEQ3 sequence init */
1129 	serdes_seq_db[PEX_TX_CONFIG_SEQ3].op_params_ptr =
1130 	    pex_and_usb3_tx_config_params3;
1131 	serdes_seq_db[PEX_TX_CONFIG_SEQ3].cfg_seq_size =
1132 	    sizeof(pex_and_usb3_tx_config_params3) / sizeof(struct op_params);
1133 	serdes_seq_db[PEX_TX_CONFIG_SEQ3].data_arr_idx = PEX;
1134 
1135 	/* PEX_BY_4_CONFIG_SEQ sequence init */
1136 	serdes_seq_db[PEX_BY_4_CONFIG_SEQ].op_params_ptr =
1137 	    pex_by4_config_params;
1138 	serdes_seq_db[PEX_BY_4_CONFIG_SEQ].cfg_seq_size =
1139 	    sizeof(pex_by4_config_params) / sizeof(struct op_params);
1140 	serdes_seq_db[PEX_BY_4_CONFIG_SEQ].data_arr_idx = PEX;
1141 
1142 	/* PEX_CONFIG_REF_CLOCK_25MHZ_SEQ sequence init */
1143 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_25MHZ_SEQ].op_params_ptr =
1144 	    pex_config_ref_clock25_m_hz;
1145 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_25MHZ_SEQ].cfg_seq_size =
1146 	    sizeof(pex_config_ref_clock25_m_hz) / sizeof(struct op_params);
1147 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_25MHZ_SEQ].data_arr_idx = PEX;
1148 
1149 	/* PEX_ELECTRICAL_CONFIG_REF_CLOCK_40MHZ_SEQ sequence init */
1150 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_40MHZ_SEQ].op_params_ptr =
1151 	    pex_config_ref_clock40_m_hz;
1152 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_40MHZ_SEQ].cfg_seq_size =
1153 	    sizeof(pex_config_ref_clock40_m_hz) / sizeof(struct op_params);
1154 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_40MHZ_SEQ].data_arr_idx = PEX;
1155 
1156 	/* PEX_CONFIG_REF_CLOCK_100MHZ_SEQ sequence init */
1157 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_100MHZ_SEQ].op_params_ptr =
1158 	    pex_config_ref_clock100_m_hz;
1159 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_100MHZ_SEQ].cfg_seq_size =
1160 	    sizeof(pex_config_ref_clock100_m_hz) / sizeof(struct op_params);
1161 	serdes_seq_db[PEX_CONFIG_REF_CLOCK_100MHZ_SEQ].data_arr_idx = PEX;
1162 
1163 	/* USB3_POWER_UP_SEQ sequence init */
1164 	if (serdes_rev == MV_SERDES_REV_1_2) {
1165 		serdes_seq_db[USB3_POWER_UP_SEQ].op_params_ptr =
1166 		    pex_and_usb3_power_up_serdes_rev1_params;
1167 		serdes_seq_db[USB3_POWER_UP_SEQ].cfg_seq_size =
1168 		    sizeof(pex_and_usb3_power_up_serdes_rev1_params) /
1169 		    sizeof(struct op_params);
1170 	} else {
1171 		serdes_seq_db[USB3_POWER_UP_SEQ].op_params_ptr =
1172 		    pex_and_usb3_power_up_serdes_rev2_params;
1173 		serdes_seq_db[USB3_POWER_UP_SEQ].cfg_seq_size =
1174 		    sizeof(pex_and_usb3_power_up_serdes_rev2_params) /
1175 		    sizeof(struct op_params);
1176 	}
1177 	serdes_seq_db[USB3_POWER_UP_SEQ].data_arr_idx = USB3;
1178 
1179 	/* USB3_HOST_SPEED_CONFIG_SEQ sequence init */
1180 	serdes_seq_db[USB3_HOST_SPEED_CONFIG_SEQ].op_params_ptr =
1181 	    pex_and_usb3_speed_config_params;
1182 	serdes_seq_db[USB3_HOST_SPEED_CONFIG_SEQ].cfg_seq_size =
1183 	    sizeof(pex_and_usb3_speed_config_params) / sizeof(struct op_params);
1184 	serdes_seq_db[USB3_HOST_SPEED_CONFIG_SEQ].data_arr_idx =
1185 	    USB3SERDES_SPEED_5_GBPS_HOST;
1186 
1187 	/* USB3_DEVICE_SPEED_CONFIG_SEQ sequence init */
1188 	serdes_seq_db[USB3_DEVICE_SPEED_CONFIG_SEQ].op_params_ptr =
1189 	    pex_and_usb3_speed_config_params;
1190 	serdes_seq_db[USB3_DEVICE_SPEED_CONFIG_SEQ].cfg_seq_size =
1191 	    sizeof(pex_and_usb3_speed_config_params) / sizeof(struct op_params);
1192 	serdes_seq_db[USB3_DEVICE_SPEED_CONFIG_SEQ].data_arr_idx =
1193 	    USB3SERDES_SPEED_5_GBPS_DEVICE;
1194 
1195 	/* USB3_ELECTRICAL_CONFIG_SEQ seq sequence init */
1196 	if (serdes_rev == MV_SERDES_REV_1_2) {
1197 		serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
1198 		    usb3_electrical_config_serdes_rev1_params;
1199 		serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
1200 		    sizeof(usb3_electrical_config_serdes_rev1_params) /
1201 		    sizeof(struct op_params);
1202 	} else {
1203 		serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
1204 		    usb3_electrical_config_serdes_rev2_params;
1205 		serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
1206 		    sizeof(usb3_electrical_config_serdes_rev2_params) /
1207 		    sizeof(struct op_params);
1208 	}
1209 	serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].data_arr_idx = USB3;
1210 
1211 	/* USB3_TX_CONFIG_SEQ sequence init */
1212 	serdes_seq_db[USB3_TX_CONFIG_SEQ1].op_params_ptr =
1213 	    pex_and_usb3_tx_config_params1;
1214 	serdes_seq_db[USB3_TX_CONFIG_SEQ1].cfg_seq_size =
1215 	    sizeof(pex_and_usb3_tx_config_params1) / sizeof(struct op_params);
1216 	serdes_seq_db[USB3_TX_CONFIG_SEQ1].data_arr_idx = USB3;
1217 
1218 	/* USB3_TX_CONFIG_SEQ sequence init */
1219 	serdes_seq_db[USB3_TX_CONFIG_SEQ2].op_params_ptr =
1220 	    pex_and_usb3_tx_config_params2;
1221 	serdes_seq_db[USB3_TX_CONFIG_SEQ2].cfg_seq_size =
1222 	    sizeof(pex_and_usb3_tx_config_params2) / sizeof(struct op_params);
1223 	serdes_seq_db[USB3_TX_CONFIG_SEQ2].data_arr_idx = USB3;
1224 
1225 	/* USB3_TX_CONFIG_SEQ sequence init */
1226 	serdes_seq_db[USB3_TX_CONFIG_SEQ3].op_params_ptr =
1227 	    pex_and_usb3_tx_config_params3;
1228 	serdes_seq_db[USB3_TX_CONFIG_SEQ3].cfg_seq_size =
1229 	    sizeof(pex_and_usb3_tx_config_params3) / sizeof(struct op_params);
1230 	serdes_seq_db[USB3_TX_CONFIG_SEQ3].data_arr_idx = USB3;
1231 
1232 	/* USB2_POWER_UP_SEQ sequence init */
1233 	serdes_seq_db[USB2_POWER_UP_SEQ].op_params_ptr = usb2_power_up_params;
1234 	serdes_seq_db[USB2_POWER_UP_SEQ].cfg_seq_size =
1235 	    sizeof(usb2_power_up_params) / sizeof(struct op_params);
1236 	serdes_seq_db[USB2_POWER_UP_SEQ].data_arr_idx = 0;
1237 
1238 	/* USB3_DEVICE_CONFIG_SEQ sequence init */
1239 	serdes_seq_db[USB3_DEVICE_CONFIG_SEQ].op_params_ptr =
1240 	    usb3_device_config_params;
1241 	serdes_seq_db[USB3_DEVICE_CONFIG_SEQ].cfg_seq_size =
1242 	    sizeof(usb3_device_config_params) / sizeof(struct op_params);
1243 	serdes_seq_db[USB3_DEVICE_CONFIG_SEQ].data_arr_idx = 0;	/* Not relevant */
1244 
1245 	/* SERDES_POWER_DOWN_SEQ sequence init */
1246 	serdes_seq_db[SERDES_POWER_DOWN_SEQ].op_params_ptr =
1247 	    serdes_power_down_params;
1248 	serdes_seq_db[SERDES_POWER_DOWN_SEQ].cfg_seq_size =
1249 	    sizeof(serdes_power_down_params) /
1250 		sizeof(struct op_params);
1251 	serdes_seq_db[SERDES_POWER_DOWN_SEQ].data_arr_idx = FIRST_CELL;
1252 
1253 	if (serdes_rev == MV_SERDES_REV_2_1) {
1254 		/* QSGMII_POWER_UP_SEQ sequence init */
1255 		serdes_seq_db[QSGMII_POWER_UP_SEQ].op_params_ptr =
1256 		    qsgmii_port_power_up_params;
1257 		serdes_seq_db[QSGMII_POWER_UP_SEQ].cfg_seq_size =
1258 		    sizeof(qsgmii_port_power_up_params) /
1259 			sizeof(struct op_params);
1260 		serdes_seq_db[QSGMII_POWER_UP_SEQ].data_arr_idx =
1261 		    QSGMII_SEQ_IDX;
1262 
1263 		/* QSGMII_5_SPEED_CONFIG_SEQ sequence init */
1264 		serdes_seq_db[QSGMII_5_SPEED_CONFIG_SEQ].op_params_ptr =
1265 		    qsgmii_port_speed_config_params;
1266 		serdes_seq_db[QSGMII_5_SPEED_CONFIG_SEQ].cfg_seq_size =
1267 		    sizeof(qsgmii_port_speed_config_params) /
1268 			sizeof(struct op_params);
1269 		serdes_seq_db[QSGMII_5_SPEED_CONFIG_SEQ].data_arr_idx =
1270 		    QSGMII_SEQ_IDX;
1271 
1272 		/* QSGMII_ELECTRICAL_CONFIG_SEQ seq sequence init */
1273 		serdes_seq_db[QSGMII_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
1274 		    qsgmii_port_electrical_config_params;
1275 		serdes_seq_db[QSGMII_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
1276 		    sizeof(qsgmii_port_electrical_config_params) /
1277 		    sizeof(struct op_params);
1278 		serdes_seq_db[QSGMII_ELECTRICAL_CONFIG_SEQ].data_arr_idx =
1279 		    QSGMII_SEQ_IDX;
1280 
1281 		/* QSGMII_TX_CONFIG_SEQ sequence init */
1282 		serdes_seq_db[QSGMII_TX_CONFIG_SEQ1].op_params_ptr =
1283 		    qsgmii_port_tx_config_params1;
1284 		serdes_seq_db[QSGMII_TX_CONFIG_SEQ1].cfg_seq_size =
1285 		    sizeof(qsgmii_port_tx_config_params1) /
1286 			sizeof(struct op_params);
1287 		serdes_seq_db[QSGMII_TX_CONFIG_SEQ1].data_arr_idx =
1288 		    QSGMII_SEQ_IDX;
1289 
1290 		/* QSGMII_TX_CONFIG_SEQ sequence init */
1291 		serdes_seq_db[QSGMII_TX_CONFIG_SEQ2].op_params_ptr =
1292 		    qsgmii_port_tx_config_params2;
1293 		serdes_seq_db[QSGMII_TX_CONFIG_SEQ2].cfg_seq_size =
1294 		    sizeof(qsgmii_port_tx_config_params2) /
1295 			sizeof(struct op_params);
1296 		serdes_seq_db[QSGMII_TX_CONFIG_SEQ2].data_arr_idx =
1297 		    QSGMII_SEQ_IDX;
1298 	}
1299 
1300 	return MV_OK;
1301 }
1302 
serdes_type_and_speed_to_speed_seq(enum serdes_type serdes_type,enum serdes_speed baud_rate)1303 enum serdes_seq serdes_type_and_speed_to_speed_seq(enum serdes_type serdes_type,
1304 					      enum serdes_speed baud_rate)
1305 {
1306 	enum serdes_seq seq_id = SERDES_LAST_SEQ;
1307 
1308 	DEBUG_INIT_FULL_S("\n### serdes_type_and_speed_to_speed_seq ###\n");
1309 	switch (serdes_type) {
1310 	case PEX0:
1311 	case PEX1:
1312 	case PEX2:
1313 	case PEX3:
1314 		if (baud_rate == SERDES_SPEED_2_5_GBPS)
1315 			seq_id = PEX_2_5_SPEED_CONFIG_SEQ;
1316 		else if (baud_rate == SERDES_SPEED_5_GBPS)
1317 			seq_id = PEX_5_SPEED_CONFIG_SEQ;
1318 		break;
1319 	case USB3_HOST0:
1320 	case USB3_HOST1:
1321 		if (baud_rate == SERDES_SPEED_5_GBPS)
1322 			seq_id = USB3_HOST_SPEED_CONFIG_SEQ;
1323 		break;
1324 	case USB3_DEVICE:
1325 		if (baud_rate == SERDES_SPEED_5_GBPS)
1326 			seq_id = USB3_DEVICE_SPEED_CONFIG_SEQ;
1327 		break;
1328 	case SATA0:
1329 	case SATA1:
1330 	case SATA2:
1331 	case SATA3:
1332 		if (baud_rate == SERDES_SPEED_1_5_GBPS)
1333 			seq_id = SATA_1_5_SPEED_CONFIG_SEQ;
1334 		else if (baud_rate == SERDES_SPEED_3_GBPS)
1335 			seq_id = SATA_3_SPEED_CONFIG_SEQ;
1336 		else if (baud_rate == SERDES_SPEED_6_GBPS)
1337 			seq_id = SATA_6_SPEED_CONFIG_SEQ;
1338 		break;
1339 	case SGMII0:
1340 	case SGMII1:
1341 	case SGMII2:
1342 		if (baud_rate == SERDES_SPEED_1_25_GBPS)
1343 			seq_id = SGMII_1_25_SPEED_CONFIG_SEQ;
1344 		else if (baud_rate == SERDES_SPEED_3_125_GBPS)
1345 			seq_id = SGMII_3_125_SPEED_CONFIG_SEQ;
1346 		break;
1347 	case QSGMII:
1348 		seq_id = QSGMII_5_SPEED_CONFIG_SEQ;
1349 		break;
1350 	default:
1351 		return SERDES_LAST_SEQ;
1352 	}
1353 
1354 	return seq_id;
1355 }
1356 
print_topology_details(const struct serdes_map * serdes_map,u8 count)1357 static void print_topology_details(const struct serdes_map *serdes_map,
1358 								u8 count)
1359 {
1360 	u32 lane_num;
1361 
1362 	DEBUG_INIT_S("board SerDes lanes topology details:\n");
1363 
1364 	DEBUG_INIT_S(" | Lane # | Speed |  Type       |\n");
1365 	DEBUG_INIT_S(" --------------------------------\n");
1366 	for (lane_num = 0; lane_num < count; lane_num++) {
1367 		if (serdes_map[lane_num].serdes_type == DEFAULT_SERDES)
1368 			continue;
1369 		DEBUG_INIT_S(" |   ");
1370 		DEBUG_INIT_D(hws_get_physical_serdes_num(lane_num), 1);
1371 		DEBUG_INIT_S("    |   ");
1372 		DEBUG_INIT_D(serdes_map[lane_num].serdes_speed, 2);
1373 		DEBUG_INIT_S("   | ");
1374 		DEBUG_INIT_S((char *)
1375 			     serdes_type_to_string[serdes_map[lane_num].
1376 						   serdes_type]);
1377 		DEBUG_INIT_S("\t|\n");
1378 	}
1379 	DEBUG_INIT_S(" --------------------------------\n");
1380 }
1381 
hws_pre_serdes_init_config(void)1382 int hws_pre_serdes_init_config(void)
1383 {
1384 	u32 data;
1385 
1386 	/*
1387 	 * Configure Core PLL
1388 	 */
1389 	/*
1390 	 * set PLL parameters
1391 	 * bits[2:0]  =0x3 (Core-PLL Kdiv)
1392 	 * bits[20:12]=0x9f (Core-PLL Ndiv)
1393 	 * bits[24:21]=0x7(Core-PLL VCO Band)
1394 	 * bits[28:25]=0x1(Core-PLL Rlf)
1395 	 * bits[31:29]=0x2(Core-PLL charge-pump adjust)
1396 	 */
1397 	reg_write(CORE_PLL_PARAMETERS_REG, 0x42e9f003);
1398 
1399 	/* Enable PLL Configuration */
1400 	data = reg_read(CORE_PLL_CONFIG_REG);
1401 	data = SET_BIT(data, 9);
1402 	reg_write(CORE_PLL_CONFIG_REG, data);
1403 
1404 	return MV_OK;
1405 }
1406 
serdes_phy_config(void)1407 int serdes_phy_config(void)
1408 {
1409 	struct serdes_map *serdes_map;
1410 	u8 serdes_count;
1411 
1412 	DEBUG_INIT_FULL_S("\n### ctrl_high_speed_serdes_phy_config ###\n");
1413 
1414 	DEBUG_INIT_S("High speed PHY - Version: ");
1415 	DEBUG_INIT_S(SERDES_VERSION);
1416 	DEBUG_INIT_S("\n");
1417 
1418 	/* Init serdes sequences DB */
1419 	if (hws_serdes_seq_init() != MV_OK) {
1420 		printf("hws_ctrl_high_speed_serdes_phy_config: Error: Serdes initialization fail\n");
1421 		return MV_FAIL;
1422 	}
1423 
1424 	/* Board topology load */
1425 	DEBUG_INIT_FULL_S
1426 	    ("ctrl_high_speed_serdes_phy_config: Loading board topology..\n");
1427 	CHECK_STATUS(hws_board_topology_load(&serdes_map, &serdes_count));
1428 	if (serdes_count > hws_serdes_get_max_lane()) {
1429 		printf("Error: too many serdes lanes specified by board\n");
1430 		return MV_FAIL;
1431 	}
1432 
1433 	/* print topology */
1434 	print_topology_details(serdes_map, serdes_count);
1435 	CHECK_STATUS(hws_pre_serdes_init_config());
1436 
1437 	/* Power-Up sequence */
1438 	DEBUG_INIT_FULL_S
1439 		("ctrl_high_speed_serdes_phy_config: Starting serdes power up sequence\n");
1440 
1441 	CHECK_STATUS(hws_power_up_serdes_lanes(serdes_map, serdes_count));
1442 
1443 	DEBUG_INIT_FULL_S
1444 		("\n### ctrl_high_speed_serdes_phy_config ended successfully ###\n");
1445 
1446 	DEBUG_INIT_S(ENDED_OK);
1447 
1448 	return MV_OK;
1449 }
1450 
serdes_polarity_config(u32 serdes_num,int is_rx)1451 int serdes_polarity_config(u32 serdes_num, int is_rx)
1452 {
1453 	u32 data;
1454 	u32 reg_addr;
1455 	u8 bit_off = (is_rx) ? 11 : 10;
1456 
1457 	reg_addr = SERDES_REGS_LANE_BASE_OFFSET(serdes_num) + SYNC_PATTERN_REG;
1458 	data = reg_read(reg_addr);
1459 	data = SET_BIT(data, bit_off);
1460 	reg_write(reg_addr, data);
1461 
1462 	return MV_OK;
1463 }
1464 
hws_power_up_serdes_lanes(struct serdes_map * serdes_map,u8 count)1465 int hws_power_up_serdes_lanes(struct serdes_map *serdes_map, u8 count)
1466 {
1467 	u32 serdes_id, serdes_lane_num;
1468 	enum ref_clock ref_clock;
1469 	enum serdes_type serdes_type;
1470 	enum serdes_speed serdes_speed;
1471 	enum serdes_mode serdes_mode;
1472 	int serdes_rx_polarity_swap;
1473 	int serdes_tx_polarity_swap;
1474 	int is_pex_enabled = 0;
1475 
1476 	/*
1477 	 * is_pex_enabled:
1478 	 * Flag which indicates that one of the Serdes is of PEX.
1479 	 * In this case, PEX unit will be initialized after Serdes power-up
1480 	 */
1481 
1482 	DEBUG_INIT_FULL_S("\n### hws_power_up_serdes_lanes ###\n");
1483 
1484 	/* COMMON PHYS SELECTORS register configuration */
1485 	DEBUG_INIT_FULL_S
1486 	    ("hws_power_up_serdes_lanes: Updating COMMON PHYS SELECTORS reg\n");
1487 	CHECK_STATUS(hws_update_serdes_phy_selectors(serdes_map, count));
1488 
1489 	/* per Serdes Power Up */
1490 	for (serdes_id = 0; serdes_id < count; serdes_id++) {
1491 		DEBUG_INIT_FULL_S
1492 		    ("calling serdes_power_up_ctrl: serdes lane number ");
1493 		DEBUG_INIT_FULL_D_10(serdes_lane_num, 1);
1494 		DEBUG_INIT_FULL_S("\n");
1495 
1496 		serdes_lane_num = hws_get_physical_serdes_num(serdes_id);
1497 		serdes_type = serdes_map[serdes_id].serdes_type;
1498 		serdes_speed = serdes_map[serdes_id].serdes_speed;
1499 		serdes_mode = serdes_map[serdes_id].serdes_mode;
1500 		serdes_rx_polarity_swap = serdes_map[serdes_id].swap_rx;
1501 		serdes_tx_polarity_swap = serdes_map[serdes_id].swap_tx;
1502 
1503 		/* serdes lane is not in use */
1504 		if (serdes_type == DEFAULT_SERDES)
1505 			continue;
1506 		else if (serdes_type <= PEX3)	/* PEX type */
1507 			is_pex_enabled = 1;
1508 
1509 		ref_clock = hws_serdes_get_ref_clock_val(serdes_type);
1510 		if (ref_clock == REF_CLOCK_UNSUPPORTED) {
1511 			DEBUG_INIT_S
1512 			    ("hws_power_up_serdes_lanes: unsupported ref clock\n");
1513 			return MV_NOT_SUPPORTED;
1514 		}
1515 		CHECK_STATUS(serdes_power_up_ctrl(serdes_lane_num,
1516 						  1,
1517 						  serdes_type,
1518 						  serdes_speed,
1519 						  serdes_mode, ref_clock));
1520 
1521 		/* RX Polarity config */
1522 		if (serdes_rx_polarity_swap)
1523 			CHECK_STATUS(serdes_polarity_config
1524 				     (serdes_lane_num, 1));
1525 
1526 		/* TX Polarity config */
1527 		if (serdes_tx_polarity_swap)
1528 			CHECK_STATUS(serdes_polarity_config
1529 				     (serdes_lane_num, 0));
1530 	}
1531 
1532 	if (is_pex_enabled) {
1533 		/* Set PEX_TX_CONFIG_SEQ sequence for PEXx4 mode.
1534 		   After finish the Power_up sequence for all lanes,
1535 		   the lanes should be released from reset state.       */
1536 		CHECK_STATUS(hws_pex_tx_config_seq(serdes_map, count));
1537 
1538 		/* PEX configuration */
1539 		CHECK_STATUS(hws_pex_config(serdes_map, count));
1540 	}
1541 
1542 	/* USB2 configuration */
1543 	DEBUG_INIT_FULL_S("hws_power_up_serdes_lanes: init USB2 Phys\n");
1544 	CHECK_STATUS(mv_seq_exec(0 /* not relevant */ , USB2_POWER_UP_SEQ));
1545 
1546 	DEBUG_INIT_FULL_S
1547 	    ("### hws_power_up_serdes_lanes ended successfully ###\n");
1548 
1549 	return MV_OK;
1550 }
1551 
ctrl_high_speed_serdes_phy_config(void)1552 int ctrl_high_speed_serdes_phy_config(void)
1553 {
1554 	return hws_ctrl_high_speed_serdes_phy_config();
1555 }
1556 
serdes_pex_usb3_pipe_delay_w_a(u32 serdes_num,u8 serdes_type)1557 static int serdes_pex_usb3_pipe_delay_w_a(u32 serdes_num, u8 serdes_type)
1558 {
1559 	u32 reg_data;
1560 
1561 	/* WA for A380 Z1 relevant for lanes 3,4,5 only */
1562 	if (serdes_num >= 3) {
1563 		reg_data = reg_read(GENERAL_PURPOSE_RESERVED0_REG);
1564 		/* set delay on pipe -
1565 		 * When lane 3 is connected to a MAC of Pex -> set bit 7 to 1.
1566 		 * When lane 3 is connected to a MAC of USB3 -> set bit 7 to 0.
1567 		 * When lane 4 is connected to a MAC of Pex -> set bit 8 to 1.
1568 		 * When lane 4 is connected to a MAC of USB3 -> set bit 8 to 0.
1569 		 * When lane 5 is connected to a MAC of Pex -> set bit 8 to 1.
1570 		 * When lane 5 is connected to a MAC of USB3 -> set bit 8 to 0.
1571 		 */
1572 		if (serdes_type == PEX)
1573 			reg_data |= 1 << (7 + (serdes_num - 3));
1574 		if (serdes_type == USB3) {
1575 			/* USB3 */
1576 			reg_data &= ~(1 << (7 + (serdes_num - 3)));
1577 		}
1578 		reg_write(GENERAL_PURPOSE_RESERVED0_REG, reg_data);
1579 	}
1580 
1581 	return MV_OK;
1582 }
1583 
1584 /*
1585  * hws_serdes_pex_ref_clock_satr_get -
1586  *
1587  * DESCRIPTION: Get the reference clock value from DEVICE_SAMPLE_AT_RESET1_REG
1588  *              and check:
1589  *              bit[2] for PEX#0, bit[3] for PEX#1, bit[30] for PEX#2, bit[31]
1590  *              for PEX#3.
1591  *              If bit=0 --> REF_CLOCK_100MHz
1592  *              If bit=1 && DEVICE_SAMPLE_AT_RESET2_REG bit[0]=0
1593  *              --> REF_CLOCK_25MHz
1594  *              If bit=1 && DEVICE_SAMPLE_AT_RESET2_REG bit[0]=1
1595  *              --> REF_CLOCK_40MHz
1596  *
1597  * INPUT:        serdes_type - Type of Serdes
1598  *
1599  * OUTPUT:       pex_satr   -  Return the REF_CLOCK value:
1600  *                            REF_CLOCK_25MHz, REF_CLOCK_40MHz or REF_CLOCK_100MHz
1601  *
1602  * RETURNS:      MV_OK        - for success
1603  *               MV_BAD_PARAM - for fail
1604  */
hws_serdes_pex_ref_clock_satr_get(enum serdes_type serdes_type,u32 * pex_satr)1605 int hws_serdes_pex_ref_clock_satr_get(enum serdes_type serdes_type, u32 *pex_satr)
1606 {
1607 	u32 data, reg_satr1;
1608 
1609 	reg_satr1 = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
1610 
1611 	switch (serdes_type) {
1612 	case PEX0:
1613 		data = REF_CLK_SELECTOR_VAL_PEX0(reg_satr1);
1614 		break;
1615 	case PEX1:
1616 		data = REF_CLK_SELECTOR_VAL_PEX1(reg_satr1);
1617 		break;
1618 	case PEX2:
1619 		data = REF_CLK_SELECTOR_VAL_PEX2(reg_satr1);
1620 		break;
1621 	case PEX3:
1622 		data = REF_CLK_SELECTOR_VAL_PEX3(reg_satr1);
1623 		break;
1624 	default:
1625 		printf("%s: Error: SerDes type %d is not supported\n",
1626 		       __func__, serdes_type);
1627 		return MV_BAD_PARAM;
1628 	}
1629 
1630 	*pex_satr = data;
1631 
1632 	return MV_OK;
1633 }
1634 
hws_serdes_get_ref_clock_val(enum serdes_type serdes_type)1635 u32 hws_serdes_get_ref_clock_val(enum serdes_type serdes_type)
1636 {
1637 	u32 pex_satr;
1638 	enum ref_clock ref_clock;
1639 
1640 	DEBUG_INIT_FULL_S("\n### hws_serdes_get_ref_clock_val ###\n");
1641 
1642 	if (serdes_type >= LAST_SERDES_TYPE)
1643 		return REF_CLOCK_UNSUPPORTED;
1644 
1645 	/* read ref clock from S@R */
1646 	ref_clock = hws_serdes_silicon_ref_clock_get();
1647 
1648 	if (serdes_type > PEX3) {
1649 		/* for all Serdes types but PCIe */
1650 		return ref_clock;
1651 	}
1652 
1653 	/* for PCIe, need also to check PCIe S@R */
1654 	CHECK_STATUS(hws_serdes_pex_ref_clock_satr_get
1655 		     (serdes_type, &pex_satr));
1656 
1657 	if (pex_satr == 0) {
1658 		return REF_CLOCK_100MHZ;
1659 	} else if (pex_satr == 1) {
1660 		/* value of 1 means we can use ref clock from SoC (as other Serdes types) */
1661 		return ref_clock;
1662 	} else {
1663 		printf
1664 		    ("%s: Error: REF_CLK_SELECTOR_VAL for SerDes type %d is wrong\n",
1665 		     __func__, serdes_type);
1666 		return REF_CLOCK_UNSUPPORTED;
1667 	}
1668 }
1669 
serdes_power_up_ctrl(u32 serdes_num,int serdes_power_up,enum serdes_type serdes_type,enum serdes_speed baud_rate,enum serdes_mode serdes_mode,enum ref_clock ref_clock)1670 int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up,
1671 			 enum serdes_type serdes_type,
1672 			 enum serdes_speed baud_rate,
1673 			 enum serdes_mode serdes_mode, enum ref_clock ref_clock)
1674 {
1675 	u32 sata_idx, pex_idx, sata_port;
1676 	enum serdes_seq speed_seq_id;
1677 	u32 reg_data;
1678 	int is_pex_by1;
1679 
1680 	DEBUG_INIT_FULL_S("\n### serdes_power_up_ctrl ###\n");
1681 
1682 	if (serdes_power_up == 1) {	/* Serdes power up */
1683 		DEBUG_INIT_FULL_S
1684 		    ("serdes_power_up_ctrl: executing power up.. ");
1685 		DEBUG_INIT_FULL_C("serdes num = ", serdes_num, 2);
1686 		DEBUG_INIT_FULL_C("serdes type = ", serdes_type, 2);
1687 
1688 		DEBUG_INIT_FULL_S("Going access 1");
1689 
1690 		/* Getting the Speed Select sequence id */
1691 		speed_seq_id =
1692 			serdes_type_and_speed_to_speed_seq(serdes_type,
1693 							   baud_rate);
1694 		if (speed_seq_id == SERDES_LAST_SEQ) {
1695 			printf
1696 			    ("serdes_power_up_ctrl: serdes type %d and speed %d are not supported together\n",
1697 			     serdes_type, baud_rate);
1698 
1699 			return MV_BAD_PARAM;
1700 		}
1701 
1702 		/* Executing power up, ref clock set, speed config and TX config */
1703 		switch (serdes_type) {
1704 		case PEX0:
1705 		case PEX1:
1706 		case PEX2:
1707 		case PEX3:
1708 			if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2) {
1709 				CHECK_STATUS(serdes_pex_usb3_pipe_delay_w_a
1710 					     (serdes_num, PEX));
1711 			}
1712 
1713 			is_pex_by1 = (serdes_mode == PEX_ROOT_COMPLEX_X1) ||
1714 				(serdes_mode == PEX_END_POINT_X1);
1715 			pex_idx = serdes_type - PEX0;
1716 
1717 			if ((is_pex_by1 == 1) || (serdes_type == PEX0)) {
1718 				/* For PEX by 4, init only the PEX 0 */
1719 				reg_data = reg_read(SOC_CONTROL_REG1);
1720 				if (is_pex_by1 == 1)
1721 					reg_data |= 0x4000;
1722 				else
1723 					reg_data &= ~0x4000;
1724 				reg_write(SOC_CONTROL_REG1, reg_data);
1725 
1726 				reg_data =
1727 				    reg_read(((PEX_IF_REGS_BASE(pex_idx)) +
1728 					      0x6c));
1729 				reg_data &= ~0x3f0;
1730 				if (is_pex_by1 == 1)
1731 					reg_data |= 0x10;
1732 				else
1733 					reg_data |= 0x40;
1734 				reg_write(((PEX_IF_REGS_BASE(pex_idx)) + 0x6c),
1735 					  reg_data);
1736 
1737 				reg_data =
1738 				    reg_read(((PEX_IF_REGS_BASE(pex_idx)) +
1739 					      0x6c));
1740 				reg_data &= ~0xf;
1741 				reg_data |= 0x2;
1742 				reg_write(((PEX_IF_REGS_BASE(pex_idx)) + 0x6c),
1743 					  reg_data);
1744 
1745 				reg_data =
1746 				    reg_read(((PEX_IF_REGS_BASE(pex_idx)) +
1747 					      0x70));
1748 				reg_data &= ~0x40;
1749 				reg_data |= 0x40;
1750 				reg_write(((PEX_IF_REGS_BASE(pex_idx)) + 0x70),
1751 					  reg_data);
1752 			}
1753 
1754 			CHECK_STATUS(mv_seq_exec(serdes_num, PEX_POWER_UP_SEQ));
1755 			if (is_pex_by1 == 0) {
1756 				/*
1757 				 * for PEX by 4 - use the PEX index as the
1758 				 * seq array index
1759 				 */
1760 				serdes_seq_db[PEX_BY_4_CONFIG_SEQ].
1761 				    data_arr_idx = pex_idx;
1762 				CHECK_STATUS(mv_seq_exec
1763 					     (serdes_num, PEX_BY_4_CONFIG_SEQ));
1764 			}
1765 
1766 			CHECK_STATUS(hws_ref_clock_set
1767 				     (serdes_num, serdes_type, ref_clock));
1768 			CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
1769 			CHECK_STATUS(mv_seq_exec
1770 				     (serdes_num, PEX_ELECTRICAL_CONFIG_SEQ));
1771 
1772 			if (is_pex_by1 == 1) {
1773 				CHECK_STATUS(mv_seq_exec
1774 					     (serdes_num, PEX_TX_CONFIG_SEQ2));
1775 				CHECK_STATUS(mv_seq_exec
1776 					     (serdes_num, PEX_TX_CONFIG_SEQ3));
1777 				CHECK_STATUS(mv_seq_exec
1778 					     (serdes_num, PEX_TX_CONFIG_SEQ1));
1779 			}
1780 			udelay(20);
1781 
1782 			break;
1783 		case USB3_HOST0:
1784 		case USB3_HOST1:
1785 		case USB3_DEVICE:
1786 			if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2) {
1787 				CHECK_STATUS(serdes_pex_usb3_pipe_delay_w_a
1788 					     (serdes_num, USB3));
1789 			}
1790 			CHECK_STATUS(mv_seq_exec
1791 				     (serdes_num, USB3_POWER_UP_SEQ));
1792 			CHECK_STATUS(hws_ref_clock_set
1793 				     (serdes_num, serdes_type, ref_clock));
1794 			CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
1795 			if (serdes_type == USB3_DEVICE) {
1796 				CHECK_STATUS(mv_seq_exec
1797 					     (serdes_num,
1798 					      USB3_DEVICE_CONFIG_SEQ));
1799 			}
1800 			CHECK_STATUS(mv_seq_exec
1801 				     (serdes_num, USB3_ELECTRICAL_CONFIG_SEQ));
1802 			CHECK_STATUS(mv_seq_exec
1803 				     (serdes_num, USB3_TX_CONFIG_SEQ1));
1804 			CHECK_STATUS(mv_seq_exec
1805 				     (serdes_num, USB3_TX_CONFIG_SEQ2));
1806 			CHECK_STATUS(mv_seq_exec
1807 				     (serdes_num, USB3_TX_CONFIG_SEQ3));
1808 
1809 			udelay(10000);
1810 			break;
1811 		case SATA0:
1812 		case SATA1:
1813 		case SATA2:
1814 		case SATA3:
1815 			sata_idx = ((serdes_type == SATA0) ||
1816 				    (serdes_type == SATA1)) ? 0 : 1;
1817 			sata_port = ((serdes_type == SATA0) ||
1818 				     (serdes_type == SATA2)) ? 0 : 1;
1819 
1820 			CHECK_STATUS(mv_seq_exec
1821 				     (sata_idx, (sata_port == 0) ?
1822 				      SATA_PORT_0_ONLY_POWER_UP_SEQ :
1823 				      SATA_PORT_1_ONLY_POWER_UP_SEQ));
1824 			CHECK_STATUS(mv_seq_exec
1825 				     (serdes_num, SATA_POWER_UP_SEQ));
1826 			CHECK_STATUS(hws_ref_clock_set
1827 				     (serdes_num, serdes_type, ref_clock));
1828 			CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
1829 			CHECK_STATUS(mv_seq_exec
1830 				     (serdes_num, SATA_ELECTRICAL_CONFIG_SEQ));
1831 			CHECK_STATUS(mv_seq_exec
1832 				     (serdes_num, SATA_TX_CONFIG_SEQ1));
1833 			CHECK_STATUS(mv_seq_exec
1834 				     (sata_idx, (sata_port == 0) ?
1835 				      SATA_PORT_0_ONLY_TX_CONFIG_SEQ :
1836 				      SATA_PORT_1_ONLY_TX_CONFIG_SEQ));
1837 			CHECK_STATUS(mv_seq_exec
1838 				     (serdes_num, SATA_TX_CONFIG_SEQ2));
1839 
1840 			udelay(10000);
1841 			break;
1842 		case SGMII0:
1843 		case SGMII1:
1844 		case SGMII2:
1845 			CHECK_STATUS(mv_seq_exec
1846 				     (serdes_num, SGMII_POWER_UP_SEQ));
1847 			CHECK_STATUS(hws_ref_clock_set
1848 				     (serdes_num, serdes_type, ref_clock));
1849 			CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
1850 			CHECK_STATUS(mv_seq_exec
1851 				     (serdes_num, SGMII_ELECTRICAL_CONFIG_SEQ));
1852 			CHECK_STATUS(mv_seq_exec
1853 				     (serdes_num, SGMII_TX_CONFIG_SEQ1));
1854 			CHECK_STATUS(mv_seq_exec
1855 				     (serdes_num, SGMII_TX_CONFIG_SEQ2));
1856 
1857 			/* GBE configuration */
1858 			reg_data = reg_read(GBE_CONFIGURATION_REG);
1859 			/* write the SGMII index */
1860 			reg_data |= 0x1 << (serdes_type - SGMII0);
1861 			reg_write(GBE_CONFIGURATION_REG, reg_data);
1862 
1863 			break;
1864 		case QSGMII:
1865 			if (hws_ctrl_serdes_rev_get() < MV_SERDES_REV_2_1)
1866 				return MV_NOT_SUPPORTED;
1867 
1868 			CHECK_STATUS(mv_seq_exec
1869 				     (serdes_num, QSGMII_POWER_UP_SEQ));
1870 			CHECK_STATUS(hws_ref_clock_set
1871 				     (serdes_num, serdes_type, ref_clock));
1872 			CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
1873 			CHECK_STATUS(mv_seq_exec
1874 				     (serdes_num,
1875 				      QSGMII_ELECTRICAL_CONFIG_SEQ));
1876 			CHECK_STATUS(mv_seq_exec
1877 				     (serdes_num, QSGMII_TX_CONFIG_SEQ1));
1878 			CHECK_STATUS(mv_seq_exec
1879 				     (serdes_num, QSGMII_TX_CONFIG_SEQ2));
1880 			break;
1881 		case SGMII3:
1882 		case XAUI:
1883 		case RXAUI:
1884 			CHECK_STATUS(serdes_power_up_ctrl_ext
1885 				     (serdes_num, serdes_power_up, serdes_type,
1886 				      baud_rate, serdes_mode, ref_clock));
1887 			break;
1888 		default:
1889 			DEBUG_INIT_S
1890 			    ("serdes_power_up_ctrl: bad serdes_type parameter\n");
1891 			return MV_BAD_PARAM;
1892 		}
1893 	} else {		/* Serdes power down */
1894 		DEBUG_INIT_FULL_S("serdes_power_up: executing power down.. ");
1895 		DEBUG_INIT_FULL_C("serdes num = ", serdes_num, 1);
1896 
1897 		CHECK_STATUS(mv_seq_exec(serdes_num, SERDES_POWER_DOWN_SEQ));
1898 	}
1899 
1900 	DEBUG_INIT_FULL_C(
1901 		"serdes_power_up_ctrl ended successfully for serdes ",
1902 		serdes_num, 2);
1903 
1904 	return MV_OK;
1905 }
1906 
hws_update_serdes_phy_selectors(struct serdes_map * serdes_map,u8 count)1907 int hws_update_serdes_phy_selectors(struct serdes_map *serdes_map, u8 count)
1908 {
1909 	u32 lane_data, idx, serdes_lane_hw_num, reg_data = 0;
1910 	enum serdes_type serdes_type;
1911 	enum serdes_mode serdes_mode;
1912 	u8 select_bit_off;
1913 	int is_pex_x4 = 0;
1914 	int updated_topology_print = 0;
1915 
1916 	DEBUG_INIT_FULL_S("\n### hws_update_serdes_phy_selectors ###\n");
1917 	DEBUG_INIT_FULL_S
1918 	    ("Updating the COMMON PHYS SELECTORS register with the serdes types\n");
1919 
1920 	if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2)
1921 		select_bit_off = 3;
1922 	else
1923 		select_bit_off = 4;
1924 
1925 	/*
1926 	 * Updating bits 0-17 in the COMMON PHYS SELECTORS register
1927 	 * according to the serdes types
1928 	 */
1929 	for (idx = 0; idx < count; idx++) {
1930 		serdes_type = serdes_map[idx].serdes_type;
1931 		serdes_mode = serdes_map[idx].serdes_mode;
1932 		serdes_lane_hw_num = hws_get_physical_serdes_num(idx);
1933 
1934 		lane_data =
1935 		    hws_serdes_get_phy_selector_val(serdes_lane_hw_num,
1936 						    serdes_type);
1937 
1938 		if (serdes_type == DEFAULT_SERDES)
1939 			continue;
1940 
1941 		if (hws_serdes_topology_verify
1942 		    (serdes_type, idx, serdes_mode) != MV_OK) {
1943 			serdes_map[idx].serdes_type =
1944 			    DEFAULT_SERDES;
1945 			printf("%s: SerDes lane #%d is  disabled\n", __func__,
1946 			       serdes_lane_hw_num);
1947 			updated_topology_print = 1;
1948 			continue;
1949 		}
1950 
1951 		/*
1952 		 * Checking if the board topology configuration includes
1953 		 * PEXx4 - for the next step
1954 		 */
1955 		if ((serdes_mode == PEX_END_POINT_X4) ||
1956 		    (serdes_mode == PEX_ROOT_COMPLEX_X4)) {
1957 			/* update lane data to the 3 next SERDES lanes */
1958 			lane_data =
1959 			    common_phys_selectors_pex_by4_lanes
1960 			    [serdes_lane_hw_num];
1961 			if (serdes_type == PEX0)
1962 				is_pex_x4 = 1;
1963 		}
1964 
1965 		if (lane_data == NA) {
1966 			printf
1967 			    ("%s: Warning: SerDes lane #%d and type %d are not supported together\n",
1968 			     __func__, serdes_lane_hw_num, serdes_mode);
1969 			serdes_map[idx].serdes_type = DEFAULT_SERDES;
1970 			printf("%s: SerDes lane #%d is  disabled\n", __func__,
1971 			       serdes_lane_hw_num);
1972 			continue;
1973 		}
1974 
1975 		/*
1976 		 * Updating the data that will be written to
1977 		 * COMMON_PHYS_SELECTORS_REG
1978 		 */
1979 		reg_data |= (lane_data <<
1980 			     (select_bit_off * serdes_lane_hw_num));
1981 	}
1982 
1983 	/*
1984 	 * Check that number of used lanes for XAUI and RXAUI
1985 	 * (if used) is right
1986 	 */
1987 	hws_serdes_xaui_topology_verify();
1988 
1989 	/* Print topology */
1990 	if (updated_topology_print)
1991 		print_topology_details(serdes_map, count);
1992 
1993 	/*
1994 	 * Updating the PEXx4 Enable bit in the COMMON PHYS SELECTORS
1995 	 * register for PEXx4 mode
1996 	 */
1997 	reg_data |= (is_pex_x4 == 1) ? (0x1 << PEX_X4_ENABLE_OFFS) : 0;
1998 
1999 	/* Updating the COMMON PHYS SELECTORS register */
2000 	reg_write(COMMON_PHYS_SELECTORS_REG, reg_data);
2001 
2002 	return MV_OK;
2003 }
2004 
hws_ref_clock_set(u32 serdes_num,enum serdes_type serdes_type,enum ref_clock ref_clock)2005 int hws_ref_clock_set(u32 serdes_num, enum serdes_type serdes_type,
2006 		      enum ref_clock ref_clock)
2007 {
2008 	u32 data1 = 0, data2 = 0, data3 = 0, reg_data;
2009 
2010 	DEBUG_INIT_FULL_S("\n### hws_ref_clock_set ###\n");
2011 
2012 	if (hws_is_serdes_active(serdes_num) != 1) {
2013 		printf("%s: SerDes lane #%d is not Active\n", __func__,
2014 		       serdes_num);
2015 		return MV_BAD_PARAM;
2016 	}
2017 
2018 	switch (serdes_type) {
2019 	case PEX0:
2020 	case PEX1:
2021 	case PEX2:
2022 	case PEX3:
2023 		switch (ref_clock) {
2024 		case REF_CLOCK_25MHZ:
2025 			CHECK_STATUS(mv_seq_exec
2026 				     (serdes_num,
2027 				      PEX_CONFIG_REF_CLOCK_25MHZ_SEQ));
2028 			return MV_OK;
2029 		case REF_CLOCK_100MHZ:
2030 			CHECK_STATUS(mv_seq_exec
2031 				     (serdes_num,
2032 				      PEX_CONFIG_REF_CLOCK_100MHZ_SEQ));
2033 			return MV_OK;
2034 		default:
2035 			printf
2036 			    ("%s: Error: ref_clock %d for SerDes lane #%d, type %d is not supported\n",
2037 			     __func__, ref_clock, serdes_num, serdes_type);
2038 			return MV_BAD_PARAM;
2039 		}
2040 	case USB3_HOST0:
2041 	case USB3_HOST1:
2042 	case USB3_DEVICE:
2043 		if (ref_clock == REF_CLOCK_25MHZ) {
2044 			data1 = POWER_AND_PLL_CTRL_REG_25MHZ_VAL_2;
2045 			data2 = GLOBAL_PM_CTRL_REG_25MHZ_VAL;
2046 			data3 = LANE_CFG4_REG_25MHZ_VAL;
2047 		} else if (ref_clock == REF_CLOCK_40MHZ) {
2048 			data1 = POWER_AND_PLL_CTRL_REG_40MHZ_VAL;
2049 			data2 = GLOBAL_PM_CTRL_REG_40MHZ_VAL;
2050 			data3 = LANE_CFG4_REG_40MHZ_VAL;
2051 		} else {
2052 			printf
2053 			    ("hws_ref_clock_set: ref clock is not valid for serdes type %d\n",
2054 			     serdes_type);
2055 			return MV_BAD_PARAM;
2056 		}
2057 		break;
2058 	case SATA0:
2059 	case SATA1:
2060 	case SATA2:
2061 	case SATA3:
2062 	case SGMII0:
2063 	case SGMII1:
2064 	case SGMII2:
2065 	case QSGMII:
2066 		if (ref_clock == REF_CLOCK_25MHZ) {
2067 			data1 = POWER_AND_PLL_CTRL_REG_25MHZ_VAL_1;
2068 		} else if (ref_clock == REF_CLOCK_40MHZ) {
2069 			data1 = POWER_AND_PLL_CTRL_REG_40MHZ_VAL;
2070 		} else {
2071 			printf
2072 			    ("hws_ref_clock_set: ref clock is not valid for serdes type %d\n",
2073 			     serdes_type);
2074 			return MV_BAD_PARAM;
2075 		}
2076 		break;
2077 	default:
2078 		DEBUG_INIT_S("hws_ref_clock_set: not supported serdes type\n");
2079 		return MV_BAD_PARAM;
2080 	}
2081 
2082 	/*
2083 	 * Write the ref_clock to relevant SELECT_REF_CLOCK_REG bits and
2084 	 * offset
2085 	 */
2086 	reg_data = reg_read(POWER_AND_PLL_CTRL_REG +
2087 			    SERDES_REGS_LANE_BASE_OFFSET(serdes_num));
2088 	reg_data &= POWER_AND_PLL_CTRL_REG_MASK;
2089 	reg_data |= data1;
2090 	reg_write(POWER_AND_PLL_CTRL_REG +
2091 		  SERDES_REGS_LANE_BASE_OFFSET(serdes_num), reg_data);
2092 
2093 	if ((serdes_type == USB3_HOST0) || (serdes_type == USB3_HOST1) ||
2094 	    (serdes_type == USB3_DEVICE)) {
2095 		reg_data = reg_read(GLOBAL_PM_CTRL +
2096 				    SERDES_REGS_LANE_BASE_OFFSET(serdes_num));
2097 		reg_data &= GLOBAL_PM_CTRL_REG_MASK;
2098 		reg_data |= data2;
2099 		reg_write(GLOBAL_PM_CTRL +
2100 			  SERDES_REGS_LANE_BASE_OFFSET(serdes_num), reg_data);
2101 
2102 		reg_data = reg_read(LANE_CFG4_REG +
2103 				    SERDES_REGS_LANE_BASE_OFFSET(serdes_num));
2104 		reg_data &= LANE_CFG4_REG_MASK;
2105 		reg_data |= data3;
2106 		reg_write(LANE_CFG4_REG +
2107 			  SERDES_REGS_LANE_BASE_OFFSET(serdes_num), reg_data);
2108 	}
2109 
2110 	return MV_OK;
2111 }
2112 
2113 /*
2114  * hws_pex_tx_config_seq -
2115  *
2116  * DESCRIPTION:          Set PEX_TX_CONFIG_SEQ sequence init for PEXx4 mode
2117  * INPUT:                serdes_map       - The board topology map
2118  * OUTPUT:               None
2119  * RETURNS:              MV_OK           - for success
2120  *                       MV_BAD_PARAM    - for fail
2121  */
hws_pex_tx_config_seq(const struct serdes_map * serdes_map,u8 count)2122 int hws_pex_tx_config_seq(const struct serdes_map *serdes_map, u8 count)
2123 {
2124 	enum serdes_mode serdes_mode;
2125 	u32 serdes_lane_id, serdes_lane_hw_num;
2126 
2127 	DEBUG_INIT_FULL_S("\n### hws_pex_tx_config_seq ###\n");
2128 
2129 	/*
2130 	 * For PEXx4: the pex_and_usb3_tx_config_params1/2/3
2131 	 * configurations should run by setting each sequence for
2132 	 * all 4 lanes.
2133 	 */
2134 
2135 	/* relese pipe soft reset for all lanes */
2136 	for (serdes_lane_id = 0; serdes_lane_id < count; serdes_lane_id++) {
2137 		serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
2138 		serdes_lane_hw_num =
2139 		    hws_get_physical_serdes_num(serdes_lane_id);
2140 
2141 		if ((serdes_mode == PEX_ROOT_COMPLEX_X4) ||
2142 		    (serdes_mode == PEX_END_POINT_X4)) {
2143 			CHECK_STATUS(mv_seq_exec
2144 				     (serdes_lane_hw_num, PEX_TX_CONFIG_SEQ1));
2145 		}
2146 	}
2147 
2148 	/* set phy soft reset for all lanes */
2149 	for (serdes_lane_id = 0; serdes_lane_id < count; serdes_lane_id++) {
2150 		serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
2151 		serdes_lane_hw_num =
2152 		    hws_get_physical_serdes_num(serdes_lane_id);
2153 		if ((serdes_mode == PEX_ROOT_COMPLEX_X4) ||
2154 		    (serdes_mode == PEX_END_POINT_X4)) {
2155 			CHECK_STATUS(mv_seq_exec
2156 				     (serdes_lane_hw_num, PEX_TX_CONFIG_SEQ2));
2157 		}
2158 	}
2159 
2160 	/* set phy soft reset for all lanes */
2161 	for (serdes_lane_id = 0; serdes_lane_id < count; serdes_lane_id++) {
2162 		serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
2163 		serdes_lane_hw_num =
2164 		    hws_get_physical_serdes_num(serdes_lane_id);
2165 		if ((serdes_mode == PEX_ROOT_COMPLEX_X4) ||
2166 		    (serdes_mode == PEX_END_POINT_X4)) {
2167 			CHECK_STATUS(mv_seq_exec
2168 				     (serdes_lane_hw_num, PEX_TX_CONFIG_SEQ3));
2169 		}
2170 	}
2171 
2172 	return MV_OK;
2173 }
2174