falcon.c (60265B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 10 #include <phymod/phymod.h> 11 #include <phymod/phymod_system.h> 12 #include <phymod/phymod_util.h> 13 #include <phymod/phymod_dispatch.h> 14 #include <phymod/chip/bcmi_falcon_xgxs_defs.h> 15 #include <phymod/chip/falcon.h> 16 #include "../../falcon/tier1/falcon_cfg_seq.h" 17 #include "../../falcon/tier1/falcon_tsc_enum.h" 18 #include "../../falcon/tier1/falcon_tsc_common.h" 19 #include "../../falcon/tier1/falcon_tsc_interface.h" 20 #include "../../falcon/tier1/falcon_tsc_dependencies.h" 21 #include "../../falcon/tier1/falcon_tsc_debug_functions.h" 22 23 #define FALCON_ID0 0 24 #define FALCON_ID1 0 25 #define FALCON_MODEL 0x1b 26 #define FALCON_REV_MASK 0x0 27 #define TSCF_PHY_ALL_LANES 0xf 28 #define FALCON_PMD_CRC_UCODE 1 29 30 #define TSCF_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \ 31 do{\ 32 PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\ 33 (_phy_access)->type = (_core_access)->type; \ 34 (_phy_access)->port_loc = (_core_access)->port_loc; \ 35 (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \ 36 (_phy_access)->access.lane_mask = TSCF_PHY_ALL_LANES; \ 37 }while(0) 38 39 #define TSCF_NOF_DFES 9 40 #define TSCF_NOF_LANES_IN_CORE 4 41 extern unsigned char tscf_ucode[]; 42 extern unsigned short tscf_ucode_len; 43 extern unsigned short tscf_ucode_crc; 44 45 46 int falcon_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 47 { 48 const phymod_access_t *pm_acc = &core->access; 49 falcon_rev_id0_t rev_id0; 50 falcon_rev_id1_t rev_id1; 51 *is_identified = 0; 52 53 /* PHY IDs match - now check model */ 54 PHYMOD_IF_ERR_RETURN(falcon_tsc_identify(pm_acc, &rev_id0, &rev_id1)); 55 if (rev_id0.revid_model == FALCON_MODEL) { 56 *is_identified = 1; 57 } 58 59 return PHYMOD_E_NONE; 60 } 61 62 63 int falcon_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info) 64 { 65 66 info->core_version = phymodCoreVersionFalconA0; 67 info->serdes_id = 0; 68 info->phy_id0 = 0; 69 info->phy_id1 = 0; 70 71 return PHYMOD_E_NONE; 72 73 } 74 75 76 int falcon_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 77 { 78 79 80 /* Not supported */ 81 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_pll_sequencer_restart)\n")); 82 83 84 return PHYMOD_E_NONE; 85 86 } 87 88 int falcon_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map) 89 { 90 int lane; 91 uint32_t pmd_swap = 0; 92 PHYMOD_IF_ERR_RETURN(falcon_pmd_lane_swap_tx_get(&core->access, &pmd_swap)); 93 for( lane = 0 ; lane < TSCF_NOF_LANES_IN_CORE ; lane++){ 94 /*deccode each lane from four bits*/ 95 /*considering the pcs lane swap: tx_map[lane] = pmd_map[pcs_map[lane]]*/ 96 /* lane_map->lane_map_tx[lane] = (pmd_swap>>(lane_map->lane_map_rx[lane]*4)) & TSCF_LANE_SWAP_LANE_MASK; */ 97 lane_map->lane_map_tx[lane] = (pmd_swap>>(lane*4)) & 0x3; 98 /*rx lane map is not supported*/ 99 lane_map->lane_map_rx[lane] = lane; 100 } 101 lane_map->num_of_lanes = TSCF_NOF_LANES_IN_CORE; 102 return PHYMOD_E_NONE; 103 104 105 return PHYMOD_E_NONE; 106 107 } 108 109 110 int falcon_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 111 { 112 113 114 /* Not supported */ 115 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_reset_set)\n")); 116 117 118 return PHYMOD_E_NONE; 119 120 } 121 122 int falcon_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 123 { 124 125 126 /* Not supported */ 127 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_reset_get) \n")); 128 129 130 return PHYMOD_E_NONE; 131 132 } 133 134 135 int falcon_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 136 { 137 138 139 /* Not supported */ 140 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_firmware_info_get) \n")); 141 142 143 return PHYMOD_E_NONE; 144 145 } 146 147 int falcon_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 148 { 149 150 151 switch (tx_control) 152 { 153 case phymodTxElectricalIdleEnable: 154 PHYMOD_IF_ERR_RETURN(falcon_electrical_idle_set(&phy->access, 1)); 155 break; 156 case phymodTxElectricalIdleDisable: 157 PHYMOD_IF_ERR_RETURN(falcon_electrical_idle_set(&phy->access, 0)); 158 break; 159 case phymodTxSquelchOn: 160 PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_disable(&phy->access, 1)); 161 break; 162 case phymodTxSquelchOff: 163 PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_disable(&phy->access, 0)); 164 break; 165 default: 166 PHYMOD_DEBUG_ERROR(("This control is NOT SUPPORTED!! (falcon_phy_tx_lane_control_set) \n")); 167 break; 168 } 169 170 return PHYMOD_E_NONE; 171 } 172 173 174 int falcon_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t *tx_control) 175 { 176 uint8_t disable; 177 178 PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_disable_get(&phy->access, &disable)); 179 if(disable) { 180 *tx_control = phymodTxSquelchOn; 181 } else { 182 *tx_control = phymodTxSquelchOff; 183 } 184 185 return PHYMOD_E_NONE; 186 } 187 188 /*Rx control*/ 189 int falcon_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 190 { 191 phymod_phy_access_t pm_phy_copy; 192 int start_lane, num_lane, i; 193 194 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 195 /* next program the tx fir taps and driver current based on the input */ 196 PHYMOD_IF_ERR_RETURN 197 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 198 199 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 200 201 switch (rx_control) { 202 case phymodRxSquelchOn: 203 for (i = 0; i < num_lane; i++) { 204 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 205 continue; 206 } 207 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 208 PHYMOD_IF_ERR_RETURN(falcon_rx_squelch_set(&pm_phy_copy.access, 1)); 209 } 210 break; 211 case phymodRxSquelchOff: 212 for (i = 0; i < num_lane; i++) { 213 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 214 continue; 215 } 216 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 217 PHYMOD_IF_ERR_RETURN(falcon_rx_squelch_set(&pm_phy_copy.access, 0)); 218 } 219 break; 220 default: 221 /* Not supported */ 222 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_rx_lane_control_set) \n")); 223 break; 224 } 225 return PHYMOD_E_NONE; 226 } 227 228 229 int falcon_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 230 { 231 uint32_t enable, lb_enable; 232 phymod_phy_access_t pm_phy_copy; 233 int start_lane, num_lane; 234 235 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 236 /* next program the tx fir taps and driver current based on the input */ 237 PHYMOD_IF_ERR_RETURN 238 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 239 240 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 241 242 PHYMOD_IF_ERR_RETURN(falcon_rx_squelch_get(&pm_phy_copy.access, &enable)); 243 /* next check if PMD loopback is on */ 244 if (enable) { 245 PHYMOD_IF_ERR_RETURN(falcon_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 246 if (lb_enable) enable = 0; 247 } 248 if(enable) { 249 *rx_control = phymodRxSquelchOn; 250 } else { 251 *rx_control = phymodRxSquelchOff; 252 } 253 return PHYMOD_E_NONE; 254 } 255 256 int falcon_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability_set_type) 257 { 258 259 260 /* Not supported */ 261 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_rx_lane_control_get) \n")); 262 263 264 return PHYMOD_E_NONE; 265 266 } 267 268 int falcon_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 269 { 270 271 272 /* Not supported */ 273 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_autoneg_ability_get) \n")); 274 275 276 return PHYMOD_E_NONE; 277 278 } 279 280 int falcon_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 281 { 282 283 284 /* Not supported */ 285 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_autoneg_set) \n")); 286 287 288 return PHYMOD_E_NONE; 289 290 } 291 292 int falcon_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 293 { 294 295 296 /* Not supported */ 297 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_autoneg_get) \n")); 298 299 300 return PHYMOD_E_NONE; 301 302 } 303 304 int falcon_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 305 { 306 307 308 /* Not supported */ 309 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_autoneg_status_get) \n")); 310 311 312 return PHYMOD_E_NONE; 313 314 } 315 316 /* load tscf fw. the fw_loader parameter is valid just for external fw load*/ 317 STATIC 318 int _falcon_core_firmware_load(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config) 319 { 320 int wait; 321 322 switch(init_config->firmware_load_method){ 323 case phymodFirmwareLoadMethodInternal: 324 PHYMOD_IF_ERR_RETURN(falcon_tsc_ucode_mdio_load(&core->access, tscf_ucode, tscf_ucode_len)); 325 break; 326 case phymodFirmwareLoadMethodExternal: 327 if(!PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 328 PHYMOD_NULL_CHECK(init_config->firmware_loader); 329 PHYMOD_IF_ERR_RETURN(falcon_tsc_ucode_init(&core->access)); 330 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 331 wait = 0; 332 } else { 333 wait = 1; 334 } 335 PHYMOD_IF_ERR_RETURN(falcon_pram_firmware_enable(&core->access, 1, wait)); 336 337 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 338 return PHYMOD_E_NONE; 339 } 340 341 PHYMOD_IF_ERR_RETURN(init_config->firmware_loader(core, tscf_ucode_len, tscf_ucode)); 342 } 343 PHYMOD_IF_ERR_RETURN(falcon_pram_firmware_enable(&core->access, 0, 0)); 344 break; 345 case phymodFirmwareLoadMethodNone: 346 break; 347 default: 348 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), init_config->firmware_load_method)); 349 } 350 if(init_config->firmware_load_method != phymodFirmwareLoadMethodNone){ 351 /*PHYMOD_IF_ERR_RETURN(tscf_core_firmware_info_get(core, &actual_fw)); 352 if((tscf_ucode_crc != actual_fw.fw_crc) || (tscf_ucode_ver != actual_fw.fw_version)){ 353 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("fw load validation was failed"))); 354 } */ 355 } 356 return PHYMOD_E_NONE; 357 } 358 359 int falcon_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_config) 360 { 361 struct falcon_tsc_uc_core_config_st serdes_firmware_core_config; 362 uint32_t is_write_disabled; 363 364 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy->access, &is_write_disabled)); 365 if(is_write_disabled) { 366 return PHYMOD_E_NONE; 367 } 368 369 370 PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config)); 371 serdes_firmware_core_config.field.core_cfg_from_pcs = fw_config.CoreConfigFromPCS; 372 serdes_firmware_core_config.field.vco_rate = fw_config.VcoRate; 373 serdes_firmware_core_config.field.disable_write_pll_iqp = fw_config.disable_write_pll_iqp; 374 PHYMOD_IF_ERR_RETURN(falcon_tsc_set_uc_core_config(&phy->access, serdes_firmware_core_config)); 375 return PHYMOD_E_NONE; 376 } 377 378 379 int falcon_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_config) 380 { 381 struct falcon_tsc_uc_core_config_st serdes_firmware_core_config; 382 PHYMOD_IF_ERR_RETURN(falcon_tsc_get_uc_core_config(&phy->access, &serdes_firmware_core_config)); 383 PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config)); 384 fw_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs; 385 fw_config->VcoRate = serdes_firmware_core_config.field.vco_rate; 386 fw_config->disable_write_pll_iqp = serdes_firmware_core_config.field.disable_write_pll_iqp; 387 return PHYMOD_E_NONE; 388 } 389 390 391 int falcon_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config) 392 { 393 struct falcon_tsc_uc_lane_config_st serdes_firmware_config; 394 395 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 396 PHYMOD_IF_ERR_RETURN(falcon_tsc_get_uc_lane_cfg(&phy->access, &serdes_firmware_config)); 397 PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config)); 398 fw_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs; 399 fw_config->AnEnabled = serdes_firmware_config.field.an_enabled; 400 fw_config->DfeOn = serdes_firmware_config.field.dfe_on; 401 fw_config->LpDfeOn = serdes_firmware_config.field.dfe_lp_mode; 402 fw_config->ForceBrDfe = serdes_firmware_config.field.force_brdfe_on; 403 /* fw_config->Cl72Enable = serdes_firmware_config.field.cl72_emulation_en; */ 404 fw_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis; 405 fw_config->UnreliableLos = serdes_firmware_config.field.unreliable_los; 406 fw_config->MediaType = serdes_firmware_config.field.media_type; 407 fw_config->Cl72AutoPolEn = serdes_firmware_config.field.cl72_auto_polarity_en; 408 fw_config->Cl72RestTO = serdes_firmware_config.field.cl72_restart_timeout_en; 409 410 return PHYMOD_E_NONE; 411 } 412 413 int falcon_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 414 { 415 416 PHYMOD_IF_ERR_RETURN 417 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_PRE, (int8_t)tx->pre)); 418 PHYMOD_IF_ERR_RETURN 419 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_MAIN, (int8_t)tx->main)); 420 PHYMOD_IF_ERR_RETURN 421 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST1, (int8_t)tx->post)); 422 PHYMOD_IF_ERR_RETURN 423 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST2, (int8_t)tx->post2)); 424 PHYMOD_IF_ERR_RETURN 425 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST3, (int8_t)tx->post3)); 426 PHYMOD_IF_ERR_RETURN 427 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_AMP, (int8_t)tx->amp)); 428 if((tx->drivermode != -1) && 429 (phy->device_op_mode & PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE)) { 430 PHYMOD_IF_ERR_RETURN 431 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_DRIVERMODE, (int8_t)tx->drivermode)); 432 } 433 return PHYMOD_E_NONE; 434 } 435 436 int falcon_phy_media_type_tx_get(const phymod_phy_access_t* phy, phymod_media_typed_t media, phymod_tx_t* tx) 437 { 438 switch (media) { 439 case phymodMediaTypeChipToChip: 440 tx->pre = 0xc; 441 tx->main = 0x66; 442 tx->post = 0x0; 443 tx->post2 = 0x0; 444 tx->post3 = 0x0; 445 tx->amp = 0xc; 446 break; 447 case phymodMediaTypeShort: 448 tx->pre = 0xc; 449 tx->main = 0x66; 450 tx->post = 0x0; 451 tx->post2 = 0x0; 452 tx->post3 = 0x0; 453 tx->amp = 0xc; 454 break; 455 case phymodMediaTypeMid: 456 tx->pre = 0xc; 457 tx->main = 0x66; 458 tx->post = 0x0; 459 tx->post2 = 0x0; 460 tx->post3 = 0x0; 461 tx->amp = 0xc; 462 break; 463 case phymodMediaTypeLong: 464 tx->pre = 0xc; 465 tx->main = 0x66; 466 tx->post = 0x0; 467 tx->post2 = 0x0; 468 tx->post3 = 0x0; 469 tx->amp = 0xc; 470 break; 471 default: 472 tx->pre = 0xc; 473 tx->main = 0x66; 474 tx->post = 0x0; 475 tx->post2 = 0x0; 476 tx->post3 = 0x0; 477 tx->amp = 0xc; 478 break; 479 } 480 481 return PHYMOD_E_NONE; 482 483 484 } 485 486 /* 487 * set lane swapping for core 488 * The tx swap is composed of PCS swap and after that the PMD swap. 489 * The rx swap is composed just by PCS swap 490 */ 491 492 int falcon_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map) 493 { 494 phymod_phy_access_t phy_access; 495 uint32_t lane, pmd_tx_map =0; 496 497 for( lane = 0 ; lane < TSCF_NOF_LANES_IN_CORE ; lane++){ 498 pmd_tx_map |= ((lane_map->lane_map_tx[lane]) & 3) << (lane*4); 499 } 500 501 TSCF_CORE_TO_PHY_ACCESS(&phy_access, core); 502 PHYMOD_IF_ERR_RETURN 503 (falcon_pmd_lane_swap(&phy_access.access, pmd_tx_map)); 504 505 return PHYMOD_E_NONE; 506 } 507 508 509 510 STATIC 511 int _falcon_pll_multiplier_get(uint32_t pll_div, uint32_t *pll_multiplier) 512 { 513 switch (pll_div) { 514 case 0x0: 515 *pll_multiplier = 64; 516 break; 517 case 0x1: 518 *pll_multiplier = 66; 519 break; 520 case 0x2: 521 *pll_multiplier = 80; 522 break; 523 case 0x3: 524 *pll_multiplier = 128; 525 break; 526 case 0x4: 527 *pll_multiplier = 132; 528 break; 529 case 0x5: 530 *pll_multiplier = 140; 531 break; 532 case 0x6: 533 *pll_multiplier = 160; 534 break; 535 case 0x7: 536 *pll_multiplier = 165; 537 break; 538 case 0x8: 539 *pll_multiplier = 168; 540 break; 541 case 0x9: 542 *pll_multiplier = 170; 543 break; 544 case 0xa: 545 *pll_multiplier = 175; 546 break; 547 case 0xb: 548 *pll_multiplier = 180; 549 break; 550 case 0xc: 551 *pll_multiplier = 184; 552 break; 553 case 0xd: 554 *pll_multiplier = 200; 555 break; 556 case 0xe: 557 *pll_multiplier = 224; 558 break; 559 case 0xf: 560 *pll_multiplier = 264; 561 break; 562 default: 563 *pll_multiplier = 165; 564 break; 565 } 566 return PHYMOD_E_NONE; 567 } 568 569 570 STATIC 571 int _falcon_actual_osr_get(int osr_mode, int* actual_os) 572 { 573 switch(osr_mode) { 574 case 0: *actual_os = 1; break; 575 case 1: *actual_os = 2; break; 576 case 2: *actual_os = 4; break; 577 default: 578 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("unsupported OS mode %d"), osr_mode)); 579 } 580 return PHYMOD_E_NONE; 581 } 582 583 584 int _falcon_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 585 { 586 uint32_t is_warm_boot; 587 struct falcon_tsc_uc_lane_config_st serdes_firmware_config; 588 589 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 590 serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS; 591 serdes_firmware_config.field.an_enabled = fw_config.AnEnabled; 592 serdes_firmware_config.field.dfe_on = fw_config.DfeOn; 593 serdes_firmware_config.field.force_brdfe_on = fw_config.ForceBrDfe; 594 /* serdes_firmware_config.field.cl72_emulation_en = fw_config.Cl72Enable; */ 595 serdes_firmware_config.field.scrambling_dis = fw_config.ScramblingDisable; 596 serdes_firmware_config.field.unreliable_los = fw_config.UnreliableLos; 597 serdes_firmware_config.field.media_type = fw_config.MediaType; 598 serdes_firmware_config.field.dfe_lp_mode = fw_config.LpDfeOn; 599 serdes_firmware_config.field.cl72_auto_polarity_en = fw_config.Cl72AutoPolEn; 600 serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO; 601 602 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy->access, &is_warm_boot)); 603 604 if(!is_warm_boot) { 605 PHYMOD_IF_ERR_RETURN(falcon_tsc_set_uc_lane_cfg(&phy->access, serdes_firmware_config)); 606 } 607 return PHYMOD_E_NONE; 608 } 609 610 int falcon_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 611 { 612 phymod_phy_access_t phy_copy; 613 int start_lane, num_lane, i; 614 615 PHYMOD_IF_ERR_RETURN 616 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 617 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 618 619 for (i = 0; i < num_lane; i++) { 620 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 621 continue; 622 } 623 phy_copy.access.lane_mask = 1 << (start_lane + i); 624 PHYMOD_IF_ERR_RETURN 625 (falcon_lane_soft_reset_release(&phy_copy.access, 0)); 626 } 627 628 629 for (i = 0; i < num_lane; i++) { 630 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 631 continue; 632 } 633 phy_copy.access.lane_mask = 1 << (start_lane + i); 634 PHYMOD_IF_ERR_RETURN 635 (_falcon_phy_firmware_lane_config_set(&phy_copy, fw_config)); 636 } 637 638 639 for (i = 0; i < num_lane; i++) { 640 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 641 continue; 642 } 643 phy_copy.access.lane_mask = 1 << (start_lane + i); 644 PHYMOD_IF_ERR_RETURN 645 (falcon_lane_soft_reset_release(&phy_copy.access, 1)); 646 } 647 648 return PHYMOD_E_NONE; 649 } 650 651 652 /* reset rx sequencer 653 * flags - unused parameter 654 */ 655 int falcon_phy_rx_restart(const phymod_phy_access_t* phy) 656 { 657 phymod_phy_access_t phy_copy; 658 int start_lane, num_lane, i; 659 660 PHYMOD_IF_ERR_RETURN 661 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 662 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 663 664 for (i = 0; i < num_lane; i++) { 665 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 666 continue; 667 } 668 phy_copy.access.lane_mask = 1 << (start_lane + i); 669 670 PHYMOD_IF_ERR_RETURN(falcon_tsc_rx_restart(&phy_copy.access, 1)); 671 } 672 return PHYMOD_E_NONE; 673 } 674 675 676 int falcon_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 677 { 678 PHYMOD_IF_ERR_RETURN 679 (falcon_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity)); 680 return PHYMOD_E_NONE; 681 } 682 683 684 int falcon_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 685 { 686 PHYMOD_IF_ERR_RETURN 687 (falcon_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity)); 688 return PHYMOD_E_NONE; 689 } 690 691 int falcon_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 692 { 693 int8_t value = 0; 694 695 PHYMOD_IF_ERR_RETURN 696 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_PRE, &value)); 697 tx->pre = value; 698 PHYMOD_IF_ERR_RETURN 699 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_MAIN, &value)); 700 tx->main = value; 701 PHYMOD_IF_ERR_RETURN 702 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST1, &value)); 703 tx->post = value; 704 PHYMOD_IF_ERR_RETURN 705 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST2, &value)); 706 tx->post2 = value; 707 PHYMOD_IF_ERR_RETURN 708 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST3, &value)); 709 tx->post3 = value; 710 PHYMOD_IF_ERR_RETURN 711 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_AMP, &value)); 712 tx->amp = value; 713 PHYMOD_IF_ERR_RETURN 714 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_DRIVERMODE, &value)); 715 tx->drivermode = value; 716 717 return PHYMOD_E_NONE; 718 } 719 720 721 722 int falcon_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override) 723 { 724 phymod_phy_access_t phy_copy; 725 int start_lane, num_lane, i; 726 727 PHYMOD_IF_ERR_RETURN 728 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 729 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 730 731 for (i = 0; i < num_lane; i++) { 732 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 733 continue; 734 } 735 phy_copy.access.lane_mask = 1 << (start_lane + i); 736 737 PHYMOD_IF_ERR_RETURN 738 (falcon_tsc_tx_pi_freq_override(&phy_copy.access, 739 tx_override->phase_interpolator.enable, 740 tx_override->phase_interpolator.value)); 741 } 742 return PHYMOD_E_NONE; 743 } 744 745 int falcon_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override) 746 { 747 /* 748 PHYMOD_IF_ERR_RETURN 749 (temod_tx_pi_control_get(&phy->access, &tx_override->phase_interpolator.value)); 750 */ 751 return PHYMOD_E_NONE; 752 } 753 754 755 int falcon_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 756 { 757 uint32_t i; 758 759 /*params check*/ 760 if((rx->num_of_dfe_taps == 0) || (rx->num_of_dfe_taps > TSCF_NOF_DFES)){ 761 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set %u"), (unsigned int)rx->num_of_dfe_taps)); 762 } 763 764 /*vga set*/ 765 if (rx->vga.enable) { 766 /* first stop the rx adaption */ 767 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 1)); 768 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_VGA, rx->vga.value)); 769 } else { 770 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0)); 771 } 772 773 /*dfe set*/ 774 for (i = 0 ; i < rx->num_of_dfe_taps ; i++){ 775 if(rx->dfe[i].enable){ 776 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 1)); 777 switch (i) { 778 case 0: 779 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE1, rx->dfe[i].value)); 780 break; 781 case 1: 782 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE2, rx->dfe[i].value)); 783 break; 784 case 2: 785 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE3, rx->dfe[i].value)); 786 break; 787 case 3: 788 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE4, rx->dfe[i].value)); 789 break; 790 case 4: 791 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE5, rx->dfe[i].value)); 792 break; 793 case 5: 794 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE6, rx->dfe[i].value)); 795 break; 796 default: 797 return PHYMOD_E_PARAM; 798 } 799 } else { 800 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0)); 801 } 802 803 804 } 805 806 /*peaking filter set*/ 807 if(rx->peaking_filter.enable){ 808 /* first stop the rx adaption */ 809 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 1)); 810 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_PF, rx->peaking_filter.value)); 811 } else { 812 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0)); 813 } 814 815 if(rx->low_freq_peaking_filter.enable){ 816 /* first stop the rx adaption */ 817 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 1)); 818 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_PF2, rx->low_freq_peaking_filter.value)); 819 } else { 820 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0)); 821 } 822 return PHYMOD_E_NONE; 823 } 824 825 826 int falcon_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 827 { 828 int8_t val; 829 830 PHYMOD_IF_ERR_RETURN 831 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_PF, &val)); 832 rx->peaking_filter.value = val; 833 834 PHYMOD_IF_ERR_RETURN 835 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_PF2, &val)); 836 rx->low_freq_peaking_filter.value = val; 837 838 PHYMOD_IF_ERR_RETURN 839 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_VGA, &val)); 840 rx->vga.value = val; 841 842 PHYMOD_IF_ERR_RETURN 843 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE1, &val)); 844 rx->dfe[0].value = val; 845 846 PHYMOD_IF_ERR_RETURN 847 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE2, &val)); 848 rx->dfe[1].value = val; 849 850 PHYMOD_IF_ERR_RETURN 851 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE3, &val)); 852 rx->dfe[2].value = val; 853 854 PHYMOD_IF_ERR_RETURN 855 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE4, &val)); 856 rx->dfe[3].value = val; 857 858 PHYMOD_IF_ERR_RETURN 859 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE5, &val)); 860 rx->dfe[4].value = val; 861 862 PHYMOD_IF_ERR_RETURN 863 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE6, &val)); 864 rx->dfe[5].value = val; 865 866 rx->num_of_dfe_taps = 6; 867 rx->dfe[0].enable = 1; 868 rx->dfe[1].enable = 1; 869 rx->dfe[2].enable = 1; 870 rx->dfe[3].enable = 1; 871 rx->dfe[4].enable = 1; 872 rx->dfe[5].enable = 1; 873 rx->vga.enable = 1; 874 rx->low_freq_peaking_filter.enable = 1; 875 rx->peaking_filter.enable = 1; 876 877 return PHYMOD_E_NONE; 878 } 879 880 int falcon_phy_rx_adaptation_resume(const phymod_phy_access_t* phy) 881 { 882 uint8_t uc_lane_stopped; 883 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_uc_lane_status(&phy->access, &uc_lane_stopped)); 884 if (uc_lane_stopped) { 885 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0)); 886 } 887 return PHYMOD_E_NONE; 888 } 889 890 891 int falcon_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 892 { 893 uint32_t rst, rst_rx, rst_tx; 894 int start_lane, num_lane, i; 895 phymod_phy_access_t phy_copy; 896 897 PHYMOD_IF_ERR_RETURN 898 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 899 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 900 901 if (reset->rx == reset->tx) { 902 PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release_get(&phy_copy.access, &rst_tx)); 903 PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release_get(&phy_copy.access, &rst_rx)); 904 for (i = 0; i < num_lane; i++) { 905 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 906 continue; 907 } 908 phy_copy.access.lane_mask = 1 << (start_lane + i); 909 /*If tx is in reset, release tx lane*/ 910 if (rst_tx == 0) { 911 PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 1)); 912 PHYMOD_USLEEP(10); 913 } 914 /*If rx is in reset, release rx lane*/ 915 if (rst_rx == 0) { 916 PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 1)); 917 PHYMOD_USLEEP(10); 918 } 919 switch (reset->tx) { 920 case phymodResetDirectionIn: 921 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 0)); 922 break; 923 case phymodResetDirectionOut: 924 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 1)); 925 break; 926 case phymodResetDirectionInOut: 927 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 0)); 928 PHYMOD_USLEEP(10); 929 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 1)); 930 break; 931 default: 932 break; 933 } 934 } 935 } else { 936 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release_get(&phy->access, &rst)); 937 for (i = 0; i < num_lane; i++) { 938 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 939 continue; 940 } 941 phy_copy.access.lane_mask = 1 << (start_lane + i); 942 /*If ln_rst is is in reset , release ln_rst first*/ 943 if (rst == 0) { 944 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 1)); 945 PHYMOD_USLEEP(10); 946 } 947 switch (reset->tx) { 948 case phymodResetDirectionIn: 949 PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 0)); 950 break; 951 case phymodResetDirectionOut: 952 PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 1)); 953 break; 954 case phymodResetDirectionInOut: 955 PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 0)); 956 PHYMOD_USLEEP(10); 957 PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 1)); 958 break; 959 default: 960 break; 961 } 962 switch (reset ->rx) { 963 case phymodResetDirectionIn: 964 PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 0)); 965 break; 966 case phymodResetDirectionOut: 967 PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 1)); 968 break; 969 case phymodResetDirectionInOut: 970 PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 0)); 971 PHYMOD_USLEEP(10); 972 PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 1)); 973 break; 974 default: 975 break; 976 } 977 } 978 } 979 980 981 return PHYMOD_E_NONE; 982 } 983 984 985 int falcon_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 986 { 987 988 uint32_t rst, rst_rx, rst_tx; 989 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release_get(&phy->access, &rst)); 990 if(rst == 0) { 991 reset->tx = phymodResetDirectionIn; 992 reset->rx = phymodResetDirectionIn; 993 } else { 994 PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release_get(&phy->access, &rst_tx)); 995 PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release_get(&phy->access, &rst_rx)); 996 if (rst_tx == 0) { 997 reset->tx = phymodResetDirectionIn; 998 } else { 999 reset->tx = phymodResetDirectionOut; 1000 } 1001 1002 if(rst_rx == 0) { 1003 reset->rx = phymodResetDirectionIn; 1004 } else { 1005 reset->rx = phymodResetDirectionOut; 1006 } 1007 } 1008 1009 return PHYMOD_E_NONE; 1010 } 1011 1012 1013 int falcon_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power) 1014 { 1015 enum srds_core_pwrdn_mode_enum mode; 1016 phymod_phy_access_t phy_copy; 1017 int start_lane, num_lane, i; 1018 1019 PHYMOD_IF_ERR_RETURN 1020 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1021 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1022 1023 for (i = 0; i < num_lane; i++) { 1024 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1025 continue; 1026 } 1027 phy_copy.access.lane_mask = 1 << (start_lane + i); 1028 1029 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) { 1030 /*disable tx on the PMD side */ 1031 mode = PWRDN_TX; 1032 PHYMOD_IF_ERR_RETURN(falcon_tsc_lane_pwrdn(&phy_copy.access, mode)); 1033 } 1034 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) { 1035 /*enable tx on the PMD side */ 1036 PHYMOD_IF_ERR_RETURN(falcon_tsc_pwrdn_set(&phy_copy.access, 1, 0)); 1037 } 1038 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) { 1039 /*disable rx on the PMD side */ 1040 mode = PWRDN_RX; 1041 PHYMOD_IF_ERR_RETURN(falcon_tsc_lane_pwrdn(&phy_copy.access, mode)); 1042 } 1043 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) { 1044 PHYMOD_IF_ERR_RETURN(falcon_tsc_pwrdn_set(&phy_copy.access, 0, 0)); 1045 /*enable rx on the PMD side */ 1046 } 1047 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) { 1048 mode = PWR_ON; 1049 PHYMOD_IF_ERR_RETURN(falcon_tsc_lane_pwrdn(&phy_copy.access, mode)); 1050 } 1051 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) { 1052 /* Both Tx and Rx power down */ 1053 mode = PWRDN; 1054 PHYMOD_IF_ERR_RETURN(falcon_tsc_lane_pwrdn(&phy_copy.access, mode)); 1055 } 1056 } 1057 return PHYMOD_E_NONE; 1058 } 1059 1060 int falcon_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 1061 { 1062 power_status_t pwrdn; 1063 PHYMOD_IF_ERR_RETURN(falcon_tsc_pwrdn_get(&phy->access, &pwrdn)); 1064 power->rx = (pwrdn.rx_s_pwrdn == 0)? phymodPowerOn: phymodPowerOff; 1065 power->tx = (pwrdn.tx_s_pwrdn == 0)? phymodPowerOn: phymodPowerOff; 1066 return PHYMOD_E_NONE; 1067 } 1068 1069 1070 int falcon_phy_interface_config_set(const phymod_phy_access_t* phy, 1071 uint32_t flags, 1072 const phymod_phy_inf_config_t* config) 1073 { 1074 /* phymod_tx_t tx_params; */ 1075 uint32_t current_pll_div=0; 1076 uint32_t vco_rate; 1077 uint32_t new_pll_div=0; 1078 int16_t new_os_mode =0; 1079 phymod_phy_access_t pm_phy_copy; 1080 int start_lane, num_lane, i; 1081 int rv; 1082 uint32_t enable[PHYMOD_MAX_LANES_PER_CORE] = {0}; 1083 1084 /* sc_table_entry exp_entry; RAVI */ 1085 phymod_firmware_lane_config_t firmware_lane_config; 1086 phymod_firmware_core_config_t firmware_core_config; 1087 1088 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 1089 PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config)); 1090 firmware_lane_config.MediaType = 0; 1091 1092 /*next program the tx fir taps and driver current based on the input*/ 1093 PHYMOD_IF_ERR_RETURN 1094 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1095 1096 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1097 1098 /*Get lane reset status*/ 1099 for (i = 0; i < num_lane; i++) { 1100 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1101 continue; 1102 } 1103 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1104 PHYMOD_IF_ERR_RETURN 1105 (falcon_lane_soft_reset_release_get(&pm_phy_copy.access, &enable[i])); 1106 } 1107 1108 /*Hold the per lne soft reset bit*/ 1109 for (i = 0; i < num_lane; i++) { 1110 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1111 continue; 1112 } 1113 if (enable[i]) 1114 { 1115 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1116 PHYMOD_IF_ERR_RETURN 1117 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1118 } 1119 } 1120 1121 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 1122 PHYMOD_IF_ERR_RETURN 1123 (falcon_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 1124 1125 /*make sure that an and config from pcs is off*/ 1126 firmware_core_config.CoreConfigFromPCS = 0; 1127 firmware_lane_config.AnEnabled = 0; 1128 firmware_lane_config.LaneConfigFromPCS = 0; 1129 firmware_lane_config.DfeOn = 1; 1130 firmware_lane_config.LpDfeOn = 0; 1131 firmware_lane_config.Cl72RestTO = 1; 1132 if(config->data_rate == 1000) 1133 firmware_lane_config.DfeOn = 0; 1134 1135 1136 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1137 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1138 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1139 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1140 } else { 1141 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1142 } 1143 1144 /* No PCS 1145 PHYMOD_IF_ERR_RETURN 1146 (tefmod_update_port_mode(&phy->access, (int *) &pll_switch)); 1147 */ 1148 1149 /* Error code returned by get_vco function is not compliant with BCM error code 1150 convert the tier1 error code to the PHYMOD error code which is compliant with 1151 BCM error codes */ 1152 rv = falcon_tsc_get_vco(config, &vco_rate, &new_pll_div, &new_os_mode); 1153 if (rv != PHYMOD_E_NONE) { 1154 /* SDK-95356 the above function could fail due to invalid param */ 1155 return PHYMOD_E_CONFIG; 1156 } 1157 1158 PHYMOD_IF_ERR_RETURN 1159 (falcon_pll_mode_get(&pm_phy_copy.access, ¤t_pll_div)); 1160 1161 /* new_pll_div already found 1162 PHYMOD_IF_ERR_RETURN 1163 (tefmod_plldiv_lkup_get(&phy->access, spd_intf, &new_pll_div)); 1164 */ 1165 1166 /* 1167 if(config->device_aux_modes !=NULL){ 1168 PHYMOD_IF_ERR_RETURN 1169 (_tscf_st_hto_interface_config_set(config->device_aux_modes, start_lane, new_speed_vec, &new_pll_div, &new_os_mode)) ; 1170 } 1171 */ 1172 1173 1174 1175 1176 1177 /*if pll change is enabled*/ 1178 if((current_pll_div != new_pll_div) && (PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)){ 1179 if(config->interface_type != phymodInterfaceBypass) { 1180 /*Terminate the execution of the function*/ 1181 PHYMOD_DEBUG_WARN(("PLL has to change for speed_set from %u to %u but DONT_TURN_OFF_PLL flag is enabled \n", 1182 (unsigned int)current_pll_div, (unsigned int)new_pll_div)); 1183 return PHYMOD_E_NONE; 1184 } 1185 } 1186 /*pll switch is required and expected */ 1187 if((current_pll_div != new_pll_div) && !(PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)) { 1188 /* phymod_access_t tmp_phy_access; */ 1189 PHYMOD_IF_ERR_RETURN 1190 (falcon_core_soft_reset_release(&pm_phy_copy.access, 0)); 1191 1192 /*release the uc reset */ 1193 #if 0 1194 PHYMOD_IF_ERR_RETURN 1195 (falcon_tsc_uc_reset(&pm_phy_copy.access ,0)); 1196 #endif 1197 /*set the PLL divider */ 1198 PHYMOD_IF_ERR_RETURN 1199 (falcon_pll_mode_set(&pm_phy_copy.access, new_pll_div)); 1200 /* In case of 22.5G (div 180 and ref_clk 125MHz), need to call falcon_tsc_configure_pll to set AMS_PLL_CTL values */ 1201 if ((new_pll_div == 0xb) && (config->ref_clock == phymodRefClk125Mhz)) 1202 { 1203 PHYMOD_IF_ERR_RETURN 1204 (falcon_tsc_configure_pll (&pm_phy_copy.access, FALCON_TSC_pll_div_180x_refc125)); 1205 } 1206 1207 firmware_core_config.VcoRate = (vco_rate * 16 + 500) / 1000 - 224; 1208 1209 /*change the master port num to the current caller port */ 1210 1211 /* 1212 PHYMOD_IF_ERR_RETURN 1213 (tefmod_master_port_num_set(&phy->access, start_lane)); 1214 ////////////////// Do we need PLL reset /////////////// 1215 */ 1216 #if 0 1217 PHYMOD_IF_ERR_RETURN 1218 (falcon_pll_reset_enable_set(&pm_phy_copy.access, 1)); 1219 #endif 1220 /*update the firmware config properly*/ 1221 PHYMOD_IF_ERR_RETURN 1222 (falcon_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config)); 1223 PHYMOD_IF_ERR_RETURN 1224 (falcon_core_soft_reset_release(&pm_phy_copy.access, 1)); 1225 } 1226 1227 /* 1228 PHYMOD_IF_ERR_RETURN 1229 (tefmod_set_spd_intf(&phy->access, spd_intf)); 1230 */ 1231 1232 /*change TX parameters if enabled*/ 1233 /* 1234 if((PHYMOD_IF_F_DONT_OVERIDE_TX_PARAMS & flags) == 0) { 1235 PHYMOD_IF_ERR_RETURN 1236 (tscf_phy_media_type_tx_get(phy, phymodMediaTypeMid, &tx_params)); 1237 } 1238 */ 1239 for (i = 0; i < num_lane; i++) { 1240 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1241 continue; 1242 } 1243 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i); 1244 PHYMOD_IF_ERR_RETURN 1245 (_falcon_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 1246 } 1247 for (i = 0; i < num_lane; i++) { 1248 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1249 continue; 1250 } 1251 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i); 1252 PHYMOD_IF_ERR_RETURN 1253 (falcon_osr_mode_set(&pm_phy_copy.access, new_os_mode)); 1254 } 1255 1256 /*release the per lne soft reset bit*/ 1257 for (i = 0; i < num_lane; i++) { 1258 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1259 continue; 1260 } 1261 if (enable[i]) 1262 { 1263 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1264 PHYMOD_IF_ERR_RETURN 1265 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1266 } 1267 } 1268 1269 1270 1271 return PHYMOD_E_NONE; 1272 } 1273 1274 /*flags- unused parameter*/ 1275 int falcon_phy_interface_config_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_ref_clk_t ref_clock, phymod_phy_inf_config_t* config) 1276 { 1277 int osr_mode; 1278 uint32_t pll_div; 1279 uint32_t pll_multiplier, refclk; 1280 phymod_phy_access_t phy_copy; 1281 int actual_osr; 1282 phymod_firmware_lane_config_t firmware_lane_config; 1283 int start_lane, num_lane; 1284 1285 config->ref_clock = ref_clock; 1286 1287 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1288 PHYMOD_IF_ERR_RETURN 1289 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1290 phy_copy.access.lane_mask = 0x1 << start_lane; 1291 1292 PHYMOD_IF_ERR_RETURN 1293 (falcon_osr_mode_get(&phy->access, &osr_mode)); 1294 PHYMOD_IF_ERR_RETURN 1295 (falcon_pll_mode_get(&phy_copy.access, &pll_div)); 1296 PHYMOD_IF_ERR_RETURN 1297 (_falcon_pll_multiplier_get(pll_div, &pll_multiplier)); 1298 1299 PHYMOD_IF_ERR_RETURN 1300 (falcon_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 1301 if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) { 1302 PHYMOD_INTF_MODES_FIBER_SET(config); 1303 } else if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeCopperCable) { 1304 PHYMOD_INTF_MODES_FIBER_CLR(config); 1305 PHYMOD_INTF_MODES_COPPER_SET(config); 1306 } else { 1307 PHYMOD_INTF_MODES_FIBER_CLR(config); 1308 PHYMOD_INTF_MODES_BACKPLANE_SET(config); 1309 } 1310 1311 if (ref_clock == phymodRefClk156Mhz) { 1312 refclk = 15625; 1313 } else if (ref_clock == phymodRefClk125Mhz) { 1314 refclk = 12500; 1315 } else { 1316 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("Unknown refclk"))); 1317 } 1318 1319 PHYMOD_IF_ERR_RETURN(_falcon_actual_osr_get(osr_mode, &actual_osr)); 1320 1321 config->data_rate = (refclk*pll_multiplier)/(100*actual_osr); 1322 config->interface_type = phymodInterfaceBypass; 1323 1324 if(osr_mode == 1) { 1325 PHYMOD_INTF_MODES_OS2_SET(config); 1326 } 1327 1328 return PHYMOD_E_NONE; 1329 } 1330 1331 1332 int falcon_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 1333 { 1334 phymod_phy_access_t phy_copy; 1335 int start_lane, num_lane, i; 1336 1337 PHYMOD_IF_ERR_RETURN 1338 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1339 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1340 1341 for (i = 0; i < num_lane; i++) { 1342 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1343 continue; 1344 } 1345 phy_copy.access.lane_mask = 1 << (start_lane + i); 1346 1347 PHYMOD_IF_ERR_RETURN 1348 (falcon_lane_soft_reset_release(&phy_copy.access, 0)); 1349 } 1350 1351 for (i = 0; i < num_lane; i++) { 1352 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1353 continue; 1354 } 1355 phy_copy.access.lane_mask = 1 << (start_lane + i); 1356 1357 PHYMOD_IF_ERR_RETURN 1358 (falcon_clause72_control(&phy_copy.access, cl72_en)); 1359 } 1360 1361 for (i = 0; i < num_lane; i++) { 1362 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1363 continue; 1364 } 1365 phy_copy.access.lane_mask = 1 << (start_lane + i); 1366 1367 PHYMOD_IF_ERR_RETURN 1368 (falcon_lane_soft_reset_release(&phy_copy.access, 1)); 1369 } 1370 return PHYMOD_E_NONE; 1371 } 1372 1373 int falcon_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 1374 { 1375 PHYMOD_IF_ERR_RETURN 1376 (falcon_clause72_control_get(&phy->access, cl72_en)); 1377 return PHYMOD_E_NONE; 1378 } 1379 1380 1381 int falcon_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 1382 { 1383 uint32_t local_status; 1384 PHYMOD_IF_ERR_RETURN 1385 (falcon_pmd_cl72_receiver_status(&phy->access, &local_status)); 1386 status->locked = local_status; 1387 return PHYMOD_E_NONE; 1388 } 1389 1390 int falcon_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 1391 { 1392 int i; 1393 int start_lane, num_lane; 1394 int rv = PHYMOD_E_NONE; 1395 phymod_phy_access_t phy_copy; 1396 1397 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1398 1399 /* next figure out the lane num and start_lane based on the input */ 1400 PHYMOD_IF_ERR_RETURN 1401 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1402 1403 switch (loopback) { 1404 case phymodLoopbackGlobal : 1405 /* PHYMOD_IF_ERR_RETURN(tefmod_tx_loopback_control(&phy->access, enable, start_lane, num_lane)); */ 1406 break; 1407 case phymodLoopbackGlobalPMD : 1408 for (i = 0; i < num_lane; i++) { 1409 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1410 continue; 1411 } 1412 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1413 PHYMOD_IF_ERR_RETURN(falcon_tsc_dig_lpbk(&phy_copy.access, (uint8_t) enable)); 1414 PHYMOD_IF_ERR_RETURN(falcon_pmd_force_signal_detect(&phy_copy.access, (int) enable)); 1415 } 1416 break; 1417 case phymodLoopbackRemotePMD : 1418 PHYMOD_IF_ERR_RETURN(falcon_tsc_rmt_lpbk(&phy->access, (uint8_t)enable)); 1419 break; 1420 case phymodLoopbackRemotePCS : 1421 /* PHYMOD_IF_ERR_RETURN(tefmod_rx_loopback_control(&phy->access, enable)); */ 1422 break; 1423 default : 1424 break; 1425 } 1426 return rv; 1427 } 1428 1429 int falcon_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 1430 { 1431 int start_lane, num_lane; 1432 1433 /*next figure out the lane num and start_lane based on the input*/ 1434 PHYMOD_IF_ERR_RETURN 1435 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1436 1437 switch (loopback) { 1438 case phymodLoopbackGlobal : 1439 /* PHYMOD_IF_ERR_RETURN(temod_tx_loopback_get(&phy->access, &enable_core)); */ 1440 /* *enable = (enable_core >> start_lane) & 0x1; */ 1441 break; 1442 case phymodLoopbackGlobalPMD : 1443 PHYMOD_IF_ERR_RETURN(falcon_tsc_dig_lpbk_get(&phy->access, enable)); 1444 break; 1445 case phymodLoopbackRemotePMD : 1446 PHYMOD_IF_ERR_RETURN(falcon_tsc_rmt_lpbk_get(&phy->access, enable)); 1447 break; 1448 case phymodLoopbackRemotePCS : 1449 /* PHYMOD_IF_ERR_RETURN(temod_rx_loopback_control(&phy->access, enable, enable, enable)); */ 1450 break; 1451 default : 1452 break; 1453 } 1454 return PHYMOD_E_NONE; 1455 } 1456 1457 int falcon_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 1458 { 1459 int rv; 1460 phymod_phy_access_t phy_access, phy_access_copy; 1461 phymod_core_access_t core_copy; 1462 phymod_firmware_core_config_t firmware_core_config_tmp; 1463 uint32_t default_pll_div=0xa; 1464 1465 TSCF_CORE_TO_PHY_ACCESS(&phy_access, core); 1466 phy_access_copy = phy_access; 1467 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 1468 core_copy.access.lane_mask = 0x1; 1469 phy_access_copy = phy_access; 1470 phy_access_copy.access = core->access; 1471 phy_access_copy.access.lane_mask = 0x1; 1472 phy_access_copy.type = core->type; 1473 1474 1475 1476 if(!PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 1477 PHYMOD_IF_ERR_RETURN 1478 (falcon_pmd_reset_seq(&core_copy.access, core_status->pmd_active)); 1479 } 1480 1481 /* need to set the heart beat default is for 156.25M */ 1482 PHYMOD_IF_ERR_RETURN(falcon_refclk_set(&core_copy.access, init_config->interface.com_clock)); 1483 1484 rv = _falcon_core_firmware_load(&core_copy, init_config); 1485 if (rv != PHYMOD_E_NONE) { 1486 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask)); 1487 PHYMOD_IF_ERR_RETURN(rv); 1488 } 1489 1490 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 1491 return PHYMOD_E_NONE; 1492 } 1493 1494 /*next we need to check if the load is correct or not */ 1495 if(init_config->firmware_load_method != phymodFirmwareLoadMethodNone) { 1496 1497 /*next we need to set the uc active and release uc */ 1498 PHYMOD_IF_ERR_RETURN 1499 (falcon_uc_active_set(&core_copy.access ,1)); 1500 1501 /*release the uc reset */ 1502 PHYMOD_IF_ERR_RETURN 1503 (falcon_tsc_uc_reset(&core_copy.access ,0)); 1504 1505 #ifndef FALCON_PMD_CRC_UCODE 1506 if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 1507 rv = falcon_tsc_ucode_load_verify(&core_copy.access, (uint8_t *) &tscf_ucode, tscf_ucode_len); 1508 1509 if (rv != PHYMOD_E_NONE) { 1510 PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask)); 1511 PHYMOD_IF_ERR_RETURN(rv); 1512 } 1513 } 1514 #endif 1515 1516 PHYMOD_IF_ERR_RETURN 1517 (falcon_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x1)); 1518 1519 /* we need to wait at least 10ms for the uc to settle */ 1520 PHYMOD_USLEEP(10000); 1521 1522 /* poll the ready bit in 10 ms */ 1523 #ifndef FALCON_PMD_CRC_UCODE 1524 PHYMOD_IF_ERR_RETURN 1525 (falcon_tsc_poll_uc_dsc_ready_for_cmd_equals_1(&phy_access_copy.access, 1)); 1526 #else 1527 if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 1528 rv = falcon_tsc_ucode_crc_verify(&core_copy.access, tscf_ucode_len, tscf_ucode_crc); 1529 if (rv != PHYMOD_E_NONE) { 1530 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC load-verify failed\n", core->access.addr, core->access.lane_mask)); 1531 PHYMOD_IF_ERR_RETURN(rv); 1532 } 1533 } 1534 #endif 1535 PHYMOD_IF_ERR_RETURN 1536 (falcon_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x0)); 1537 } 1538 1539 /* AFE/PLL config */ 1540 if(init_config->afe_pll.afe_pll_change_default) { 1541 PHYMOD_IF_ERR_RETURN 1542 (falcon_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 1543 firmware_core_config_tmp.disable_write_pll_iqp = 1; 1544 } else { 1545 PHYMOD_IF_ERR_RETURN 1546 (falcon_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 1547 firmware_core_config_tmp.disable_write_pll_iqp = 0; 1548 } 1549 1550 /* plldiv CONFIG */ 1551 PHYMOD_IF_ERR_RETURN 1552 (falcon_pll_mode_set(&core_copy.access, default_pll_div)); 1553 /* In case of 22.5G (div 180 and ref_clk 125MHz), need to call falcon_tsc_configure_pll to set AMS_PLL_CTL values */ 1554 /* The below dead-code was added deliberately, for potential future cases, in which default_pll_div will be modified */ 1555 /* coverity[dead_error_line] */ 1556 if ((default_pll_div == 0xb) && (init_config->interface.com_clock == phymodRefClk125Mhz)) 1557 { 1558 PHYMOD_IF_ERR_RETURN 1559 (falcon_tsc_configure_pll (&core_copy.access, FALCON_TSC_pll_div_180x_refc125)); 1560 } 1561 1562 /*now config the lane mapping and polarity */ 1563 PHYMOD_IF_ERR_RETURN 1564 (falcon_core_lane_map_set(core, &init_config->lane_map)); 1565 /* 1566 PHYMOD_IF_ERR_RETURN 1567 (tscf_core_lane_map_set(core, &init_config->lane_map)); 1568 PHYMOD_IF_ERR_RETURN 1569 (tefmod_autoneg_timer_init(&core->access)); 1570 PHYMOD_IF_ERR_RETURN 1571 (tefmod_master_port_num_set(&core->access, 0)); 1572 */ 1573 /*don't overide the fw that set in config set if not specified*/ 1574 firmware_core_config_tmp = init_config->firmware_core_config; 1575 firmware_core_config_tmp.CoreConfigFromPCS = 0; 1576 /*set the vco rate to be default at 10.3125G */ 1577 firmware_core_config_tmp.VcoRate = 0x13; 1578 1579 PHYMOD_IF_ERR_RETURN 1580 (falcon_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp)); 1581 1582 1583 /* release core soft reset */ 1584 PHYMOD_IF_ERR_RETURN 1585 (falcon_core_soft_reset_release(&core_copy.access, 1)); 1586 1587 return PHYMOD_E_NONE; 1588 } 1589 1590 int falcon_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 1591 { 1592 const phymod_access_t *pm_acc = &phy->access; 1593 phymod_phy_access_t pm_phy_copy; 1594 int start_lane, num_lane, i; 1595 int lane_bkup; 1596 phymod_polarity_t tmp_pol; 1597 1598 PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol)); 1599 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1600 1601 /*next program the tx fir taps and driver current based on the input*/ 1602 PHYMOD_IF_ERR_RETURN 1603 (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane)); 1604 /*per lane based reset release */ 1605 /* PHYMOD_IF_ERR_RETURN 1606 (tefmod_pmd_x4_reset(pm_acc)); */ 1607 PHYMOD_IF_ERR_RETURN(falcon_lane_hard_soft_reset_release(&pm_phy_copy.access, 0)); 1608 PHYMOD_IF_ERR_RETURN(falcon_lane_hard_soft_reset_release(&pm_phy_copy.access, 1)); 1609 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1610 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1611 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1612 1613 lane_bkup = pm_phy_copy.access.lane_mask; 1614 for (i = 0; i < num_lane; i++) { 1615 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1616 continue; 1617 } 1618 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1619 PHYMOD_IF_ERR_RETURN 1620 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1621 } 1622 for (i = 0; i < num_lane; i++) { 1623 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1624 continue; 1625 } 1626 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1627 PHYMOD_IF_ERR_RETURN 1628 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1629 } 1630 pm_phy_copy.access.lane_mask = lane_bkup; 1631 1632 /* program the rx/tx polarity */ 1633 for (i = 0; i < num_lane; i++) { 1634 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1635 tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> (i + start_lane) & 0x1; 1636 tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> (i + start_lane) & 0x1; 1637 PHYMOD_IF_ERR_RETURN 1638 (falcon_phy_polarity_set(&pm_phy_copy, &tmp_pol)); 1639 } 1640 1641 for (i = 0; i < num_lane; i++) { 1642 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1643 continue; 1644 } 1645 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1646 PHYMOD_IF_ERR_RETURN 1647 (falcon_phy_tx_set(&pm_phy_copy, &init_config->tx[i])); 1648 } 1649 1650 PHYMOD_IF_ERR_RETURN 1651 (falcon_phy_cl72_set(&pm_phy_copy, init_config->cl72_en)); 1652 1653 /* ONLY for PCS 1654 PHYMOD_IF_ERR_RETURN 1655 (tefmod_update_port_mode(pm_acc, &pll_restart)); 1656 1657 PHYMOD_IF_ERR_RETURN 1658 (tefmod_rx_lane_control_set(pm_acc, 1)); 1659 PHYMOD_IF_ERR_RETURN 1660 (tefmod_tx_lane_control_set(pm_acc, TEFMOD_TX_LANE_RESET_TRAFFIC_ENABLE)); 1661 */ 1662 1663 1664 return PHYMOD_E_NONE; 1665 1666 } 1667 1668 1669 /* this function gives the PMD_RX_LOCK_STATUS */ 1670 int falcon_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status) 1671 { 1672 1673 unsigned char rx_lock; 1674 PHYMOD_IF_ERR_RETURN(falcon_tsc_pmd_lock_status(&phy->access, &rx_lock)); 1675 *link_status = (uint32_t ) rx_lock; 1676 1677 return PHYMOD_E_NONE; 1678 1679 } 1680 1681 1682 int falcon_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* pmd_lock) 1683 { 1684 1685 PHYMOD_IF_ERR_RETURN(falcon_phy_link_status_get(phy, pmd_lock)); 1686 return PHYMOD_E_NONE; 1687 1688 } 1689 1690 /* this function gives the PMD_RX_LOCK_STATUS */ 1691 int falcon_phy_rx_signal_detect_get(const phymod_phy_access_t* phy, uint32_t* signal_detect) 1692 { 1693 1694 PHYMOD_IF_ERR_RETURN(falcon_tsc_signal_detect(&phy->access, signal_detect)); 1695 1696 return PHYMOD_E_NONE; 1697 1698 } 1699 1700 int falcon_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val) 1701 { 1702 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val)); 1703 return PHYMOD_E_NONE; 1704 } 1705 1706 1707 int falcon_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val) 1708 { 1709 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val)); 1710 return PHYMOD_E_NONE; 1711 } 1712 1713 int falcon_phy_eye_margin_est_get(const phymod_phy_access_t* phy, phymod_eye_margin_mode_t eye_margin_mode, uint32_t* value) 1714 { 1715 int start_lane, num_lane; 1716 phymod_phy_access_t phy_copy; 1717 int hz_l, hz_r, vt_u, vt_d; 1718 1719 1720 /* first get the start_lane */ 1721 PHYMOD_IF_ERR_RETURN 1722 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1723 1724 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1725 phy_copy.access.lane_mask = 0x1 << start_lane; 1726 1727 PHYMOD_IF_ERR_RETURN 1728 (falcon_tsc_get_eye_margin_est(&phy_copy.access, &hz_l, &hz_r, &vt_u, &vt_d)); 1729 1730 switch (eye_margin_mode) { 1731 case phymod_eye_marign_HZ_L: 1732 *value = hz_l; 1733 break; 1734 case phymod_eye_marign_HZ_R: 1735 *value = hz_r; 1736 break; 1737 case phymod_eye_marign_VT_U: 1738 *value = vt_u; 1739 break; 1740 case phymod_eye_marign_VT_D: 1741 *value = vt_d; 1742 break; 1743 default: 1744 *value = 0; 1745 break; 1746 } 1747 1748 return PHYMOD_E_NONE; 1749 } 1750 1751 1752 1753 int falcon_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout) 1754 { 1755 1756 1757 /* Not supported */ 1758 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_wait_event) \n")); 1759 1760 1761 return PHYMOD_E_NONE; 1762 1763 } 1764 1765