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