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