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