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