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