1 /* 2 * Copyright (C) Marvell International Ltd. and its affiliates 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <i2c.h> 9 #include <spl.h> 10 #include <asm/io.h> 11 #include <asm/arch/cpu.h> 12 #include <asm/arch/soc.h> 13 14 #include "high_speed_env_spec.h" 15 #include "board_env_spec.h" 16 17 #define SERDES_VERION "2.1.5" 18 #define ENDED_OK "High speed PHY - Ended Successfully\n" 19 20 static const u8 serdes_cfg[][SERDES_LAST_UNIT] = BIN_SERDES_CFG; 21 22 extern MV_BIN_SERDES_CFG *serdes_info_tbl[]; 23 24 extern u8 rd78460gp_twsi_dev[]; 25 extern u8 db88f78xx0rev2_twsi_dev[]; 26 27 u32 pex_cfg_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 offs); 28 int pex_local_bus_num_set(u32 pex_if, u32 bus_num); 29 int pex_local_dev_num_set(u32 pex_if, u32 dev_num); 30 31 #define MV_BOARD_PEX_MODULE_ADDR 0x23 32 #define MV_BOARD_PEX_MODULE_ID 1 33 #define MV_BOARD_ETM_MODULE_ID 2 34 35 #define PEX_MODULE_DETECT 1 36 #define ETM_MODULE_DETECT 2 37 38 #define PEX_MODE_GET(satr) ((satr & 0x6) >> 1) 39 #define PEX_CAPABILITY_GET(satr) (satr & 1) 40 #define MV_PEX_UNIT_TO_IF(pex_unit) ((pex_unit < 3) ? (pex_unit * 4) : 9) 41 42 /* Static parametes */ 43 static int config_module; 44 static int switch_module; 45 46 /* Local function */ 47 static u32 board_id_get(void) 48 { 49 #if defined(CONFIG_DB_88F78X60) 50 return DB_88F78XX0_BP_ID; 51 #elif defined(CONFIG_RD_88F78460_SERVER) 52 return RD_78460_SERVER_ID; 53 #elif defined(CONFIG_RD_78460_SERVER_REV2) 54 return RD_78460_SERVER_REV2_ID; 55 #elif defined(CONFIG_DB_78X60_PCAC) 56 return DB_78X60_PCAC_ID; 57 #elif defined(CONFIG_DB_88F78X60_REV2) 58 return DB_88F78XX0_BP_REV2_ID; 59 #elif defined(CONFIG_RD_78460_NAS) 60 return RD_78460_NAS_ID; 61 #elif defined(CONFIG_DB_78X60_AMC) 62 return DB_78X60_AMC_ID; 63 #elif defined(CONFIG_DB_78X60_PCAC_REV2) 64 return DB_78X60_PCAC_REV2_ID; 65 #elif defined(CONFIG_DB_784MP_GP) 66 return DB_784MP_GP_ID; 67 #elif defined(CONFIG_RD_78460_CUSTOMER) 68 return RD_78460_CUSTOMER_ID; 69 #else 70 /* 71 * Return 0 here for custom board as this should not be used 72 * for custom boards. 73 */ 74 return 0; 75 #endif 76 } 77 78 __weak u8 board_sat_r_get(u8 dev_num, u8 reg) 79 { 80 u8 data; 81 u8 *dev; 82 u32 board_id = board_id_get(); 83 int ret; 84 85 switch (board_id) { 86 case DB_78X60_AMC_ID: 87 case DB_78X60_PCAC_REV2_ID: 88 case RD_78460_CUSTOMER_ID: 89 case RD_78460_SERVER_ID: 90 case RD_78460_SERVER_REV2_ID: 91 case DB_78X60_PCAC_ID: 92 return (0x1 << 1) | 1; 93 case FPGA_88F78XX0_ID: 94 case RD_78460_NAS_ID: 95 return (0x0 << 1) | 1; 96 case DB_784MP_GP_ID: 97 dev = rd78460gp_twsi_dev; 98 99 break; 100 case DB_88F78XX0_BP_ID: 101 case DB_88F78XX0_BP_REV2_ID: 102 dev = db88f78xx0rev2_twsi_dev; 103 break; 104 105 default: 106 return 0; 107 } 108 109 /* Read MPP module ID */ 110 i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); 111 ret = i2c_read(dev[dev_num], 0, 1, (u8 *)&data, 1); 112 if (ret) 113 return MV_ERROR; 114 115 return data; 116 } 117 118 static int board_modules_scan(void) 119 { 120 u8 val; 121 u32 board_id = board_id_get(); 122 int ret; 123 124 /* Perform scan only for DB board */ 125 if ((board_id == DB_88F78XX0_BP_ID) || 126 (board_id == DB_88F78XX0_BP_REV2_ID)) { 127 /* reset modules flags */ 128 config_module = 0; 129 130 i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); 131 132 /* SERDES module (only PEX model is supported now) */ 133 ret = i2c_read(MV_BOARD_PEX_MODULE_ADDR, 0, 1, (u8 *)&val, 1); 134 if (ret) 135 return MV_ERROR; 136 137 if (val == MV_BOARD_PEX_MODULE_ID) 138 config_module = PEX_MODULE_DETECT; 139 if (val == MV_BOARD_ETM_MODULE_ID) 140 config_module = ETM_MODULE_DETECT; 141 } else if (board_id == RD_78460_NAS_ID) { 142 switch_module = 0; 143 if ((reg_read(GPP_DATA_IN_REG(2)) & MV_GPP66) == 0x0) 144 switch_module = 1; 145 } 146 147 return MV_OK; 148 } 149 150 u32 pex_max_unit_get(void) 151 { 152 /* 153 * TODO: 154 * Right now only MV78460 is supported. Other SoC's might need 155 * a different value here. 156 */ 157 return MV_PEX_MAX_UNIT; 158 } 159 160 u32 pex_max_if_get(void) 161 { 162 /* 163 * TODO: 164 * Right now only MV78460 is supported. Other SoC's might need 165 * a different value here. 166 */ 167 return MV_PEX_MAX_IF; 168 } 169 170 u8 board_cpu_freq_get(void) 171 { 172 u32 sar; 173 u32 sar_msb; 174 175 sar = reg_read(MPP_SAMPLE_AT_RESET(0)); 176 sar_msb = reg_read(MPP_SAMPLE_AT_RESET(1)); 177 return ((sar_msb & 0x100000) >> 17) | ((sar & 0xe00000) >> 21); 178 } 179 180 __weak MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode) 181 { 182 u32 board_id; 183 u32 serdes_cfg_val = 0; /* default */ 184 185 board_id = board_id_get(); 186 187 switch (board_id) { 188 case DB_784MP_GP_ID: 189 serdes_cfg_val = 0; 190 break; 191 } 192 193 return &serdes_info_tbl[board_id - BOARD_ID_BASE][serdes_cfg_val]; 194 } 195 196 u16 ctrl_model_get(void) 197 { 198 /* 199 * SoC version can't be autodetected. So we need to rely on a define 200 * from the config system here. 201 */ 202 #if defined(CONFIG_MV78230) 203 return MV_78230_DEV_ID; 204 #elif defined(CONFIG_MV78260) 205 return MV_78260_DEV_ID; 206 #else 207 return MV_78460_DEV_ID; 208 #endif 209 } 210 211 u32 get_line_cfg(u32 line_num, MV_BIN_SERDES_CFG *info) 212 { 213 if (line_num < 8) 214 return (info->line0_7 >> (line_num << 2)) & 0xF; 215 else 216 return (info->line8_15 >> ((line_num - 8) << 2)) & 0xF; 217 } 218 219 static int serdes_max_lines_get(void) 220 { 221 switch (ctrl_model_get()) { 222 case MV_78230_DEV_ID: 223 return 7; 224 case MV_78260_DEV_ID: 225 return 12; 226 case MV_78460_DEV_ID: 227 return 16; 228 } 229 230 return 0; 231 } 232 233 /* 234 * Tests have shown that on some boards the default width of the 235 * configuration pulse for the PEX link detection might lead to 236 * non-established PCIe links (link down). Especially under certain 237 * conditions (higher temperature) and with specific PCIe devices. 238 * To enable a board-specific detection pulse width this weak 239 * array "serdes_pex_pulse_width[4]" is introduced which can be 240 * overwritten if needed by a board-specific version. If the board 241 * code does not provide a non-weak version of this variable, the 242 * default value will be used. So nothing is changed from the 243 * current setup on the supported board. 244 */ 245 __weak u8 serdes_pex_pulse_width[4] = { 2, 2, 2, 2 }; 246 247 int serdes_phy_config(void) 248 { 249 int status = MV_OK; 250 u32 line_cfg; 251 u8 line_num; 252 /* addr/value for each line @ every setup step */ 253 u32 addr[16][11], val[16][11]; 254 u8 pex_unit, pex_line_num; 255 u8 sgmii_port = 0; 256 u32 tmp; 257 u32 in_direct; 258 u8 max_serdes_lines; 259 MV_BIN_SERDES_CFG *info; 260 u8 satr11; 261 u8 sata_port; 262 u8 freq; 263 u8 device_rev; 264 u32 rx_high_imp_mode; 265 u16 ctrl_mode; 266 u32 pex_if; 267 u32 pex_if_num; 268 269 /* 270 * Get max. serdes lines count 271 */ 272 max_serdes_lines = serdes_max_lines_get(); 273 if (max_serdes_lines == 0) 274 return MV_OK; 275 276 satr11 = board_sat_r_get(1, 1); 277 if ((u8) MV_ERROR == (u8) satr11) 278 return MV_ERROR; 279 280 board_modules_scan(); 281 memset(addr, 0, sizeof(addr)); 282 memset(val, 0, sizeof(val)); 283 284 /* Check if DRAM is already initialized */ 285 if (reg_read(REG_BOOTROM_ROUTINE_ADDR) & 286 (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) { 287 DEBUG_INIT_S("High speed PHY - Version: "); 288 DEBUG_INIT_S(SERDES_VERION); 289 DEBUG_INIT_S(" - 2nd boot - Skip\n"); 290 return MV_OK; 291 } 292 DEBUG_INIT_S("High speed PHY - Version: "); 293 DEBUG_INIT_S(SERDES_VERION); 294 DEBUG_INIT_S(" (COM-PHY-V20)\n"); 295 296 /* 297 * AVS : disable AVS for frequency less than 1333 298 */ 299 freq = board_cpu_freq_get(); 300 device_rev = mv_ctrl_rev_get(); 301 302 if (device_rev == 2) { /* for B0 only */ 303 u32 cpu_avs; 304 u8 fabric_freq; 305 cpu_avs = reg_read(CPU_AVS_CONTROL2_REG); 306 DEBUG_RD_REG(CPU_AVS_CONTROL2_REG, cpu_avs); 307 cpu_avs &= ~(1 << 9); 308 309 if ((0x4 == freq) || (0xB == freq)) { 310 u32 tmp2; 311 312 tmp2 = reg_read(CPU_AVS_CONTROL0_REG); 313 DEBUG_RD_REG(CPU_AVS_CONTROL0_REG, tmp2); 314 /* cpu upper limit = 1.1V cpu lower limit = 0.9125V */ 315 tmp2 |= 0x0FF; 316 reg_write(CPU_AVS_CONTROL0_REG, tmp2); 317 DEBUG_WR_REG(CPU_AVS_CONTROL0_REG, tmp2); 318 cpu_avs |= (1 << 9); /* cpu avs enable */ 319 cpu_avs |= (1 << 18); /* AvsAvddDetEn enable */ 320 fabric_freq = (reg_read(MPP_SAMPLE_AT_RESET(0)) & 321 SAR0_FABRIC_FREQ_MASK) >> SAR0_FABRIC_FREQ_OFFSET; 322 if ((0xB == freq) && (5 == fabric_freq)) { 323 u32 core_avs; 324 325 core_avs = reg_read(CORE_AVS_CONTROL_0REG); 326 DEBUG_RD_REG(CORE_AVS_CONTROL_0REG, core_avs); 327 328 /* 329 * Set core lower limit = 0.9V & 330 * core upper limit = 0.9125V 331 */ 332 core_avs &= ~(0xff); 333 core_avs |= 0x0E; 334 reg_write(CORE_AVS_CONTROL_0REG, core_avs); 335 DEBUG_WR_REG(CORE_AVS_CONTROL_0REG, core_avs); 336 337 core_avs = reg_read(CORE_AVS_CONTROL_2REG); 338 DEBUG_RD_REG(CORE_AVS_CONTROL_2REG, core_avs); 339 core_avs |= (1 << 9); /* core AVS enable */ 340 reg_write(CORE_AVS_CONTROL_2REG, core_avs); 341 DEBUG_WR_REG(CORE_AVS_CONTROL_2REG, core_avs); 342 343 tmp2 = reg_read(GENERAL_PURPOSE_RESERVED0_REG); 344 DEBUG_RD_REG(GENERAL_PURPOSE_RESERVED0_REG, 345 tmp2); 346 tmp2 |= 0x1; /* AvsCoreAvddDetEn enable */ 347 reg_write(GENERAL_PURPOSE_RESERVED0_REG, tmp2); 348 DEBUG_WR_REG(GENERAL_PURPOSE_RESERVED0_REG, 349 tmp2); 350 } 351 } 352 reg_write(CPU_AVS_CONTROL2_REG, cpu_avs); 353 DEBUG_WR_REG(CPU_AVS_CONTROL2_REG, cpu_avs); 354 } 355 356 info = board_serdes_cfg_get(PEX_MODE_GET(satr11)); 357 DEBUG_INIT_FULL_S("info->line0_7= 0x"); 358 DEBUG_INIT_FULL_D(info->line0_7, 8); 359 DEBUG_INIT_FULL_S(" info->line8_15= 0x"); 360 DEBUG_INIT_FULL_D(info->line8_15, 8); 361 DEBUG_INIT_FULL_S("\n"); 362 363 if (info == NULL) { 364 DEBUG_INIT_S("Hight speed PHY Error #1\n"); 365 return MV_ERROR; 366 } 367 368 if (config_module & ETM_MODULE_DETECT) { /* step 0.9 ETM */ 369 DEBUG_INIT_FULL_S("ETM module detect Step 0.9:\n"); 370 reg_write(SERDES_LINE_MUX_REG_0_7, 0x11111111); 371 DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, 0x11111111); 372 info->pex_mode[1] = PEX_BUS_DISABLED; /* pex unit 1 is configure for ETM */ 373 mdelay(100); 374 reg_write(PEX_PHY_ACCESS_REG(1), (0x002 << 16) | 0xf44d); /* SETM0 - start calibration */ 375 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x002 << 16) | 0xf44d); /* SETM0 - start calibration */ 376 reg_write(PEX_PHY_ACCESS_REG(1), (0x302 << 16) | 0xf44d); /* SETM1 - start calibration */ 377 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x302 << 16) | 0xf44d); /* SETM1 - start calibration */ 378 reg_write(PEX_PHY_ACCESS_REG(1), (0x001 << 16) | 0xf801); /* SETM0 - SATA mode & 25MHz ref clk */ 379 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x001 << 16) | 0xf801); /* SETM0 - SATA mode & 25MHz ref clk */ 380 reg_write(PEX_PHY_ACCESS_REG(1), (0x301 << 16) | 0xf801); /* SETM1 - SATA mode & 25MHz ref clk */ 381 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x301 << 16) | 0xf801); /* SETM1 - SATA mode & 25MHz ref clk */ 382 reg_write(PEX_PHY_ACCESS_REG(1), (0x011 << 16) | 0x0BFF); /* SETM0 - G3 full swing AMP */ 383 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x011 << 16) | 0x0BFF); /* SETM0 - G3 full swing AMP */ 384 reg_write(PEX_PHY_ACCESS_REG(1), (0x311 << 16) | 0x0BFF); /* SETM1 - G3 full swing AMP */ 385 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x311 << 16) | 0x0BFF); /* SETM1 - G3 full swing AMP */ 386 reg_write(PEX_PHY_ACCESS_REG(1), (0x023 << 16) | 0x0800); /* SETM0 - 40 data bit width */ 387 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x023 << 16) | 0x0800); /* SETM0 - 40 data bit width */ 388 reg_write(PEX_PHY_ACCESS_REG(1), (0x323 << 16) | 0x0800); /* SETM1 - 40 data bit width */ 389 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x323 << 16) | 0x0800); /* SETM1 - 40 data bit width */ 390 reg_write(PEX_PHY_ACCESS_REG(1), (0x046 << 16) | 0x0400); /* lane0(serdes4) */ 391 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x046 << 16) | 0x0400); /* lane0(serdes4) */ 392 reg_write(PEX_PHY_ACCESS_REG(1), (0x346 << 16) | 0x0400); /* lane3(serdes7) */ 393 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x346 << 16) | 0x0400); /* lane3(serdes7) */ 394 } 395 396 /* STEP -1 [PEX-Only] First phase of PEX-PIPE Configuration: */ 397 DEBUG_INIT_FULL_S("Step 1: First phase of PEX-PIPE Configuration\n"); 398 for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) { 399 if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) 400 continue; 401 402 /* 1. GLOB_CLK_CTRL Reset and Clock Control */ 403 reg_write(PEX_PHY_ACCESS_REG(pex_unit), (0xC1 << 16) | 0x25); 404 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), (0xC1 << 16) | 0x25); 405 406 /* 2. GLOB_TEST_CTRL Test Mode Control */ 407 if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) { 408 reg_write(PEX_PHY_ACCESS_REG(pex_unit), 409 (0xC2 << 16) | 0x200); 410 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), 411 (0xC2 << 16) | 0x200); 412 } 413 414 /* 3. GLOB_CLK_SRC_LO Clock Source Low */ 415 if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1) { 416 reg_write(PEX_PHY_ACCESS_REG(pex_unit), 417 (0xC3 << 16) | 0x0F); 418 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), 419 (0xC3 << 16) | 0x0F); 420 } 421 422 reg_write(PEX_PHY_ACCESS_REG(pex_unit), (0xC5 << 16) | 0x11F); 423 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), 424 (0xC5 << 16) | 0x11F); 425 } 426 427 /* 428 * 2 Configure the desire PIN_PHY_GEN and do power down to the PU_PLL, 429 * PU_RX,PU_TX. (bits[12:5]) 430 */ 431 DEBUG_INIT_FULL_S("Step 2: Configure the desire PIN_PHY_GEN\n"); 432 for (line_num = 0; line_num < max_serdes_lines; line_num++) { 433 line_cfg = get_line_cfg(line_num, info); 434 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) 435 continue; 436 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) 437 continue; 438 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) { 439 switch (line_num) { 440 case 4: 441 case 6: 442 sata_port = 0; 443 break; 444 case 5: 445 sata_port = 1; 446 break; 447 default: 448 DEBUG_INIT_C 449 ("SATA port error for serdes line: ", 450 line_num, 2); 451 return MV_ERROR; 452 } 453 tmp = reg_read(SATA_LP_PHY_EXT_CTRL_REG(sata_port)); 454 DEBUG_RD_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); 455 tmp &= ~((0x1ff << 5) | 0x7); 456 tmp |= ((info->bus_speed & (1 << line_num)) != 0) ? 457 (0x11 << 5) : 0x0; 458 459 reg_write(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); 460 DEBUG_WR_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); 461 } 462 463 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { 464 /* 465 * 4) Configure the desire PIN_PHY_GEN and do power 466 * down to the PU_PLL,PU_RX,PU_TX. (bits[12:5]) 467 */ 468 tmp = reg_read(SGMII_SERDES_CFG_REG(0)); 469 DEBUG_RD_REG(SGMII_SERDES_CFG_REG(0), tmp); 470 tmp &= ~((0x1ff << 5) | 0x7); 471 tmp |= 0x660; 472 reg_write(SGMII_SERDES_CFG_REG(0), tmp); 473 DEBUG_WR_REG(SGMII_SERDES_CFG_REG(0), tmp); 474 continue; 475 } 476 477 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0]) 478 sgmii_port = 0; 479 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1]) 480 sgmii_port = 1; 481 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2]) 482 sgmii_port = 2; 483 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3]) 484 sgmii_port = 3; 485 else 486 continue; 487 488 tmp = reg_read(SGMII_SERDES_CFG_REG(sgmii_port)); 489 DEBUG_RD_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp); 490 tmp &= ~((0x1ff << 5) | 0x7); 491 tmp |= (((info->bus_speed & (1 << line_num)) != 0) ? 492 (0x88 << 5) : (0x66 << 5)); 493 reg_write(SGMII_SERDES_CFG_REG(sgmii_port), tmp); 494 DEBUG_WR_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp); 495 } 496 497 /* Step 3 - QSGMII enable */ 498 DEBUG_INIT_FULL_S("Step 3 QSGMII enable\n"); 499 for (line_num = 0; line_num < max_serdes_lines; line_num++) { 500 line_cfg = get_line_cfg(line_num, info); 501 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { 502 /* QSGMII Active bit set to true */ 503 tmp = reg_read(QSGMII_CONTROL_1_REG); 504 DEBUG_RD_REG(QSGMII_CONTROL_1_REG, tmp); 505 tmp |= (1 << 30); 506 #ifdef ERRATA_GL_6572255 507 tmp |= (1 << 27); 508 #endif 509 reg_write(QSGMII_CONTROL_1_REG, tmp); 510 DEBUG_WR_REG(QSGMII_CONTROL_1_REG, tmp); 511 } 512 } 513 514 /* Step 4 - configure SERDES MUXes */ 515 DEBUG_INIT_FULL_S("Step 4: Configure SERDES MUXes\n"); 516 if (config_module & ETM_MODULE_DETECT) { 517 reg_write(SERDES_LINE_MUX_REG_0_7, 0x40041111); 518 DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, 0x40041111); 519 } else { 520 reg_write(SERDES_LINE_MUX_REG_0_7, info->line0_7); 521 DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, info->line0_7); 522 } 523 reg_write(SERDES_LINE_MUX_REG_8_15, info->line8_15); 524 DEBUG_WR_REG(SERDES_LINE_MUX_REG_8_15, info->line8_15); 525 526 /* Step 5: Activate the RX High Impedance Mode */ 527 DEBUG_INIT_FULL_S("Step 5: Activate the RX High Impedance Mode\n"); 528 rx_high_imp_mode = 0x8080; 529 if (device_rev == 2) /* for B0 only */ 530 rx_high_imp_mode |= 4; 531 532 for (line_num = 0; line_num < max_serdes_lines; line_num++) { 533 /* for each serdes lane */ 534 DEBUG_INIT_FULL_S("SERDES "); 535 DEBUG_INIT_FULL_D_10(line_num, 2); 536 line_cfg = get_line_cfg(line_num, info); 537 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) { 538 DEBUG_INIT_FULL_S(" unconnected ***\n"); 539 continue; 540 } 541 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) { 542 pex_unit = line_num >> 2; 543 pex_line_num = line_num % 4; 544 DEBUG_INIT_FULL_S(" - PEX unit "); 545 DEBUG_INIT_FULL_D_10(pex_unit, 1); 546 DEBUG_INIT_FULL_S(" line= "); 547 DEBUG_INIT_FULL_D_10(pex_line_num, 1); 548 DEBUG_INIT_FULL_S("\n"); 549 550 /* Needed for PEX_PHY_ACCESS_REG macro */ 551 if ((line_num > 7) && 552 (info->pex_mode[3] == PEX_BUS_MODE_X8)) 553 /* lines 8 - 15 are belong to PEX3 in x8 mode */ 554 pex_unit = 3; 555 556 if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) 557 continue; 558 559 /* 560 * 8) Activate the RX High Impedance Mode field 561 * (bit [2]) in register /PCIe_USB Control (Each MAC 562 * contain different Access to reach its 563 * Serdes-Regfile). 564 * [PEX-Only] Set bit[12]: The analog part latches idle 565 * if PU_TX = 1 and PU_PLL =1. 566 */ 567 568 /* Termination enable */ 569 if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1) { 570 in_direct = (0x48 << 16) | (pex_line_num << 24) | 571 0x1000 | rx_high_imp_mode; /* x1 */ 572 } else if ((info->pex_mode[pex_unit] == 573 PEX_BUS_MODE_X4) && (pex_line_num == 0)) 574 in_direct = (0x48 << 16) | (pex_line_num << 24) | 575 0x1000 | (rx_high_imp_mode & 0xff); /* x4 */ 576 else 577 in_direct = 0; 578 579 if (in_direct) { 580 reg_write(PEX_PHY_ACCESS_REG(pex_unit), 581 in_direct); 582 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), 583 in_direct); 584 } 585 586 continue; 587 } 588 589 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) { 590 /* 591 * port 0 for serdes lines 4,6, and port 1 for 592 * serdes lines 5 593 */ 594 sata_port = line_num & 1; 595 DEBUG_INIT_FULL_S(" - SATA port "); 596 DEBUG_INIT_FULL_D_10(sata_port, 2); 597 DEBUG_INIT_FULL_S("\n"); 598 reg_write(SATA_COMPHY_CTRL_REG(sata_port), 599 rx_high_imp_mode); 600 DEBUG_WR_REG(SATA_COMPHY_CTRL_REG(sata_port), 601 rx_high_imp_mode); 602 continue; 603 } 604 605 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { 606 DEBUG_INIT_FULL_S(" - QSGMII\n"); 607 reg_write(SGMII_COMPHY_CTRL_REG(0), rx_high_imp_mode); 608 DEBUG_WR_REG(SGMII_COMPHY_CTRL_REG(0), 609 rx_high_imp_mode); 610 continue; 611 } 612 613 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0]) 614 sgmii_port = 0; 615 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1]) 616 sgmii_port = 1; 617 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2]) 618 sgmii_port = 2; 619 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3]) 620 sgmii_port = 3; 621 else 622 continue; 623 DEBUG_INIT_FULL_S(" - SGMII port "); 624 DEBUG_INIT_FULL_D_10(sgmii_port, 2); 625 DEBUG_INIT_FULL_S("\n"); 626 reg_write(SGMII_COMPHY_CTRL_REG(sgmii_port), rx_high_imp_mode); 627 DEBUG_WR_REG(SGMII_COMPHY_CTRL_REG(sgmii_port), 628 rx_high_imp_mode); 629 } /* for each serdes lane */ 630 631 /* Step 6 [PEX-Only] PEX-Main configuration (X4 or X1): */ 632 DEBUG_INIT_FULL_S("Step 6: [PEX-Only] PEX-Main configuration (X4 or X1)\n"); 633 tmp = reg_read(SOC_CTRL_REG); 634 DEBUG_RD_REG(SOC_CTRL_REG, tmp); 635 tmp &= 0x200; 636 if (info->pex_mode[0] == PEX_BUS_MODE_X1) 637 tmp |= PCIE0_QUADX1_EN; 638 if (info->pex_mode[1] == PEX_BUS_MODE_X1) 639 tmp |= PCIE1_QUADX1_EN; 640 if (((reg_read(MPP_SAMPLE_AT_RESET(0)) & PEX_CLK_100MHZ_MASK) >> 641 PEX_CLK_100MHZ_OFFSET) == 0x1) 642 tmp |= (PCIE0_CLK_OUT_EN_MASK | PCIE1_CLK_OUT_EN_MASK); 643 644 reg_write(SOC_CTRL_REG, tmp); 645 DEBUG_WR_REG(SOC_CTRL_REG, tmp); 646 647 /* 6.2 PCI Express Link Capabilities */ 648 DEBUG_INIT_FULL_S("Step 6.2: [PEX-Only] PCI Express Link Capabilities\n"); 649 650 for (line_num = 0; line_num < max_serdes_lines; line_num++) { 651 line_cfg = get_line_cfg(line_num, info); 652 653 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) { 654 /* 655 * PCI Express Control 656 * 0xX1A00 [0]: 657 * 0x0 X4-Link. 658 * 0x1 X1-Link 659 */ 660 pex_unit = line_num >> 2; 661 pex_if = MV_SERDES_NUM_TO_PEX_NUM(line_num); 662 if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) 663 continue; 664 665 /* set Common Clock Configuration */ 666 tmp = reg_read(PEX_LINK_CTRL_STATUS_REG(pex_if)); 667 DEBUG_RD_REG(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp); 668 tmp |= (1 << 6); 669 reg_write(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp); 670 DEBUG_WR_REG(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp); 671 672 tmp = reg_read(PEX_LINK_CAPABILITIES_REG(pex_if)); 673 DEBUG_RD_REG(PEX_LINK_CAPABILITIES_REG(pex_if), tmp); 674 tmp &= ~(0x3FF); 675 if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1) 676 tmp |= (0x1 << 4); 677 if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) 678 tmp |= (0x4 << 4); 679 if (0 == PEX_CAPABILITY_GET(satr11)) 680 tmp |= 0x1; 681 else 682 tmp |= 0x2; 683 DEBUG_INIT_FULL_S("Step 6.2: PEX "); 684 DEBUG_INIT_FULL_D(pex_if, 1); 685 DEBUG_INIT_FULL_C(" set GEN", (tmp & 3), 1); 686 reg_write(PEX_LINK_CAPABILITIES_REG(pex_if), tmp); 687 DEBUG_WR_REG(PEX_LINK_CAPABILITIES_REG(pex_if), tmp); 688 689 /* 690 * If pex is X4, no need to pass thru the other 691 * 3X1 serdes lines 692 */ 693 if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) 694 line_num += 3; 695 } 696 } 697 698 /* 699 * Step 7 [PEX-X4 Only] To create PEX-Link that contain 4-lanes you 700 * need to config the register SOC_Misc/General Purpose2 701 * (Address= 182F8) 702 */ 703 DEBUG_INIT_FULL_S("Step 7: [PEX-X4 Only] To create PEX-Link\n"); 704 tmp = reg_read(GEN_PURP_RES_2_REG); 705 DEBUG_RD_REG(GEN_PURP_RES_2_REG, tmp); 706 707 tmp &= 0xFFFF0000; 708 if (info->pex_mode[0] == PEX_BUS_MODE_X4) 709 tmp |= 0x0000000F; 710 711 if (info->pex_mode[1] == PEX_BUS_MODE_X4) 712 tmp |= 0x000000F0; 713 714 if (info->pex_mode[2] == PEX_BUS_MODE_X4) 715 tmp |= 0x00000F00; 716 717 if (info->pex_mode[3] == PEX_BUS_MODE_X4) 718 tmp |= 0x0000F000; 719 720 reg_write(GEN_PURP_RES_2_REG, tmp); 721 DEBUG_WR_REG(GEN_PURP_RES_2_REG, tmp); 722 723 /* Steps 8 , 9 ,10 - use prepared REG addresses and values */ 724 DEBUG_INIT_FULL_S("Steps 7,8,9,10 and 11\n"); 725 726 /* Prepare PHY parameters for each step according to MUX selection */ 727 for (line_num = 0; line_num < max_serdes_lines; line_num++) { 728 /* for each serdes lane */ 729 730 line_cfg = get_line_cfg(line_num, info); 731 732 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) 733 continue; 734 735 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) { 736 pex_unit = line_num >> 2; 737 pex_line_num = line_num % 4; 738 739 if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) 740 continue; 741 /* 742 * 8) Configure the desire PHY_MODE (bits [7:5]) 743 * and REF_FREF_SEL (bits[4:0]) in the register Power 744 * and PLL Control (Each MAC contain different Access 745 * to reach its Serdes-Regfile). 746 */ 747 if (((info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) && 748 (0 == pex_line_num)) 749 || ((info->pex_mode[pex_unit] == PEX_BUS_MODE_X1))) { 750 reg_write(PEX_PHY_ACCESS_REG(pex_unit), 751 (0x01 << 16) | (pex_line_num << 24) | 752 0xFC60); 753 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), 754 (0x01 << 16) | (pex_line_num << 24) 755 | 0xFC60); 756 /* 757 * Step 8.1: [PEX-Only] Configure Max PLL Rate 758 * (bit 8 in KVCO Calibration Control and 759 * bits[10:9] in 760 */ 761 /* Use Maximum PLL Rate(Bit 8) */ 762 reg_write(PEX_PHY_ACCESS_REG(pex_unit), 763 (0x02 << 16) | (1 << 31) | 764 (pex_line_num << 24)); /* read command */ 765 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), 766 (0x02 << 16) | (1 << 31) | 767 (pex_line_num << 24)); 768 tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit)); 769 DEBUG_RD_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp); 770 tmp &= ~(1 << 31); 771 tmp |= (1 << 8); 772 reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp); 773 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp); 774 775 /* Use Maximum PLL Rate(Bits [10:9]) */ 776 reg_write(PEX_PHY_ACCESS_REG(pex_unit), 777 (0x81 << 16) | (1 << 31) | 778 (pex_line_num << 24)); /* read command */ 779 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), 780 (0x81 << 16) | (1 << 31) | 781 (pex_line_num << 24)); 782 tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit)); 783 DEBUG_RD_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp); 784 tmp &= ~(1 << 31); 785 tmp |= (3 << 9); 786 reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp); 787 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp); 788 } 789 790 continue; 791 } 792 793 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) { 794 /* 795 * Port 0 for serdes lines 4,6, and port 1 for serdes 796 * lines 5 797 */ 798 sata_port = line_num & 1; 799 800 /* 801 * 8) Configure the desire PHY_MODE (bits [7:5]) and 802 * REF_FREF_SEL (bits[4:0]) in the register Power 803 * and PLL Control (Each MAC contain different Access 804 * to reach its Serdes-Regfile). 805 */ 806 reg_write(SATA_PWR_PLL_CTRL_REG(sata_port), 0xF801); 807 DEBUG_WR_REG(SATA_PWR_PLL_CTRL_REG(sata_port), 0xF801); 808 809 /* 9) Configure the desire SEL_BITS */ 810 reg_write(SATA_DIG_LP_ENA_REG(sata_port), 0x400); 811 DEBUG_WR_REG(SATA_DIG_LP_ENA_REG(sata_port), 0x400); 812 813 /* 10) Configure the desire REFCLK_SEL */ 814 815 reg_write(SATA_REF_CLK_SEL_REG(sata_port), 0x400); 816 DEBUG_WR_REG(SATA_REF_CLK_SEL_REG(sata_port), 0x400); 817 818 /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */ 819 tmp = reg_read(SATA_LP_PHY_EXT_CTRL_REG(sata_port)); 820 DEBUG_RD_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); 821 tmp |= 7; 822 reg_write(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); 823 DEBUG_WR_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); 824 825 continue; 826 } 827 828 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { 829 /* 830 * 8) Configure the desire PHY_MODE (bits [7:5]) 831 * and REF_FREF_SEL (bits[4:0]) in the register 832 */ 833 reg_write(SGMII_PWR_PLL_CTRL_REG(0), 0xF881); 834 DEBUG_WR_REG(SGMII_PWR_PLL_CTRL_REG(0), 0xF881); 835 836 /* 837 * 9) Configure the desire SEL_BITS (bits [11:0] 838 * in register 839 */ 840 reg_write(SGMII_DIG_LP_ENA_REG(0), 0x400); 841 DEBUG_WR_REG(SGMII_DIG_LP_ENA_REG(0), 0x400); 842 843 /* 844 * 10) Configure the desire REFCLK_SEL (bit [10]) 845 * in register 846 */ 847 reg_write(SGMII_REF_CLK_SEL_REG(0), 0x400); 848 DEBUG_WR_REG(SGMII_REF_CLK_SEL_REG(0), 0x400); 849 850 /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */ 851 tmp = reg_read(SGMII_SERDES_CFG_REG(0)); 852 DEBUG_RD_REG(SGMII_SERDES_CFG_REG(0), tmp); 853 tmp |= 7; 854 reg_write(SGMII_SERDES_CFG_REG(0), tmp); 855 DEBUG_WR_REG(SGMII_SERDES_CFG_REG(0), tmp); 856 continue; 857 } 858 859 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0]) 860 sgmii_port = 0; 861 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1]) 862 sgmii_port = 1; 863 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2]) 864 sgmii_port = 2; 865 else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3]) 866 sgmii_port = 3; 867 else 868 continue; 869 870 /* 871 * 8) Configure the desire PHY_MODE (bits [7:5]) and 872 * REF_FREF_SEL (bits[4:0]) in the register 873 */ 874 reg_write(SGMII_PWR_PLL_CTRL_REG(sgmii_port), 0xF881); 875 DEBUG_WR_REG(SGMII_PWR_PLL_CTRL_REG(sgmii_port), 0xF881); 876 877 /* 9) Configure the desire SEL_BITS (bits [11:0] in register */ 878 reg_write(SGMII_DIG_LP_ENA_REG(sgmii_port), 0); 879 DEBUG_WR_REG(SGMII_DIG_LP_ENA_REG(sgmii_port), 0); 880 881 /* 10) Configure the desire REFCLK_SEL (bit [10]) in register */ 882 reg_write(SGMII_REF_CLK_SEL_REG(sgmii_port), 0x400); 883 DEBUG_WR_REG(SGMII_REF_CLK_SEL_REG(sgmii_port), 0x400); 884 885 /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */ 886 tmp = reg_read(SGMII_SERDES_CFG_REG(sgmii_port)); 887 DEBUG_RD_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp); 888 tmp |= 7; 889 reg_write(SGMII_SERDES_CFG_REG(sgmii_port), tmp); 890 DEBUG_WR_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp); 891 892 } /* for each serdes lane */ 893 894 /* Step 12 [PEX-Only] Last phase of PEX-PIPE Configuration */ 895 DEBUG_INIT_FULL_S("Steps 12: [PEX-Only] Last phase of PEX-PIPE Configuration\n"); 896 for (line_num = 0; line_num < max_serdes_lines; line_num++) { 897 /* for each serdes lane */ 898 899 line_cfg = get_line_cfg(line_num, info); 900 901 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) 902 continue; 903 904 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) { 905 pex_unit = line_num >> 2; 906 pex_line_num = line_num % 4; 907 if (0 == pex_line_num) { 908 /* 909 * Configure the detection pulse with before 910 * the reset is deasserted 911 */ 912 913 /* Read the old value (indirect access) */ 914 reg_write(PEX_PHY_ACCESS_REG(pex_unit), 915 (0x48 << 16) | (1 << 31) | 916 (pex_line_num << 24)); 917 tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit)); 918 tmp &= ~(1 << 31); /* Clear read */ 919 tmp &= ~(3 << 6); /* Mask width */ 920 /* Insert new detection pulse width */ 921 tmp |= serdes_pex_pulse_width[pex_unit] << 6; 922 /* Write value back */ 923 reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp); 924 925 reg_write(PEX_PHY_ACCESS_REG(pex_unit), 926 (0xC1 << 16) | 0x24); 927 DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), 928 (0xC1 << 16) | 0x24); 929 } 930 } 931 } 932 933 /*--------------------------------------------------------------*/ 934 /* Step 13: Wait 15ms before checking results */ 935 DEBUG_INIT_FULL_S("Steps 13: Wait 15ms before checking results"); 936 mdelay(15); 937 tmp = 20; 938 while (tmp) { 939 status = MV_OK; 940 for (line_num = 0; line_num < max_serdes_lines; line_num++) { 941 u32 tmp; 942 line_cfg = get_line_cfg(line_num, info); 943 if (line_cfg == 944 serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) 945 continue; 946 947 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) 948 continue; 949 950 if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) { 951 /* 952 * Port 0 for serdes lines 4,6, and port 1 953 * for serdes lines 5 954 */ 955 sata_port = line_num & 1; 956 957 tmp = 958 reg_read(SATA_LP_PHY_EXT_STAT_REG 959 (sata_port)); 960 DEBUG_RD_REG(SATA_LP_PHY_EXT_STAT_REG 961 (sata_port), tmp); 962 if ((tmp & 0x7) != 0x7) 963 status = MV_ERROR; 964 continue; 965 } 966 967 if (line_cfg == 968 serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { 969 tmp = reg_read(SGMII_SERDES_STAT_REG(0)); 970 DEBUG_RD_REG(SGMII_SERDES_STAT_REG(0), tmp); 971 if ((tmp & 0x7) != 0x7) 972 status = MV_ERROR; 973 continue; 974 } 975 976 if (line_cfg == 977 serdes_cfg[line_num][SERDES_UNIT_SGMII0]) 978 sgmii_port = 0; 979 else if (line_cfg == 980 serdes_cfg[line_num][SERDES_UNIT_SGMII1]) 981 sgmii_port = 1; 982 else if (line_cfg == 983 serdes_cfg[line_num][SERDES_UNIT_SGMII2]) 984 sgmii_port = 2; 985 else if (line_cfg == 986 serdes_cfg[line_num][SERDES_UNIT_SGMII3]) 987 sgmii_port = 3; 988 else 989 continue; 990 991 tmp = reg_read(SGMII_SERDES_STAT_REG(sgmii_port)); 992 DEBUG_RD_REG(SGMII_SERDES_STAT_REG(sgmii_port), tmp); 993 if ((tmp & 0x7) != 0x7) 994 status = MV_ERROR; 995 } 996 997 if (status == MV_OK) 998 break; 999 mdelay(5); 1000 tmp--; 1001 } 1002 1003 /* 1004 * Step14 [PEX-Only] In order to configure RC/EP mode please write 1005 * to register 0x0060 bits 1006 */ 1007 DEBUG_INIT_FULL_S("Steps 14: [PEX-Only] In order to configure\n"); 1008 for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) { 1009 if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) 1010 continue; 1011 tmp = 1012 reg_read(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit))); 1013 DEBUG_RD_REG(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)), 1014 tmp); 1015 tmp &= ~(0xf << 20); 1016 if (info->pex_type == MV_PEX_ROOT_COMPLEX) 1017 tmp |= (0x4 << 20); 1018 else 1019 tmp |= (0x1 << 20); 1020 reg_write(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)), 1021 tmp); 1022 DEBUG_WR_REG(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)), 1023 tmp); 1024 } 1025 1026 /* 1027 * Step 15 [PEX-Only] Only for EP mode set to Zero bits 19 and 16 of 1028 * register 0x1a60 1029 */ 1030 DEBUG_INIT_FULL_S("Steps 15: [PEX-Only] In order to configure\n"); 1031 for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) { 1032 if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) 1033 continue; 1034 if (info->pex_type == MV_PEX_END_POINT) { 1035 tmp = 1036 reg_read(PEX_DBG_CTRL_REG 1037 (MV_PEX_UNIT_TO_IF(pex_unit))); 1038 DEBUG_RD_REG(PEX_DBG_CTRL_REG 1039 (MV_PEX_UNIT_TO_IF(pex_unit)), tmp); 1040 tmp &= 0xfff6ffff; 1041 reg_write(PEX_DBG_CTRL_REG(MV_PEX_UNIT_TO_IF(pex_unit)), 1042 tmp); 1043 DEBUG_WR_REG(PEX_DBG_CTRL_REG 1044 (MV_PEX_UNIT_TO_IF(pex_unit)), tmp); 1045 } 1046 } 1047 1048 if (info->serdes_m_phy_change) { 1049 MV_SERDES_CHANGE_M_PHY *serdes_m_phy_change; 1050 u32 bus_speed; 1051 for (line_num = 0; line_num < max_serdes_lines; line_num++) { 1052 line_cfg = get_line_cfg(line_num, info); 1053 if (line_cfg == 1054 serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) 1055 continue; 1056 serdes_m_phy_change = info->serdes_m_phy_change; 1057 bus_speed = info->bus_speed & (1 << line_num); 1058 while (serdes_m_phy_change->type != 1059 SERDES_UNIT_UNCONNECTED) { 1060 switch (serdes_m_phy_change->type) { 1061 case SERDES_UNIT_PEX: 1062 if (line_cfg != SERDES_UNIT_PEX) 1063 break; 1064 pex_unit = line_num >> 2; 1065 pex_line_num = line_num % 4; 1066 if (info->pex_mode[pex_unit] == 1067 PEX_BUS_DISABLED) 1068 break; 1069 if ((info->pex_mode[pex_unit] == 1070 PEX_BUS_MODE_X4) && pex_line_num) 1071 break; 1072 1073 if (bus_speed) { 1074 reg_write(PEX_PHY_ACCESS_REG 1075 (pex_unit), 1076 (pex_line_num << 24) | 1077 serdes_m_phy_change->val_hi_speed); 1078 DEBUG_WR_REG(PEX_PHY_ACCESS_REG 1079 (pex_unit), 1080 (pex_line_num << 1081 24) | 1082 serdes_m_phy_change->val_hi_speed); 1083 } else { 1084 reg_write(PEX_PHY_ACCESS_REG 1085 (pex_unit), 1086 (pex_line_num << 24) | 1087 serdes_m_phy_change->val_low_speed); 1088 DEBUG_WR_REG(PEX_PHY_ACCESS_REG 1089 (pex_unit), 1090 (pex_line_num << 1091 24) | 1092 serdes_m_phy_change->val_low_speed); 1093 } 1094 break; 1095 case SERDES_UNIT_SATA: 1096 if (line_cfg != SERDES_UNIT_SATA) 1097 break; 1098 /* 1099 * Port 0 for serdes lines 4,6, and 1100 * port 1 for serdes lines 5 1101 */ 1102 sata_port = line_num & 1; 1103 if (bus_speed) { 1104 reg_write(SATA_BASE_REG 1105 (sata_port) | 1106 serdes_m_phy_change->reg_hi_speed, 1107 serdes_m_phy_change->val_hi_speed); 1108 DEBUG_WR_REG(SATA_BASE_REG 1109 (sata_port) | 1110 serdes_m_phy_change->reg_hi_speed, 1111 serdes_m_phy_change->val_hi_speed); 1112 } else { 1113 reg_write(SATA_BASE_REG 1114 (sata_port) | 1115 serdes_m_phy_change->reg_low_speed, 1116 serdes_m_phy_change->val_low_speed); 1117 DEBUG_WR_REG(SATA_BASE_REG 1118 (sata_port) | 1119 serdes_m_phy_change->reg_low_speed, 1120 serdes_m_phy_change->val_low_speed); 1121 } 1122 break; 1123 case SERDES_UNIT_SGMII0: 1124 case SERDES_UNIT_SGMII1: 1125 case SERDES_UNIT_SGMII2: 1126 case SERDES_UNIT_SGMII3: 1127 if (line_cfg == serdes_cfg[line_num] 1128 [SERDES_UNIT_SGMII0]) 1129 sgmii_port = 0; 1130 else if (line_cfg == 1131 serdes_cfg[line_num] 1132 [SERDES_UNIT_SGMII1]) 1133 sgmii_port = 1; 1134 else if (line_cfg == 1135 serdes_cfg[line_num] 1136 [SERDES_UNIT_SGMII2]) 1137 sgmii_port = 2; 1138 else if (line_cfg == 1139 serdes_cfg[line_num] 1140 [SERDES_UNIT_SGMII3]) 1141 sgmii_port = 3; 1142 else 1143 break; 1144 if (bus_speed) { 1145 reg_write(MV_ETH_REGS_BASE 1146 (sgmii_port) | 1147 serdes_m_phy_change->reg_hi_speed, 1148 serdes_m_phy_change->val_hi_speed); 1149 DEBUG_WR_REG(MV_ETH_REGS_BASE 1150 (sgmii_port) | 1151 serdes_m_phy_change->reg_hi_speed, 1152 serdes_m_phy_change->val_hi_speed); 1153 } else { 1154 reg_write(MV_ETH_REGS_BASE 1155 (sgmii_port) | 1156 serdes_m_phy_change->reg_low_speed, 1157 serdes_m_phy_change->val_low_speed); 1158 DEBUG_WR_REG(MV_ETH_REGS_BASE 1159 (sgmii_port) | 1160 serdes_m_phy_change->reg_low_speed, 1161 serdes_m_phy_change->val_low_speed); 1162 } 1163 break; 1164 case SERDES_UNIT_QSGMII: 1165 if (line_cfg != SERDES_UNIT_QSGMII) 1166 break; 1167 if (bus_speed) { 1168 reg_write 1169 (serdes_m_phy_change->reg_hi_speed, 1170 serdes_m_phy_change->val_hi_speed); 1171 DEBUG_WR_REG 1172 (serdes_m_phy_change->reg_hi_speed, 1173 serdes_m_phy_change->val_hi_speed); 1174 } else { 1175 reg_write 1176 (serdes_m_phy_change->reg_low_speed, 1177 serdes_m_phy_change->val_low_speed); 1178 DEBUG_WR_REG 1179 (serdes_m_phy_change->reg_low_speed, 1180 serdes_m_phy_change->val_low_speed); 1181 } 1182 break; 1183 default: 1184 break; 1185 } 1186 serdes_m_phy_change++; 1187 } 1188 } 1189 } 1190 1191 /* Step 16 [PEX-Only] Training Enable */ 1192 DEBUG_INIT_FULL_S("Steps 16: [PEX-Only] Training Enable"); 1193 tmp = reg_read(SOC_CTRL_REG); 1194 DEBUG_RD_REG(SOC_CTRL_REG, tmp); 1195 tmp &= ~(0x0F); 1196 for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) { 1197 reg_write(PEX_CAUSE_REG(pex_unit), 0); 1198 DEBUG_WR_REG(PEX_CAUSE_REG(pex_unit), 0); 1199 if (info->pex_mode[pex_unit] != PEX_BUS_DISABLED) 1200 tmp |= (0x1 << pex_unit); 1201 } 1202 reg_write(SOC_CTRL_REG, tmp); 1203 DEBUG_WR_REG(SOC_CTRL_REG, tmp); 1204 1205 /* Step 17: Speed change to target speed and width */ 1206 { 1207 u32 tmp_reg, tmp_pex_reg; 1208 u32 addr; 1209 u32 first_busno, next_busno; 1210 u32 max_link_width = 0; 1211 u32 neg_link_width = 0; 1212 pex_if_num = pex_max_if_get(); 1213 mdelay(150); 1214 DEBUG_INIT_FULL_C("step 17: max_if= 0x", pex_if_num, 1); 1215 next_busno = 0; 1216 for (pex_if = 0; pex_if < pex_if_num; pex_if++) { 1217 line_num = (pex_if <= 8) ? pex_if : 12; 1218 line_cfg = get_line_cfg(line_num, info); 1219 if (line_cfg != serdes_cfg[line_num][SERDES_UNIT_PEX]) 1220 continue; 1221 pex_unit = (pex_if < 9) ? (pex_if >> 2) : 3; 1222 DEBUG_INIT_FULL_S("step 17: PEX"); 1223 DEBUG_INIT_FULL_D(pex_if, 1); 1224 DEBUG_INIT_FULL_C(" pex_unit= ", pex_unit, 1); 1225 1226 if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) { 1227 DEBUG_INIT_FULL_C("PEX disabled interface ", 1228 pex_if, 1); 1229 if (pex_if < 8) 1230 pex_if += 3; 1231 continue; 1232 } 1233 first_busno = next_busno; 1234 if ((info->pex_type == MV_PEX_END_POINT) && 1235 (0 == pex_if)) { 1236 if ((pex_if < 8) && (info->pex_mode[pex_unit] == 1237 PEX_BUS_MODE_X4)) 1238 pex_if += 3; 1239 continue; 1240 } 1241 1242 tmp = reg_read(PEX_DBG_STATUS_REG(pex_if)); 1243 DEBUG_RD_REG(PEX_DBG_STATUS_REG(pex_if), tmp); 1244 if ((tmp & 0x7f) == 0x7e) { 1245 next_busno++; 1246 tmp = reg_read(PEX_LINK_CAPABILITIES_REG(pex_if)); 1247 max_link_width = tmp; 1248 DEBUG_RD_REG((PEX_LINK_CAPABILITIES_REG 1249 (pex_if)), tmp); 1250 max_link_width = ((max_link_width >> 4) & 0x3F); 1251 neg_link_width = 1252 reg_read(PEX_LINK_CTRL_STATUS_REG(pex_if)); 1253 DEBUG_RD_REG((PEX_LINK_CTRL_STATUS_REG(pex_if)), 1254 neg_link_width); 1255 neg_link_width = ((neg_link_width >> 20) & 0x3F); 1256 if (max_link_width > neg_link_width) { 1257 tmp &= ~(0x3F << 4); 1258 tmp |= (neg_link_width << 4); 1259 reg_write(PEX_LINK_CAPABILITIES_REG 1260 (pex_if), tmp); 1261 DEBUG_WR_REG((PEX_LINK_CAPABILITIES_REG 1262 (pex_if)), tmp); 1263 mdelay(1); /* wait 1ms before reading capability for speed */ 1264 DEBUG_INIT_S("PEX"); 1265 DEBUG_INIT_D(pex_if, 1); 1266 DEBUG_INIT_C(": change width to X", 1267 neg_link_width, 1); 1268 } 1269 tmp_pex_reg = 1270 reg_read((PEX_CFG_DIRECT_ACCESS 1271 (pex_if, 1272 PEX_LINK_CAPABILITY_REG))); 1273 DEBUG_RD_REG((PEX_CFG_DIRECT_ACCESS 1274 (pex_if, 1275 PEX_LINK_CAPABILITY_REG)), 1276 tmp_pex_reg); 1277 tmp_pex_reg &= (0xF); 1278 if (tmp_pex_reg == 0x2) { 1279 tmp_reg = 1280 (reg_read 1281 (PEX_CFG_DIRECT_ACCESS 1282 (pex_if, 1283 PEX_LINK_CTRL_STAT_REG)) & 1284 0xF0000) >> 16; 1285 DEBUG_RD_REG(PEX_CFG_DIRECT_ACCESS 1286 (pex_if, 1287 PEX_LINK_CTRL_STAT_REG), 1288 tmp_pex_reg); 1289 /* check if the link established is GEN1 */ 1290 if (tmp_reg == 0x1) { 1291 pex_local_bus_num_set(pex_if, 1292 first_busno); 1293 pex_local_dev_num_set(pex_if, 1294 1); 1295 1296 DEBUG_INIT_FULL_S("** Link is Gen1, check the EP capability\n"); 1297 /* link is Gen1, check the EP capability */ 1298 addr = 1299 pex_cfg_read(pex_if, 1300 first_busno, 0, 1301 0, 1302 0x34) & 0xFF; 1303 DEBUG_INIT_FULL_C("pex_cfg_read: return addr=0x%x", 1304 addr, 4); 1305 if (addr == 0xff) { 1306 DEBUG_INIT_FULL_C("pex_cfg_read: return 0xff -->PEX (%d): Detected No Link.", 1307 pex_if, 1); 1308 continue; 1309 } 1310 while ((pex_cfg_read 1311 (pex_if, first_busno, 0, 1312 0, 1313 addr) & 0xFF) != 1314 0x10) { 1315 addr = 1316 (pex_cfg_read 1317 (pex_if, 1318 first_busno, 0, 0, 1319 addr) & 0xFF00) >> 1320 8; 1321 } 1322 if ((pex_cfg_read 1323 (pex_if, first_busno, 0, 0, 1324 addr + 0xC) & 0xF) >= 1325 0x2) { 1326 tmp = 1327 reg_read 1328 (PEX_LINK_CTRL_STATUS2_REG 1329 (pex_if)); 1330 DEBUG_RD_REG 1331 (PEX_LINK_CTRL_STATUS2_REG 1332 (pex_if), tmp); 1333 tmp &= ~(0x1 | 1 << 1); 1334 tmp |= (1 << 1); 1335 reg_write 1336 (PEX_LINK_CTRL_STATUS2_REG 1337 (pex_if), tmp); 1338 DEBUG_WR_REG 1339 (PEX_LINK_CTRL_STATUS2_REG 1340 (pex_if), tmp); 1341 1342 tmp = 1343 reg_read 1344 (PEX_CTRL_REG 1345 (pex_if)); 1346 DEBUG_RD_REG 1347 (PEX_CTRL_REG 1348 (pex_if), tmp); 1349 tmp |= (1 << 10); 1350 reg_write(PEX_CTRL_REG 1351 (pex_if), 1352 tmp); 1353 DEBUG_WR_REG 1354 (PEX_CTRL_REG 1355 (pex_if), tmp); 1356 mdelay(10); /* We need to wait 10ms before reading the PEX_DBG_STATUS_REG in order not to read the status of the former state */ 1357 DEBUG_INIT_FULL_S 1358 ("Gen2 client!\n"); 1359 } else { 1360 DEBUG_INIT_FULL_S 1361 ("GEN1 client!\n"); 1362 } 1363 } 1364 } 1365 } else { 1366 DEBUG_INIT_FULL_S("PEX"); 1367 DEBUG_INIT_FULL_D(pex_if, 1); 1368 DEBUG_INIT_FULL_S(" : Detected No Link. Status Reg(0x"); 1369 DEBUG_INIT_FULL_D(PEX_DBG_STATUS_REG(pex_if), 1370 8); 1371 DEBUG_INIT_FULL_C(") = 0x", tmp, 8); 1372 } 1373 1374 if ((pex_if < 8) && 1375 (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)) 1376 pex_if += 3; 1377 } 1378 } 1379 1380 /* Step 18: update pex DEVICE ID */ 1381 { 1382 u32 devId; 1383 pex_if_num = pex_max_if_get(); 1384 ctrl_mode = ctrl_model_get(); 1385 for (pex_if = 0; pex_if < pex_if_num; pex_if++) { 1386 pex_unit = (pex_if < 9) ? (pex_if >> 2) : 3; 1387 if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) { 1388 if ((pex_if < 8) && 1389 (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)) 1390 pex_if += 3; 1391 continue; 1392 } 1393 1394 devId = reg_read(PEX_CFG_DIRECT_ACCESS( 1395 pex_if, PEX_DEVICE_AND_VENDOR_ID)); 1396 devId &= 0xFFFF; 1397 devId |= ((ctrl_mode << 16) & 0xffff0000); 1398 DEBUG_INIT_FULL_S("Update Device ID PEX"); 1399 DEBUG_INIT_FULL_D(pex_if, 1); 1400 DEBUG_INIT_FULL_D(devId, 8); 1401 DEBUG_INIT_FULL_S("\n"); 1402 reg_write(PEX_CFG_DIRECT_ACCESS 1403 (pex_if, PEX_DEVICE_AND_VENDOR_ID), devId); 1404 if ((pex_if < 8) && 1405 (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)) 1406 pex_if += 3; 1407 } 1408 DEBUG_INIT_FULL_S("Update PEX Device ID 0x"); 1409 DEBUG_INIT_FULL_D(ctrl_mode, 4); 1410 DEBUG_INIT_FULL_S("0\n"); 1411 } 1412 tmp = reg_read(PEX_DBG_STATUS_REG(0)); 1413 DEBUG_RD_REG(PEX_DBG_STATUS_REG(0), tmp); 1414 1415 DEBUG_INIT_S(ENDED_OK); 1416 return MV_OK; 1417 } 1418 1419 /* PEX configuration space read write */ 1420 1421 /* 1422 * pex_cfg_read - Read from configuration space 1423 * 1424 * DESCRIPTION: 1425 * This function performs a 32 bit read from PEX configuration space. 1426 * It supports both type 0 and type 1 of Configuration Transactions 1427 * (local and over bridge). In order to read from local bus segment, use 1428 * bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers 1429 * will result configuration transaction of type 1 (over bridge). 1430 * 1431 * INPUT: 1432 * pex_if - PEX interface number. 1433 * bus - PEX segment bus number. 1434 * dev - PEX device number. 1435 * func - Function number. 1436 * offss - Register offset. 1437 * 1438 * OUTPUT: 1439 * None. 1440 * 1441 * RETURN: 1442 * 32bit register data, 0xffffffff on error 1443 * 1444 */ 1445 u32 pex_cfg_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 offs) 1446 { 1447 u32 pex_data = 0; 1448 u32 local_dev, local_bus; 1449 u32 val; 1450 1451 if (pex_if >= MV_PEX_MAX_IF) 1452 return 0xFFFFFFFF; 1453 1454 if (dev >= MAX_PEX_DEVICES) { 1455 DEBUG_INIT_C("pex_cfg_read: ERR. device number illigal ", dev, 1456 1); 1457 return 0xFFFFFFFF; 1458 } 1459 1460 if (func >= MAX_PEX_FUNCS) { 1461 DEBUG_INIT_C("pex_cfg_read: ERR. function num illigal ", func, 1462 1); 1463 return 0xFFFFFFFF; 1464 } 1465 1466 if (bus >= MAX_PEX_BUSSES) { 1467 DEBUG_INIT_C("pex_cfg_read: ERR. bus number illigal ", bus, 1); 1468 return MV_ERROR; 1469 } 1470 val = reg_read(PEX_STATUS_REG(pex_if)); 1471 1472 local_dev = 1473 ((val & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS); 1474 local_bus = 1475 ((val & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS); 1476 1477 /* Speed up the process. In case on no link, return MV_ERROR */ 1478 if ((dev != local_dev) || (bus != local_bus)) { 1479 pex_data = reg_read(PEX_STATUS_REG(pex_if)); 1480 1481 if ((pex_data & PXSR_DL_DOWN)) 1482 return MV_ERROR; 1483 } 1484 1485 /* 1486 * In PCI Express we have only one device number 1487 * and this number is the first number we encounter else that the 1488 * local_dev spec pex define return on config read/write on any device 1489 */ 1490 if (bus == local_bus) { 1491 if (local_dev == 0) { 1492 /* 1493 * If local dev is 0 then the first number we encounter 1494 * after 0 is 1 1495 */ 1496 if ((dev != 1) && (dev != local_dev)) 1497 return MV_ERROR; 1498 } else { 1499 /* 1500 * If local dev is not 0 then the first number we 1501 * encounter is 0 1502 */ 1503 if ((dev != 0) && (dev != local_dev)) 1504 return MV_ERROR; 1505 } 1506 } 1507 1508 /* Creating PEX address to be passed */ 1509 pex_data = (bus << PXCAR_BUS_NUM_OFFS); 1510 pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS); 1511 pex_data |= (func << PXCAR_FUNC_NUM_OFFS); 1512 pex_data |= (offs & PXCAR_REG_NUM_MASK); /* lgacy register space */ 1513 /* extended register space */ 1514 pex_data |= (((offs & PXCAR_REAL_EXT_REG_NUM_MASK) >> 1515 PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS); 1516 1517 pex_data |= PXCAR_CONFIG_EN; 1518 1519 /* Write the address to the PEX configuration address register */ 1520 reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data); 1521 1522 /* 1523 * In order to let the PEX controller absorbed the address of the read 1524 * transaction we perform a validity check that the address was written 1525 */ 1526 if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if))) 1527 return MV_ERROR; 1528 1529 /* cleaning Master Abort */ 1530 reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND), 1531 PXSAC_MABORT); 1532 /* Read the Data returned in the PEX Data register */ 1533 pex_data = reg_read(PEX_CFG_DATA_REG(pex_if)); 1534 1535 DEBUG_INIT_FULL_C(" --> ", pex_data, 4); 1536 1537 return pex_data; 1538 } 1539 1540 /* 1541 * pex_local_bus_num_set - Set PEX interface local bus number. 1542 * 1543 * DESCRIPTION: 1544 * This function sets given PEX interface its local bus number. 1545 * Note: In case the PEX interface is PEX-X, the information is read-only. 1546 * 1547 * INPUT: 1548 * pex_if - PEX interface number. 1549 * bus_num - Bus number. 1550 * 1551 * OUTPUT: 1552 * None. 1553 * 1554 * RETURN: 1555 * MV_NOT_ALLOWED in case PEX interface is PEX-X. 1556 * MV_BAD_PARAM on bad parameters , 1557 * otherwise MV_OK 1558 * 1559 */ 1560 int pex_local_bus_num_set(u32 pex_if, u32 bus_num) 1561 { 1562 u32 val; 1563 1564 if (bus_num >= MAX_PEX_BUSSES) { 1565 DEBUG_INIT_C("pex_local_bus_num_set: ERR. bus number illigal %d\n", 1566 bus_num, 4); 1567 return MV_ERROR; 1568 } 1569 1570 val = reg_read(PEX_STATUS_REG(pex_if)); 1571 val &= ~PXSR_PEX_BUS_NUM_MASK; 1572 val |= (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK; 1573 reg_write(PEX_STATUS_REG(pex_if), val); 1574 1575 return MV_OK; 1576 } 1577 1578 /* 1579 * pex_local_dev_num_set - Set PEX interface local device number. 1580 * 1581 * DESCRIPTION: 1582 * This function sets given PEX interface its local device number. 1583 * Note: In case the PEX interface is PEX-X, the information is read-only. 1584 * 1585 * INPUT: 1586 * pex_if - PEX interface number. 1587 * dev_num - Device number. 1588 * 1589 * OUTPUT: 1590 * None. 1591 * 1592 * RETURN: 1593 * MV_NOT_ALLOWED in case PEX interface is PEX-X. 1594 * MV_BAD_PARAM on bad parameters , 1595 * otherwise MV_OK 1596 * 1597 */ 1598 int pex_local_dev_num_set(u32 pex_if, u32 dev_num) 1599 { 1600 u32 val; 1601 1602 if (pex_if >= MV_PEX_MAX_IF) 1603 return MV_BAD_PARAM; 1604 1605 val = reg_read(PEX_STATUS_REG(pex_if)); 1606 val &= ~PXSR_PEX_DEV_NUM_MASK; 1607 val |= (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK; 1608 reg_write(PEX_STATUS_REG(pex_if), val); 1609 1610 return MV_OK; 1611 } 1612