Home | History | Annotate | Download | only in a38x
      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  */
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   1557 int ctrl_high_speed_serdes_phy_config(void)
   1558 {
   1559 	return hws_ctrl_high_speed_serdes_phy_config();
   1560 }
   1561 
   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  */
   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 
   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 
   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 
   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 
   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  */
   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