blackhawk.c (75924B)
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_blackhawk_xgxs_defs.h> 15 #include <phymod/chip/blackhawk.h> 16 #include "blackhawk/tier1/blackhawk_cfg_seq.h" 17 #include "blackhawk/tier1/blackhawk_tsc_enum.h" 18 #include "blackhawk/tier1/blackhawk_tsc_common.h" 19 #include "blackhawk/tier1/blackhawk_tsc_interface.h" 20 #include "blackhawk/tier1/blackhawk_tsc_dependencies.h" 21 #include "blackhawk/tier1/blackhawk_tsc_internal.h" 22 #include "blackhawk/tier1/public/blackhawk_api_uc_vars_rdwr_defns_public.h" 23 #include "blackhawk/tier1/blackhawk_tsc_access.h" 24 25 26 27 28 extern unsigned char blackhawk_ucode_rev0[]; 29 extern unsigned int blackhawk_ucode_len_rev0; 30 extern unsigned short blackhawk_ucode_crc_rev0; 31 extern unsigned short blackhawk_ucode_stack_size_rev0; 32 33 extern unsigned char blackhawk_ucode_rev1[]; 34 extern unsigned int blackhawk_ucode_len_rev1; 35 extern unsigned short blackhawk_ucode_crc_rev1; 36 extern unsigned short blackhawk_ucode_stack_size_rev1; 37 38 39 #define BLACKHAWK_MODEL 0x26 40 #define BLACKHAWK_NOF_LANES_IN_CORE 0x8 41 #define BLACKHAWK_PHY_ALL_LANES 0xff 42 #define BLACKHAWK_TX_TAP_NUM 12 43 #define BLACKHAWK_PMD_CRC_UCODE 1 44 45 46 #define REF_CLOCK_312P5_HZ 312500000 47 #define REF_CLOCK_156P25_HZ 156250000 48 49 50 #define BLACKHAWK_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \ 51 do{\ 52 PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\ 53 (_phy_access)->type = (_core_access)->type; \ 54 (_phy_access)->port_loc = (_core_access)->port_loc; \ 55 (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \ 56 (_phy_access)->access.lane_mask = BLACKHAWK_PHY_ALL_LANES; \ 57 }while(0) 58 59 60 int blackhawk_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 61 { 62 phymod_core_access_t core_copy; 63 64 blackhawk_rev_id0_t rev_id0; 65 blackhawk_rev_id1_t rev_id1; 66 *is_identified = 0; 67 68 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 69 70 71 /* PHY IDs match - now check model */ 72 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_identify(&core_copy.access, &rev_id0, &rev_id1)); 73 if (rev_id0.revid_model == BLACKHAWK_MODEL) { 74 *is_identified = 1; 75 } 76 77 return PHYMOD_E_NONE; 78 79 } 80 81 82 int blackhawk_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info) 83 { 84 info->core_version = phymodCoreVersionBlackhawk16; 85 info->serdes_id = 0; 86 info->phy_id0 = 0; 87 info->phy_id1 = 0; 88 89 return PHYMOD_E_NONE; 90 91 } 92 93 94 int blackhawk_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map) 95 { 96 phymod_core_access_t core_copy; 97 uint32_t tx_lane_map, rx_lane_map; 98 int i = 0; 99 100 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 101 core_copy.access.lane_mask = 0x1; 102 103 PHYMOD_IF_ERR_RETURN 104 (blackhawk_pmd_lane_map_get(&core_copy.access, &tx_lane_map, &rx_lane_map)); 105 106 /*next get the lane map into serdes spi format */ 107 for (i = 0; i < BLACKHAWK_NOF_LANES_IN_CORE; i++) { 108 lane_map->lane_map_tx[tx_lane_map >> (4 * i) & 0xf] = i; 109 lane_map->lane_map_rx[rx_lane_map >> (4 * i) & 0xf] = i; 110 } 111 112 return PHYMOD_E_NONE; 113 } 114 115 116 int blackhawk_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 117 { 118 return PHYMOD_E_NONE; 119 120 } 121 122 int blackhawk_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 123 { 124 return PHYMOD_E_NONE; 125 126 } 127 128 129 130 int blackhawk_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 131 { 132 int start_lane, num_lane, i; 133 uint32_t lane_reset; 134 phymod_phy_access_t pm_phy_copy; 135 136 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 137 138 PHYMOD_IF_ERR_RETURN 139 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 140 141 /*first check if lane is in reset */ 142 PHYMOD_IF_ERR_RETURN 143 (blackhawk_lane_soft_reset_get(&pm_phy_copy.access, &lane_reset)); 144 145 /* if lane is not in reset, then reset the lane first */ 146 if (!lane_reset) { 147 PHYMOD_IF_ERR_RETURN 148 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 1)); 149 } 150 151 for (i = 0; i < num_lane; i++) { 152 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 153 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 154 continue; 155 } 156 switch (tx_control) 157 { 158 case phymodTxElectricalIdleEnable: 159 PHYMOD_IF_ERR_RETURN(blackhawk_electrical_idle_set(&pm_phy_copy.access, 1)); 160 break; 161 case phymodTxElectricalIdleDisable: 162 PHYMOD_IF_ERR_RETURN(blackhawk_electrical_idle_set(&pm_phy_copy.access, 0)); 163 break; 164 case phymodTxSquelchOn: 165 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_tx_disable(&pm_phy_copy.access, 1)); 166 break; 167 case phymodTxSquelchOff: 168 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_tx_disable(&pm_phy_copy.access, 0)); 169 break; 170 default: 171 PHYMOD_DEBUG_ERROR(("This control is NOT SUPPORTED!! (blackhawk_phy_tx_lane_control_set) \n")); 172 break; 173 } 174 } 175 176 /* if lane is not in reset, then reset the lane first */ 177 if (!lane_reset) { 178 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 179 PHYMOD_IF_ERR_RETURN 180 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 0)); 181 } 182 183 return PHYMOD_E_NONE; 184 } 185 186 187 int blackhawk_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t *tx_control) 188 { 189 190 uint8_t disable, idle_enable; 191 phymod_phy_access_t pm_phy_copy; 192 193 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 194 195 196 *tx_control = phymodTxSquelchOff; 197 198 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_tx_disable_get(&pm_phy_copy.access, &disable)); 199 if(disable) { 200 *tx_control = phymodTxSquelchOn; 201 } else { 202 PHYMOD_IF_ERR_RETURN(blackhawk_electrical_idle_get(&pm_phy_copy.access, &idle_enable)); 203 if (!idle_enable) { 204 *tx_control = phymodTxElectricalIdleDisable; 205 } 206 } 207 208 return PHYMOD_E_NONE; 209 } 210 211 /*Rx control*/ 212 int blackhawk_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 213 { 214 phymod_phy_access_t pm_phy_copy; 215 int start_lane, num_lane, i; 216 217 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 218 /* next program the tx fir taps and driver current based on the input */ 219 PHYMOD_IF_ERR_RETURN 220 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 221 222 /*put the lane into dp reset */ 223 PHYMOD_IF_ERR_RETURN 224 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 1)); 225 226 227 switch (rx_control) { 228 case phymodRxSquelchOn: 229 for (i = 0; i < num_lane; i++) { 230 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 231 continue; 232 } 233 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 234 PHYMOD_IF_ERR_RETURN(blackhawk_pmd_force_signal_detect(&pm_phy_copy.access, 1, 0)); 235 } 236 break; 237 case phymodRxSquelchOff: 238 for (i = 0; i < num_lane; i++) { 239 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 240 continue; 241 } 242 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 243 PHYMOD_IF_ERR_RETURN(blackhawk_pmd_force_signal_detect(&pm_phy_copy.access, 0, 0)); 244 } 245 break; 246 default: 247 break; 248 } 249 250 /*release the lane dp reset */ 251 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 252 PHYMOD_IF_ERR_RETURN 253 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 0)); 254 255 return PHYMOD_E_NONE; 256 } 257 258 int blackhawk_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 259 { 260 uint8_t force_en, force_val; 261 phymod_phy_access_t pm_phy_copy; 262 263 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 264 265 /* first get the force enabled bit and forced value */ 266 PHYMOD_IF_ERR_RETURN(blackhawk_pmd_force_signal_detect_get(&pm_phy_copy.access, &force_en, &force_val)); 267 268 if ((force_en) && (force_val == 0)) { 269 *rx_control = phymodRxSquelchOn; 270 } else { 271 *rx_control = phymodRxSquelchOff; 272 } 273 return PHYMOD_E_NONE; 274 275 } 276 277 int blackhawk_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability_set_type) 278 { 279 280 281 /* Not supported */ 282 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (blackhawk_phy_rx_lane_control_get) \n")); 283 284 285 return PHYMOD_E_NONE; 286 287 } 288 289 int blackhawk_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 290 { 291 /* Not supported */ 292 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (blackhawk_phy_autoneg_ability_get) \n")); 293 return PHYMOD_E_UNAVAIL; 294 } 295 296 int blackhawk_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 297 { 298 /* Not supported */ 299 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (blackhawk_phy_autoneg_set) \n")); 300 return PHYMOD_E_UNAVAIL; 301 } 302 303 int blackhawk_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 304 { 305 /* Not supported */ 306 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (blackhawk_phy_autoneg_get) \n")); 307 return PHYMOD_E_UNAVAIL; 308 } 309 310 int blackhawk_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 311 { 312 /* Not supported */ 313 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (blackhawk_phy_autoneg_status_get) \n")); 314 return PHYMOD_E_UNAVAIL; 315 } 316 317 /* load tscf fw. the fw_loader parameter is valid just for external fw load*/ 318 STATIC 319 int _blackhawk_core_firmware_load(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config) 320 { 321 int wait; 322 phymod_core_access_t core_copy; 323 phymod_phy_access_t phy_access; 324 phymod_firmware_load_info_t info; 325 326 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 327 BLACKHAWK_CORE_TO_PHY_ACCESS(&phy_access, core); 328 329 /* Get ucode load info */ 330 PHYMOD_IF_ERR_RETURN(blackhawk_phy_firmware_load_info_get(&phy_access, &info)); 331 332 switch(init_config->firmware_load_method){ 333 case phymodFirmwareLoadMethodInternal: 334 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_ucode_mdio_load(&core_copy.access, info.ucode_ptr, info.ucode_len)); 335 break; 336 case phymodFirmwareLoadMethodExternal: 337 if(!PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 338 PHYMOD_NULL_CHECK(init_config->firmware_loader); 339 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_ucode_init(&core_copy.access)); 340 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 341 wait = 0; 342 } else { 343 wait = 1; 344 } 345 PHYMOD_IF_ERR_RETURN 346 (blackhawk_pram_firmware_enable(&core_copy.access, 1, wait)); 347 348 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 349 return PHYMOD_E_NONE; 350 } 351 352 PHYMOD_IF_ERR_RETURN(init_config->firmware_loader(core, info.ucode_len, info.ucode_ptr)); 353 } 354 PHYMOD_IF_ERR_RETURN 355 (blackhawk_pram_firmware_enable(&core_copy.access, 0, 0)); 356 break; 357 case phymodFirmwareLoadMethodNone: 358 break; 359 default: 360 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), init_config->firmware_load_method)); 361 } 362 363 return PHYMOD_E_NONE; 364 365 } 366 367 int blackhawk_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_config) 368 { 369 struct blackhawk_tsc_uc_core_config_st serdes_firmware_core_config; 370 uint32_t is_write_disabled; 371 phymod_phy_access_t pm_phy_copy; 372 373 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 374 375 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy->access, &is_write_disabled)); 376 if (is_write_disabled){ 377 return PHYMOD_E_NONE; 378 } 379 380 PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config)); 381 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_set_core_config_from_pcs(&pm_phy_copy.access, fw_config.CoreConfigFromPCS)); 382 383 return PHYMOD_E_NONE; 384 } 385 386 387 int blackhawk_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_config) 388 { 389 /* this function is not supported on BH */ 390 PHYMOD_DEBUG_ERROR(("Unsupported feature in BH \n")); 391 return PHYMOD_E_UNAVAIL; 392 } 393 394 395 int blackhawk_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config) 396 { 397 struct blackhawk_tsc_uc_lane_config_st lane_config; 398 phymod_phy_access_t pm_phy_copy; 399 400 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 401 402 PHYMOD_MEMSET(&lane_config, 0x0, sizeof(lane_config)); 403 PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config)); 404 405 PHYMOD_IF_ERR_RETURN 406 (blackhawk_tsc_get_uc_lane_cfg(&pm_phy_copy.access, &lane_config)); 407 408 fw_config->LaneConfigFromPCS = lane_config.field.lane_cfg_from_pcs; 409 fw_config->AnEnabled = lane_config.field.an_enabled; 410 fw_config->DfeOn = lane_config.field.dfe_on; 411 fw_config->LpDfeOn = lane_config.field.dfe_lp_mode; 412 fw_config->ForceBrDfe = lane_config.field.force_brdfe_on; 413 fw_config->MediaType = lane_config.field.media_type; 414 fw_config->UnreliableLos = lane_config.field.unreliable_los; 415 fw_config->Cl72AutoPolEn = lane_config.field.cl72_auto_polarity_en; 416 fw_config->ScramblingDisable = lane_config.field.scrambling_dis; 417 fw_config->Cl72RestTO = lane_config.field.cl72_restart_timeout_en; 418 fw_config->ForceExtenedReach = lane_config.field.force_es; 419 fw_config->ForceNormalReach = lane_config.field.force_ns; 420 fw_config->LpPrecoderEnabled = lane_config.field.lp_has_prec_en; 421 fw_config->ForcePAM4Mode = lane_config.field.force_pam4_mode; 422 fw_config->ForceNRZMode = lane_config.field.force_nrz_mode; 423 424 return PHYMOD_E_NONE; 425 } 426 427 int blackhawk_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 428 { 429 phymod_phy_access_t phy_copy; 430 int start_lane, num_lane, i; 431 enum blackhawk_tsc_txfir_tap_enable_enum enable_taps = NRZ_6TAP; 432 433 PHYMOD_IF_ERR_RETURN 434 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 435 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 436 437 PHYMOD_IF_ERR_RETURN 438 (blackhawk_lane_soft_reset(&phy_copy.access, 1)); 439 440 for (i = 0; i < num_lane; i++) { 441 phy_copy.access.lane_mask = 1 << (start_lane + i); 442 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 443 continue; 444 } 445 /*next check 3 tap mode or 6 tap mode */ 446 if (tx->tap_mode == phymodTxTapMode3Tap) { 447 if (tx->sig_method == phymodSignallingMethodNRZ) { 448 enable_taps= NRZ_LP_3TAP; 449 } else { 450 enable_taps= PAM4_LP_3TAP; 451 } 452 PHYMOD_PMD_IF_ERR_RETURN 453 (blackhawk_tsc_apply_txfir_cfg(&phy_copy.access, 454 enable_taps, 455 0, 456 tx->pre, 457 tx->main, 458 tx->post, 459 0, 460 0)); 461 } else { 462 if (tx->sig_method == phymodSignallingMethodNRZ) { 463 enable_taps= NRZ_6TAP; 464 } else { 465 enable_taps= PAM4_6TAP; 466 } 467 PHYMOD_PMD_IF_ERR_RETURN 468 (blackhawk_tsc_apply_txfir_cfg(&phy_copy.access, 469 enable_taps, 470 tx->pre2, 471 tx->pre, 472 tx->main, 473 tx->post, 474 tx->post2, 475 tx->post3)); 476 } 477 } 478 479 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 480 PHYMOD_IF_ERR_RETURN 481 (blackhawk_lane_soft_reset(&phy_copy.access, 0)); 482 483 return PHYMOD_E_NONE; 484 } 485 486 int blackhawk_phy_media_type_tx_get(const phymod_phy_access_t* phy, phymod_media_typed_t media, phymod_tx_t* tx) 487 { 488 489 return PHYMOD_E_NONE; 490 491 492 } 493 494 /* 495 * set lane swapping for core 496 */ 497 498 int blackhawk_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map) 499 { 500 phymod_core_access_t core_copy; 501 uint8_t pmd_tx_addr[8], pmd_rx_addr[8]; 502 int i = 0; 503 uint8_t tmp_phy_lane; 504 505 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 506 core_copy.access.lane_mask = 0x1; 507 508 /*next get the lane map into serdes spi format */ 509 for (i = 0; i < BLACKHAWK_NOF_LANES_IN_CORE; i++) { 510 tmp_phy_lane = (uint8_t) lane_map->lane_map_tx[i]; 511 pmd_tx_addr[tmp_phy_lane] = i; 512 tmp_phy_lane = (uint8_t) lane_map->lane_map_rx[i]; 513 pmd_rx_addr[tmp_phy_lane] = i; 514 } 515 516 PHYMOD_IF_ERR_RETURN 517 (blackhawk_tsc_map_lanes(&core_copy.access, 518 BLACKHAWK_NOF_LANES_IN_CORE, 519 pmd_tx_addr, 520 pmd_rx_addr)); 521 522 return PHYMOD_E_NONE; 523 } 524 525 int _blackhawk_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 526 { 527 uint32_t is_warm_boot; 528 struct blackhawk_tsc_uc_lane_config_st serdes_firmware_config; 529 phymod_phy_access_t phy_copy; 530 531 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 532 533 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 534 serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS; 535 serdes_firmware_config.field.an_enabled = fw_config.AnEnabled; 536 serdes_firmware_config.field.dfe_on = fw_config.DfeOn; 537 serdes_firmware_config.field.force_brdfe_on = fw_config.ForceBrDfe; 538 /* serdes_firmware_config.field.cl72_emulation_en = fw_config.Cl72Enable; */ 539 serdes_firmware_config.field.scrambling_dis = fw_config.ScramblingDisable; 540 serdes_firmware_config.field.unreliable_los = fw_config.UnreliableLos; 541 serdes_firmware_config.field.media_type = fw_config.MediaType; 542 serdes_firmware_config.field.dfe_lp_mode = fw_config.LpDfeOn; 543 serdes_firmware_config.field.cl72_auto_polarity_en = fw_config.Cl72AutoPolEn; 544 serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO; 545 serdes_firmware_config.field.force_es = fw_config.ForceExtenedReach; 546 serdes_firmware_config.field.force_ns = fw_config.ForceNormalReach; 547 serdes_firmware_config.field.force_nrz_mode = fw_config.ForceNRZMode; 548 serdes_firmware_config.field.force_pam4_mode = fw_config.ForcePAM4Mode; 549 serdes_firmware_config.field.lp_has_prec_en = fw_config.LpPrecoderEnabled; 550 551 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy->access, &is_warm_boot)); 552 553 if(!is_warm_boot) { 554 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_set_uc_lane_cfg(&phy_copy.access, serdes_firmware_config)); 555 } 556 return PHYMOD_E_NONE; 557 } 558 559 int blackhawk_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 560 { 561 phymod_phy_access_t phy_copy; 562 int start_lane, num_lane, i; 563 564 PHYMOD_IF_ERR_RETURN 565 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 566 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 567 568 PHYMOD_IF_ERR_RETURN 569 (blackhawk_lane_soft_reset(&phy_copy.access, 1)); 570 571 for (i = 0; i < num_lane; i++) { 572 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 573 continue; 574 } 575 phy_copy.access.lane_mask = 1 << (start_lane + i); 576 PHYMOD_IF_ERR_RETURN 577 (_blackhawk_phy_firmware_lane_config_set(&phy_copy, fw_config)); 578 } 579 580 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 581 PHYMOD_IF_ERR_RETURN 582 (blackhawk_lane_soft_reset(&phy_copy.access, 0)); 583 584 return PHYMOD_E_NONE; 585 } 586 587 588 /* reset rx sequencer 589 * flags - unused parameter 590 */ 591 int blackhawk_phy_rx_restart(const phymod_phy_access_t* phy) 592 { 593 phymod_phy_access_t phy_copy; 594 int start_lane, num_lane, i; 595 596 PHYMOD_IF_ERR_RETURN 597 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 598 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 599 600 PHYMOD_IF_ERR_RETURN 601 (blackhawk_lane_soft_reset(&phy_copy.access, 1)); 602 603 for (i = 0; i < num_lane; i++) { 604 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 605 continue; 606 } 607 phy_copy.access.lane_mask = 1 << (start_lane + i); 608 PHYMOD_IF_ERR_RETURN 609 (blackhawk_tsc_rx_restart(&phy_copy.access, 1)); 610 } 611 612 PHYMOD_USLEEP(1000); 613 614 for (i = 0; i < num_lane; i++) { 615 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 616 continue; 617 } 618 phy_copy.access.lane_mask = 1 << (start_lane + i); 619 PHYMOD_IF_ERR_RETURN 620 (blackhawk_tsc_rx_restart(&phy_copy.access, 0)); 621 } 622 623 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 624 PHYMOD_IF_ERR_RETURN 625 (blackhawk_lane_soft_reset(&phy_copy.access, 0)); 626 627 return PHYMOD_E_NONE; 628 } 629 630 631 int blackhawk_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 632 { 633 phymod_phy_access_t phy_copy; 634 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 635 636 PHYMOD_IF_ERR_RETURN 637 (blackhawk_tx_rx_polarity_set(&phy_copy.access, polarity->tx_polarity, polarity->rx_polarity)); 638 639 return PHYMOD_E_NONE; 640 } 641 642 643 int blackhawk_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 644 { 645 phymod_phy_access_t phy_copy; 646 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 647 648 PHYMOD_IF_ERR_RETURN 649 (blackhawk_tx_rx_polarity_get(&phy_copy.access, &polarity->tx_polarity, &polarity->rx_polarity)); 650 651 return PHYMOD_E_NONE; 652 } 653 654 int blackhawk_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 655 { 656 uint8_t pmd_tx_tap_mode; 657 int16_t val; 658 uint16_t tx_tap_nrz_mode = 0; 659 phymod_phy_access_t phy_copy; 660 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 661 662 663 /* read current tx tap mode */ 664 PHYMOD_IF_ERR_RETURN 665 (blackhawk_tsc_tx_tap_mode_get(&phy_copy.access, &pmd_tx_tap_mode)); 666 667 /*read current tx NRZ mode control info */ 668 PHYMOD_IF_ERR_RETURN 669 (blackhawk_tsc_tx_nrz_mode_get(&phy_copy.access, &tx_tap_nrz_mode)); 670 671 if (pmd_tx_tap_mode == 0) { 672 /* 3 tap mode */ 673 tx->tap_mode = phymodTxTapMode3Tap; 674 } else { 675 tx->tap_mode = phymodTxTapMode6Tap; 676 } 677 678 if (tx_tap_nrz_mode) { 679 tx->sig_method = phymodSignallingMethodNRZ; 680 } else { 681 tx->sig_method = phymodSignallingMethodPAM4; 682 } 683 684 /*next check 3 tap mode or 6 tap mode */ 685 if (tx->tap_mode == phymodTxTapMode3Tap) { 686 PHYMOD_IF_ERR_RETURN 687 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP0, &val)); 688 tx->pre = val; 689 PHYMOD_IF_ERR_RETURN 690 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP1, &val)); 691 tx->main = val; 692 PHYMOD_IF_ERR_RETURN 693 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP2, &val)); 694 tx->post = val; 695 tx->pre2 = 0; 696 tx->post2 = 0; 697 tx->post3 = 0; 698 } else { 699 PHYMOD_IF_ERR_RETURN 700 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP0, &val)); 701 tx->pre2 = val; 702 PHYMOD_IF_ERR_RETURN 703 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP1, &val)); 704 tx->pre = val; 705 PHYMOD_IF_ERR_RETURN 706 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP2, &val)); 707 tx->main = val; 708 PHYMOD_IF_ERR_RETURN 709 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP3, &val)); 710 tx->post = val; 711 PHYMOD_IF_ERR_RETURN 712 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP4, &val)); 713 tx->post2 = val; 714 PHYMOD_IF_ERR_RETURN 715 (blackhawk_tsc_read_tx_afe(&phy_copy.access, TX_AFE_TAP5, &val)); 716 tx->post3 = val; 717 } 718 719 720 return PHYMOD_E_NONE; 721 } 722 723 724 725 int blackhawk_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override) 726 { 727 phymod_phy_access_t phy_copy; 728 int start_lane, num_lane, i; 729 730 PHYMOD_IF_ERR_RETURN 731 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 732 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 733 734 PHYMOD_IF_ERR_RETURN 735 (blackhawk_lane_soft_reset(&phy_copy.access, 1)); 736 737 for (i = 0; i < num_lane; i++) { 738 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 739 continue; 740 } 741 phy_copy.access.lane_mask = 1 << (start_lane + i); 742 PHYMOD_IF_ERR_RETURN 743 (blackhawk_tsc_tx_pi_freq_override(&phy_copy.access, 744 tx_override->phase_interpolator.enable, 745 tx_override->phase_interpolator.value)); 746 } 747 748 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 749 PHYMOD_IF_ERR_RETURN 750 (blackhawk_lane_soft_reset(&phy_copy.access, 0)); 751 752 return PHYMOD_E_NONE; 753 } 754 755 int blackhawk_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override) 756 { 757 phymod_phy_access_t phy_copy; 758 int16_t value; 759 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 760 761 PHYMOD_IF_ERR_RETURN 762 (blackhawk_tx_pi_control_get(&phy_copy.access, &value)); 763 764 tx_override->phase_interpolator.value = (int32_t) value; 765 766 return PHYMOD_E_NONE; 767 } 768 769 770 int blackhawk_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 771 { 772 phymod_phy_access_t phy_copy; 773 int start_lane, num_lane, i; 774 uint8_t uc_lane_stopped; 775 phymod_phy_signalling_method_t signalling_mode; 776 777 PHYMOD_IF_ERR_RETURN 778 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 779 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 780 781 /* next read the PAM4 mode or not */ 782 PHYMOD_IF_ERR_RETURN 783 (blackhawk_tsc_signalling_mode_status_get(&phy_copy.access, &signalling_mode)); 784 785 for (i = 0; i < num_lane; i++) { 786 int j = 0; 787 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 788 continue; 789 } 790 phy_copy.access.lane_mask = 1 << (start_lane + i); 791 /* first check if uc lane is stopped already */ 792 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_stop_uc_lane_status(&phy_copy.access, &uc_lane_stopped)); 793 if (!uc_lane_stopped) { 794 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_stop_rx_adaptation(&phy_copy.access, 1)); 795 } 796 797 PHYMOD_PMD_IF_ERR_RETURN 798 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_VGA, (int8_t) rx->vga.value)); 799 800 PHYMOD_PMD_IF_ERR_RETURN 801 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_PF, (int8_t) rx->peaking_filter.value)); 802 803 PHYMOD_PMD_IF_ERR_RETURN 804 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_PF2, (int8_t) rx->low_freq_peaking_filter.value)); 805 806 /* next check the peaking value */ 807 PHYMOD_PMD_IF_ERR_RETURN 808 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_PF3, (int8_t) rx->high_freq_peaking_filter.value)); 809 810 for (j = 0 ; j < rx->num_of_dfe_taps ; j++){ 811 switch (j) { 812 case 0: 813 if (signalling_mode == phymodSignallingMethodNRZ) { 814 PHYMOD_PMD_IF_ERR_RETURN 815 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE1, (int8_t) rx->dfe[j].value)); 816 } else { 817 if (rx->dfe[0].enable) { 818 PHYMOD_DEBUG_ERROR(("ERROR :: DFE1 is not supported on PAM4 mode \n")); 819 return PHYMOD_E_PARAM; 820 } 821 } 822 break; 823 case 1: 824 PHYMOD_PMD_IF_ERR_RETURN 825 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE2, (int8_t) rx->dfe[j].value)); 826 break; 827 case 2: 828 PHYMOD_PMD_IF_ERR_RETURN 829 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE3, (int8_t) rx->dfe[j].value)); 830 break; 831 case 3: 832 PHYMOD_PMD_IF_ERR_RETURN 833 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE4, (int8_t) rx->dfe[j].value)); 834 break; 835 case 4: 836 PHYMOD_PMD_IF_ERR_RETURN 837 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE5, (int8_t) rx->dfe[j].value)); 838 break; 839 case 5: 840 PHYMOD_PMD_IF_ERR_RETURN 841 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE6, (int8_t) rx->dfe[j].value)); 842 break; 843 case 6: 844 PHYMOD_PMD_IF_ERR_RETURN 845 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE7, (int8_t) rx->dfe[j].value)); 846 break; 847 case 7: 848 PHYMOD_PMD_IF_ERR_RETURN 849 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE8, (int8_t) rx->dfe[j].value)); 850 break; 851 case 8: 852 PHYMOD_PMD_IF_ERR_RETURN 853 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE9, (int8_t) rx->dfe[j].value)); 854 break; 855 case 9: 856 PHYMOD_PMD_IF_ERR_RETURN 857 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE10, (int8_t) rx->dfe[j].value)); 858 break; 859 case 10: 860 PHYMOD_PMD_IF_ERR_RETURN 861 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE11,(int8_t) rx->dfe[j].value)); 862 break; 863 case 11: 864 PHYMOD_PMD_IF_ERR_RETURN 865 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE12, (int8_t) rx->dfe[j].value)); 866 break; 867 case 12: 868 PHYMOD_PMD_IF_ERR_RETURN 869 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE13, (int8_t) rx->dfe[j].value)); 870 break; 871 case 13: 872 PHYMOD_PMD_IF_ERR_RETURN 873 (blackhawk_tsc_write_rx_afe(&phy_copy.access, RX_AFE_DFE14, (int8_t) rx->dfe[j].value)); 874 break; 875 default: 876 return PHYMOD_E_PARAM; 877 } 878 } 879 } 880 881 return PHYMOD_E_NONE; 882 } 883 884 885 int blackhawk_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 886 { 887 int j; 888 int8_t val; 889 phymod_phy_access_t phy_copy; 890 phymod_phy_signalling_method_t signalling_mode; 891 892 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 893 /* next read the PAM4 mode or not */ 894 PHYMOD_IF_ERR_RETURN 895 (blackhawk_tsc_signalling_mode_status_get(&phy_copy.access, &signalling_mode)); 896 897 PHYMOD_IF_ERR_RETURN 898 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_VGA, &val)); 899 rx->vga.value = val; 900 PHYMOD_IF_ERR_RETURN 901 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_PF, &val)); 902 rx->peaking_filter.value = val; 903 PHYMOD_IF_ERR_RETURN 904 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_PF2, &val)); 905 rx->low_freq_peaking_filter.value = val; 906 PHYMOD_IF_ERR_RETURN 907 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_PF3, &val)); 908 rx->high_freq_peaking_filter.value = val; 909 910 rx->num_of_dfe_taps = 14; 911 912 for (j = 0 ; j < rx->num_of_dfe_taps ; j++){ 913 switch (j) { 914 case 0: 915 if (signalling_mode == phymodSignallingMethodNRZ) { 916 PHYMOD_IF_ERR_RETURN 917 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE1, &val)); 918 rx->dfe[0].enable = 1; 919 } else { 920 /* for PAM4 mode, DFE1 tap is not supported */ 921 rx->dfe[0].enable = 0; 922 } 923 break; 924 case 1: 925 PHYMOD_IF_ERR_RETURN 926 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE2, &val)); 927 break; 928 case 2: 929 PHYMOD_IF_ERR_RETURN 930 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE3, &val)); 931 break; 932 case 3: 933 PHYMOD_IF_ERR_RETURN 934 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE4, &val)); 935 break; 936 case 4: 937 PHYMOD_IF_ERR_RETURN 938 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE5, &val)); 939 break; 940 case 5: 941 PHYMOD_IF_ERR_RETURN 942 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE6, &val)); 943 break; 944 case 6: 945 PHYMOD_IF_ERR_RETURN 946 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE7, &val)); 947 break; 948 case 7: 949 PHYMOD_IF_ERR_RETURN 950 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE8, &val)); 951 break; 952 case 8: 953 PHYMOD_IF_ERR_RETURN 954 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE9, &val)); 955 break; 956 case 9: 957 PHYMOD_IF_ERR_RETURN 958 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE10, &val)); 959 break; 960 case 10: 961 PHYMOD_IF_ERR_RETURN 962 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE11, &val)); 963 break; 964 case 11: 965 PHYMOD_IF_ERR_RETURN 966 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE12, &val)); 967 break; 968 case 12: 969 PHYMOD_IF_ERR_RETURN 970 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE13, &val)); 971 break; 972 case 13: 973 PHYMOD_IF_ERR_RETURN 974 (blackhawk_tsc_read_rx_afe(&phy_copy.access, RX_AFE_DFE14, &val)); 975 break; 976 default: 977 return PHYMOD_E_PARAM; 978 } 979 rx->dfe[j].value = val; 980 } 981 982 for (j = 1 ; j < rx->num_of_dfe_taps ; j++){ 983 rx->dfe[j].enable = 1; 984 } 985 rx->vga.enable = 1; 986 rx->peaking_filter.enable = 1; 987 rx->low_freq_peaking_filter.enable = 1; 988 rx->high_freq_peaking_filter.enable = 1; 989 990 return PHYMOD_E_NONE; 991 } 992 993 994 int blackhawk_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 995 { 996 997 return PHYMOD_E_UNAVAIL; 998 } 999 1000 1001 int blackhawk_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 1002 { 1003 1004 return PHYMOD_E_UNAVAIL; 1005 1006 } 1007 1008 1009 int blackhawk_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power) 1010 { 1011 phymod_phy_access_t pm_phy_copy; 1012 1013 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1014 1015 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) { 1016 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_lane_pwrdn(&pm_phy_copy.access, PWRDN)); 1017 } else if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) { 1018 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_lane_pwrdn(&pm_phy_copy.access, PWR_ON)); 1019 } else if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOn)) { 1020 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_lane_pwrdn(&pm_phy_copy.access, PWRDN_TX)); 1021 } else if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOff)) { 1022 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_lane_pwrdn(&pm_phy_copy.access, PWRDN_RX)); 1023 } else { 1024 return PHYMOD_E_CONFIG; 1025 } 1026 1027 return PHYMOD_E_NONE; 1028 } 1029 1030 int blackhawk_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 1031 { 1032 return PHYMOD_E_UNAVAIL; 1033 } 1034 1035 int blackhawk_phy_speed_config_set(const phymod_phy_access_t* phy, 1036 const phymod_phy_speed_config_t* speed_config, 1037 const phymod_phy_pll_state_t* old_pll_state, 1038 phymod_phy_pll_state_t* new_pll_state) 1039 { 1040 uint32_t pll_0_is_free, pll_1_is_free; 1041 uint32_t pll_0_is_pwrdn, pll_1_is_pwrdn; 1042 phymod_phy_access_t pm_phy_copy; 1043 uint32_t pll_0_div = 0, pll_1_div = 0, request_pll_div, pll_index = 0; 1044 uint32_t is_pam4, osr_mode; 1045 uint32_t loss_in_db; 1046 int i, start_lane, num_lane, ref_clk_is_156p25 = 0; 1047 phymod_firmware_lane_config_t firmware_lane_config; 1048 phymod_firmware_core_config_t firmware_core_config; 1049 1050 firmware_lane_config = speed_config->pmd_lane_config; 1051 ref_clk_is_156p25 = PHYMOD_SPEED_CONFIG_REF_CLK_IS_156P25MHZ_GET(speed_config); 1052 1053 PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config)); 1054 1055 /* first copy the PLL state */ 1056 *new_pll_state = *old_pll_state; 1057 1058 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1059 PHYMOD_IF_ERR_RETURN 1060 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1061 1062 /* first check if any PLL is free */ 1063 if (old_pll_state->pll0_lanes_bitmap) { 1064 pll_0_is_free = 0; 1065 } else { 1066 pll_0_is_free = 1; 1067 } 1068 1069 if (old_pll_state->pll1_lanes_bitmap) { 1070 pll_1_is_free = 0; 1071 } else { 1072 pll_1_is_free = 1; 1073 } 1074 1075 /* Check if PLLs are power down */ 1076 pm_phy_copy.access.pll_idx = 0; 1077 PHYMOD_IF_ERR_RETURN 1078 (blackhawk_tsc_pll_pwrdn_get(&pm_phy_copy.access, &pll_0_is_pwrdn)); 1079 1080 pm_phy_copy.access.pll_idx = 1; 1081 PHYMOD_IF_ERR_RETURN 1082 (blackhawk_tsc_pll_pwrdn_get(&pm_phy_copy.access, &pll_1_is_pwrdn)); 1083 1084 /* get the VCO if PLL0 is active */ 1085 if (!pll_0_is_pwrdn) { 1086 pm_phy_copy.access.pll_idx = 0; 1087 PHYMOD_IF_ERR_RETURN 1088 (blackhawk_tsc_INTERNAL_read_pll_div(&pm_phy_copy.access, &pll_0_div)); 1089 } 1090 1091 if (!pll_1_is_pwrdn) { 1092 pm_phy_copy.access.pll_idx = 1; 1093 PHYMOD_IF_ERR_RETURN 1094 (blackhawk_tsc_INTERNAL_read_pll_div(&pm_phy_copy.access, &pll_1_div)); 1095 } 1096 1097 /* next check the request speed VCO */ 1098 PHYMOD_IF_ERR_RETURN 1099 (blackhawk_speed_config_get(speed_config->data_rate, ref_clk_is_156p25, &request_pll_div, &is_pam4, &osr_mode)); 1100 1101 /* first assert the ln dp reset */ 1102 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1103 PHYMOD_IF_ERR_RETURN 1104 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 1)); 1105 1106 /* first to check if any PLL is free and needs to configured */ 1107 if ( ((pll_0_is_free) && (pll_1_is_free)) || 1108 ((pll_0_is_free) && (pll_1_div != request_pll_div)) || 1109 ((pll_1_is_free) && (pll_0_div != request_pll_div)) ) { 1110 /*choose the the right PLL to config */ 1111 if (PHYMOD_SPEED_CONFIG_ONLY_PLL0_IS_ACTIVE_GET(speed_config)) 1112 { 1113 pll_index = 0; 1114 } 1115 else 1116 { 1117 pll_index = (pll_1_is_free)? 1 : 0; 1118 } 1119 pm_phy_copy.access.pll_idx = pll_index; 1120 1121 if (((pll_index == 0) && pll_0_is_pwrdn) || ((pll_index == 1) && pll_1_is_pwrdn)) { 1122 /* Power up PLL */ 1123 PHYMOD_IF_ERR_RETURN 1124 (blackhawk_tsc_core_pwrdn(&pm_phy_copy.access, PWR_ON)); 1125 } 1126 1127 /*toggle core dp reset */ 1128 pm_phy_copy.access.lane_mask = 0x1; 1129 PHYMOD_IF_ERR_RETURN 1130 (blackhawk_tsc_core_dp_reset(&pm_phy_copy.access, 1)); 1131 1132 /*config the PLL to the requested VCO */ 1133 if (ref_clk_is_156p25) { 1134 PHYMOD_IF_ERR_RETURN 1135 (blackhawk_tsc_configure_pll_refclk_div(&pm_phy_copy.access, 1136 BLACKHAWK_TSC_PLL_REFCLK_156P25MHZ, 1137 request_pll_div)); 1138 } else { 1139 PHYMOD_IF_ERR_RETURN 1140 (blackhawk_tsc_configure_pll_refclk_div(&pm_phy_copy.access, 1141 BLACKHAWK_TSC_PLL_REFCLK_312P5MHZ, 1142 request_pll_div)); 1143 } 1144 1145 /* release core soft reset */ 1146 PHYMOD_IF_ERR_RETURN 1147 (blackhawk_tsc_core_dp_reset(&pm_phy_copy.access, 0)); 1148 1149 } else if ( ((pll_0_is_free) && (pll_1_div == request_pll_div)) || 1150 ((pll_1_is_free) && (pll_0_div == request_pll_div)) ) { 1151 pll_index = (pll_0_div == request_pll_div)? 0 : 1; 1152 } else if ((!pll_0_is_free) && (!pll_1_is_free)) { 1153 /*next if both pll0 and ppl1 are active and the new speed can be 1154 supported with existing VCO */ 1155 if ((pll_0_div == request_pll_div) || (pll_1_div == request_pll_div)) { 1156 1157 pll_index = (pll_0_div == request_pll_div)? 0 : 1; 1158 } 1159 } else { 1160 /*this speed request can not be configured */ 1161 PHYMOD_DEBUG_ERROR(("ERROR :: this speed can not be configured \n")); 1162 return PHYMOD_E_CONFIG; 1163 } 1164 1165 /* choose the right pll index for the port */ 1166 for (i = 0; i < num_lane; i++) { 1167 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1168 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1169 continue; 1170 } 1171 PHYMOD_IF_ERR_RETURN 1172 (blackhawk_lane_pll_selection_set(&pm_phy_copy.access, pll_index)); 1173 } 1174 1175 /* config oversample for each lane */ 1176 for (i = 0; i < num_lane; i++) { 1177 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1178 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1179 continue; 1180 } 1181 PHYMOD_IF_ERR_RETURN 1182 (blackhawk_osr_mode_set(&pm_phy_copy.access, osr_mode)); 1183 } 1184 1185 /*next need to set certain firmware lane config to be zero*/ 1186 firmware_lane_config.LaneConfigFromPCS = 0; 1187 firmware_lane_config.AnEnabled = 0; 1188 1189 for (i = 0; i < num_lane; i++) { 1190 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1191 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1192 continue; 1193 } 1194 PHYMOD_IF_ERR_RETURN 1195 (_blackhawk_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 1196 } 1197 1198 /* if the PAM4 mode, need to program the channel loss. In NRZ mode it is zeroed. */ 1199 loss_in_db = firmware_lane_config.ForcePAM4Mode? speed_config->PAM4_channel_loss : 0; 1200 for (i = 0; i < num_lane; i++) { 1201 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1202 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1203 continue; 1204 } 1205 PHYMOD_IF_ERR_RETURN 1206 (blackhawk_channel_loss_set(&pm_phy_copy.access, loss_in_db)); 1207 } 1208 1209 /* next need to enable/disable link training based on the input */ 1210 for (i = 0; i < num_lane; i++) { 1211 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1212 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1213 continue; 1214 } 1215 PHYMOD_IF_ERR_RETURN 1216 (blackhawk_clause72_control(&pm_phy_copy.access, speed_config->linkTraining)); 1217 } 1218 1219 /* next release the ln dp reset */ 1220 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1221 PHYMOD_IF_ERR_RETURN 1222 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 0)); 1223 1224 /* first clear the current lane _mask from both */ 1225 new_pll_state->pll1_lanes_bitmap &= ~(phy->access.lane_mask); 1226 new_pll_state->pll0_lanes_bitmap &= ~(phy->access.lane_mask); 1227 1228 /* need to update the pll_state */ 1229 if (pll_index) { 1230 new_pll_state->pll1_lanes_bitmap |= phy->access.lane_mask; 1231 } else { 1232 new_pll_state->pll0_lanes_bitmap |= phy->access.lane_mask; 1233 } 1234 1235 return PHYMOD_E_NONE; 1236 } 1237 1238 int blackhawk_phy_speed_config_get(const phymod_phy_access_t* phy, phymod_phy_speed_config_t* speed_config) 1239 { 1240 int osr_mode = 0; 1241 uint32_t pll_div, vco_freq_khz, cl72_enable, channel_loss; 1242 uint32_t pll_index; 1243 phymod_phy_access_t phy_copy; 1244 phymod_firmware_lane_config_t firmware_lane_config; 1245 int start_lane, num_lane, ref_clk_is_156p25 = 0; 1246 1247 /* first get the ref clock */ 1248 ref_clk_is_156p25 = PHYMOD_SPEED_CONFIG_REF_CLK_IS_156P25MHZ_GET(speed_config); 1249 1250 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1251 PHYMOD_IF_ERR_RETURN 1252 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1253 phy_copy.access.lane_mask = 0x1 << start_lane; 1254 1255 /*first figure out which pll the current port is using */ 1256 PHYMOD_IF_ERR_RETURN 1257 (blackhawk_lane_pll_selection_get(&phy_copy.access, &pll_index)); 1258 1259 phy_copy.access.pll_idx = pll_index; 1260 /* get the PLL div from HW */ 1261 PHYMOD_IF_ERR_RETURN 1262 (blackhawk_tsc_INTERNAL_read_pll_div(&phy_copy.access, &pll_div)); 1263 1264 /* both 312.5M and 156.25M ref clock will be supported used for DNX device */ 1265 if (ref_clk_is_156p25) { 1266 PHYMOD_IF_ERR_RETURN 1267 (blackhawk_tsc_get_vco_from_refclk_div(&phy_copy.access, REF_CLOCK_156P25_HZ, pll_div, &vco_freq_khz, 0)); 1268 } else { 1269 PHYMOD_IF_ERR_RETURN 1270 (blackhawk_tsc_get_vco_from_refclk_div(&phy_copy.access, REF_CLOCK_312P5_HZ, pll_div, &vco_freq_khz, 0)); 1271 } 1272 1273 PHYMOD_IF_ERR_RETURN 1274 (blackhawk_osr_mode_get(&phy_copy.access, &osr_mode)); 1275 1276 PHYMOD_IF_ERR_RETURN 1277 (blackhawk_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 1278 1279 speed_config->pmd_lane_config.AnEnabled = firmware_lane_config.AnEnabled; 1280 speed_config->pmd_lane_config.Cl72AutoPolEn = firmware_lane_config.Cl72AutoPolEn; 1281 speed_config->pmd_lane_config.Cl72RestTO = firmware_lane_config.Cl72RestTO; 1282 speed_config->pmd_lane_config.DfeOn = firmware_lane_config.DfeOn; 1283 speed_config->pmd_lane_config.ForceBrDfe = firmware_lane_config.ForceBrDfe; 1284 speed_config->pmd_lane_config.ForceExtenedReach = firmware_lane_config.ForceExtenedReach; 1285 speed_config->pmd_lane_config.ForceNormalReach = firmware_lane_config.ForceNormalReach; 1286 speed_config->pmd_lane_config.ForceNRZMode = firmware_lane_config.ForceNRZMode; 1287 speed_config->pmd_lane_config.ForcePAM4Mode = firmware_lane_config.ForcePAM4Mode; 1288 speed_config->pmd_lane_config.LaneConfigFromPCS = firmware_lane_config.LaneConfigFromPCS; 1289 speed_config->pmd_lane_config.LpDfeOn = firmware_lane_config.LpDfeOn; 1290 speed_config->pmd_lane_config.LpPrecoderEnabled = firmware_lane_config.LpPrecoderEnabled; 1291 speed_config->pmd_lane_config.MediaType = firmware_lane_config.MediaType; 1292 speed_config->pmd_lane_config.ScramblingDisable = firmware_lane_config.ScramblingDisable; 1293 speed_config->pmd_lane_config.UnreliableLos = firmware_lane_config.UnreliableLos; 1294 1295 /* next get the cl72 enable status */ 1296 PHYMOD_IF_ERR_RETURN 1297 (blackhawk_clause72_control_get(&phy_copy.access, &cl72_enable)); 1298 speed_config->linkTraining = cl72_enable; 1299 1300 1301 PHYMOD_IF_ERR_RETURN 1302 (blackhawk_channel_loss_get(&phy_copy.access, &channel_loss)); 1303 speed_config->PAM4_channel_loss = channel_loss; 1304 1305 /* next check if PAM4 mode enabled */ 1306 if (firmware_lane_config.ForcePAM4Mode) { 1307 speed_config->data_rate = (vco_freq_khz << 1) / 1000; 1308 } else { 1309 /* to get the over sample value */ 1310 if (osr_mode == 0) { 1311 speed_config->data_rate = (vco_freq_khz) / 1000; 1312 } else if(osr_mode == 1) { 1313 speed_config->data_rate = (vco_freq_khz >> 1) / 1000; 1314 } else if (osr_mode == 2) { 1315 speed_config->data_rate = (vco_freq_khz >> 2) / 1000; 1316 } 1317 } 1318 1319 return PHYMOD_E_NONE; 1320 } 1321 1322 1323 int blackhawk_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 1324 { 1325 int start_lane, num_lane, i; 1326 uint32_t lane_reset; 1327 phymod_phy_access_t pm_phy_copy; 1328 phymod_firmware_lane_config_t firmware_lane_config; 1329 1330 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1331 1332 PHYMOD_IF_ERR_RETURN 1333 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1334 1335 /*first check if lane is in reset */ 1336 PHYMOD_IF_ERR_RETURN 1337 (blackhawk_lane_soft_reset_get(&pm_phy_copy.access, &lane_reset)); 1338 1339 /* if lane is not in reset, then reset the lane first */ 1340 if (!lane_reset) { 1341 PHYMOD_IF_ERR_RETURN 1342 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 1)); 1343 } 1344 1345 /* next need to clear both force ER and NR config on the firmware lane config side 1346 if link training enable is passed*/ 1347 if (cl72_en) { 1348 PHYMOD_IF_ERR_RETURN 1349 (blackhawk_phy_firmware_lane_config_get(phy, &firmware_lane_config)); 1350 1351 firmware_lane_config.ForceNormalReach = 0; 1352 firmware_lane_config.ForceExtenedReach = 0; 1353 1354 PHYMOD_IF_ERR_RETURN 1355 (_blackhawk_phy_firmware_lane_config_set(phy, firmware_lane_config)); 1356 } 1357 for (i = 0; i < num_lane; i++) { 1358 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1359 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1360 continue; 1361 } 1362 PHYMOD_IF_ERR_RETURN 1363 (blackhawk_clause72_control(&pm_phy_copy.access, cl72_en)); 1364 } 1365 1366 /* release the ln dp reset */ 1367 if (!lane_reset) { 1368 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1369 PHYMOD_IF_ERR_RETURN 1370 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 0)); 1371 } 1372 1373 return PHYMOD_E_NONE; 1374 } 1375 1376 int blackhawk_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 1377 { 1378 phymod_phy_access_t pm_phy_copy; 1379 1380 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1381 1382 PHYMOD_IF_ERR_RETURN 1383 (blackhawk_clause72_control_get(&pm_phy_copy.access, cl72_en)); 1384 1385 return PHYMOD_E_NONE; 1386 } 1387 1388 1389 int blackhawk_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 1390 { 1391 int i; 1392 uint32_t tmp_status; 1393 int start_lane, num_lane; 1394 phymod_phy_access_t phy_copy; 1395 1396 1397 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1398 status->locked = 1; 1399 1400 /* next figure out the lane num and start_lane based on the input */ 1401 PHYMOD_IF_ERR_RETURN 1402 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1403 for (i = 0; i < num_lane; i++) { 1404 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1405 continue; 1406 } 1407 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1408 tmp_status = 1; 1409 PHYMOD_IF_ERR_RETURN(blackhawk_pmd_cl72_receiver_status(&phy_copy.access, &tmp_status)); 1410 if (tmp_status == 0) { 1411 status->locked = 0; 1412 return PHYMOD_E_NONE; 1413 } 1414 } 1415 return PHYMOD_E_NONE; 1416 } 1417 1418 int blackhawk_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 1419 { 1420 int i; 1421 int start_lane, num_lane; 1422 phymod_phy_access_t phy_copy; 1423 1424 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1425 1426 /* next figure out the lane num and start_lane based on the input */ 1427 PHYMOD_IF_ERR_RETURN 1428 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1429 1430 switch (loopback) { 1431 case phymodLoopbackGlobal : 1432 case phymodLoopbackGlobalPMD : 1433 for (i = 0; i < num_lane; i++) { 1434 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1435 continue; 1436 } 1437 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1438 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_dig_lpbk(&phy_copy.access, (uint8_t) enable)); 1439 PHYMOD_IF_ERR_RETURN(blackhawk_pmd_force_signal_detect(&phy_copy.access, (int) enable, (int) enable)); 1440 } 1441 break; 1442 case phymodLoopbackRemotePMD : 1443 for (i = 0; i < num_lane; i++) { 1444 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1445 continue; 1446 } 1447 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1448 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_rmt_lpbk(&phy_copy.access, (uint8_t)enable)); 1449 } 1450 break; 1451 case phymodLoopbackRemotePCS : 1452 default : 1453 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_UNAVAIL, 1454 (_PHYMOD_MSG("This mode is not supported\n"))); 1455 break; 1456 } 1457 return PHYMOD_E_NONE; 1458 } 1459 1460 int blackhawk_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 1461 { 1462 int start_lane, num_lane; 1463 phymod_phy_access_t phy_copy; 1464 1465 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1466 1467 /*next figure out the lane num and start_lane based on the input*/ 1468 PHYMOD_IF_ERR_RETURN 1469 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1470 1471 switch (loopback) { 1472 case phymodLoopbackGlobal : 1473 case phymodLoopbackGlobalPMD : 1474 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_dig_lpbk_get(&phy_copy.access, enable)); 1475 break; 1476 case phymodLoopbackRemotePMD : 1477 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_rmt_lpbk_get(&phy_copy.access, enable)); 1478 break; 1479 case phymodLoopbackRemotePCS : 1480 default : 1481 return PHYMOD_E_UNAVAIL; 1482 } 1483 return PHYMOD_E_NONE; 1484 } 1485 1486 int blackhawk_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 1487 { 1488 int rv; 1489 int lane = 0; 1490 int pll_index = 0, ref_clk_is_156p25 = 0; 1491 phymod_phy_access_t phy_access, phy_access_copy; 1492 phymod_core_access_t core_copy; 1493 phymod_firmware_core_config_t firmware_core_config_tmp; 1494 uint32_t uc_enable = 0, ams_version; 1495 phymod_polarity_t tmp_pol; 1496 ucode_info_t ucode; 1497 unsigned int blackhawk_ucode_len; 1498 unsigned char *blackhawk_ucode; 1499 unsigned short blackhawk_ucode_crc; 1500 1501 BLACKHAWK_CORE_TO_PHY_ACCESS(&phy_access, core); 1502 PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol)); 1503 phy_access_copy = phy_access; 1504 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 1505 core_copy.access.lane_mask = 0x1; 1506 phy_access_copy = phy_access; 1507 phy_access_copy.access = core->access; 1508 phy_access_copy.access.lane_mask = 0x1; 1509 phy_access_copy.type = core->type; 1510 1511 /*check the ref clk */ 1512 if (init_config->interface.ref_clock == phymodRefClk156Mhz) { 1513 ref_clk_is_156p25 = 1; 1514 } 1515 1516 /* Get ucode info */ 1517 PHYMOD_IF_ERR_RETURN( 1518 blackhawk_ams_version_get(&phy_access_copy.access, &ams_version)); 1519 if (ams_version < 0xc0) { 1520 ucode.stack_size = blackhawk_ucode_stack_size_rev0; 1521 ucode.ucode_size = blackhawk_ucode_len_rev0; 1522 blackhawk_ucode_len = blackhawk_ucode_len_rev0; 1523 blackhawk_ucode = blackhawk_ucode_rev0; 1524 blackhawk_ucode_crc = blackhawk_ucode_crc_rev0; 1525 } else { 1526 ucode.stack_size = blackhawk_ucode_stack_size_rev1; 1527 ucode.ucode_size = blackhawk_ucode_len_rev1; 1528 blackhawk_ucode_len = blackhawk_ucode_len_rev1; 1529 blackhawk_ucode = blackhawk_ucode_rev1; 1530 blackhawk_ucode_crc = blackhawk_ucode_crc_rev1; 1531 } 1532 ucode.crc_value = blackhawk_ucode_crc; 1533 1534 /* 1. De-assert PMD core power and core data path reset */ 1535 if(!PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 1536 PHYMOD_IF_ERR_RETURN 1537 (blackhawk_pmd_reset_seq(&core_copy.access, core_status->pmd_active)); 1538 1539 /*wait until com clk and ref clk is stable */ 1540 PHYMOD_USLEEP(1000); 1541 1542 /* De-assert PMD lane reset */ 1543 1544 for (lane = 0; lane < BLACKHAWK_NOF_LANES_IN_CORE; lane++) { 1545 phy_access_copy.access.lane_mask = 1 << lane; 1546 PHYMOD_IF_ERR_RETURN 1547 (blackhawk_lane_hard_soft_reset_release(&phy_access_copy.access, 0)); 1548 } 1549 1550 1551 for (lane = 0; lane < BLACKHAWK_NOF_LANES_IN_CORE; lane++) { 1552 phy_access_copy.access.lane_mask = 1 << lane; 1553 PHYMOD_IF_ERR_RETURN 1554 (blackhawk_lane_hard_soft_reset_release(&phy_access_copy.access, 1)); 1555 } 1556 1557 1558 PHYMOD_IF_ERR_RETURN 1559 (blackhawk_uc_active_get(&phy_access.access, &uc_enable)); 1560 if (uc_enable) return PHYMOD_E_NONE; 1561 1562 /* 2. Set the heart beat, default is for 156.25M */ 1563 if (init_config->interface.ref_clock != phymodRefClk156Mhz) { 1564 PHYMOD_IF_ERR_RETURN 1565 (blackhawk_refclk_set(&core_copy.access, init_config->interface.ref_clock)); 1566 } 1567 1568 /*now config the lane mapping*/ 1569 PHYMOD_IF_ERR_RETURN 1570 (blackhawk_core_lane_map_set(&core_copy, &init_config->lane_map)); 1571 1572 PHYMOD_IF_ERR_RETURN 1573 (blackhawk_tsc_uc_reset_with_info(&core_copy.access , 1, ucode)); 1574 } 1575 1576 rv = _blackhawk_core_firmware_load(&core_copy, init_config); 1577 1578 if (rv != PHYMOD_E_NONE) { 1579 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask)); 1580 PHYMOD_IF_ERR_RETURN(rv); 1581 } 1582 1583 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 1584 return PHYMOD_E_NONE; 1585 } 1586 1587 if (init_config->firmware_load_method != phymodFirmwareLoadMethodNone) { 1588 if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 1589 rv = blackhawk_tsc_ucode_load_verify(&core_copy.access, (uint8_t *) blackhawk_ucode, blackhawk_ucode_len); 1590 1591 if (rv != PHYMOD_E_NONE) { 1592 PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask)); 1593 PHYMOD_IF_ERR_RETURN(rv); 1594 } 1595 } 1596 } 1597 1598 /*next we need to check if the load is correct or not */ 1599 if(init_config->firmware_load_method != phymodFirmwareLoadMethodNone) { 1600 /*next we need to set the uc active and release uc */ 1601 PHYMOD_IF_ERR_RETURN 1602 (blackhawk_uc_active_set(&core_copy.access ,1)); 1603 1604 /*release the uc reset */ 1605 PHYMOD_IF_ERR_RETURN 1606 (blackhawk_tsc_uc_reset_with_info(&core_copy.access , 0, ucode)); 1607 1608 PHYMOD_IF_ERR_RETURN (blackhawk_tsc_wait_uc_active(&core_copy.access)); 1609 1610 for (lane = 0; lane < BLACKHAWK_NOF_LANES_IN_CORE; lane++) { 1611 phy_access_copy.access.lane_mask = 1 << lane; 1612 PHYMOD_IF_ERR_RETURN 1613 (blackhawk_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x1)); 1614 } 1615 1616 /* we need to wait at least 10ms for the uc to settle */ 1617 PHYMOD_USLEEP(10000); 1618 1619 /* 7. Initialize software information table for the micro */ 1620 PHYMOD_IF_ERR_RETURN 1621 (blackhawk_tsc_init_blackhawk_tsc_info(&core_copy.access)); 1622 1623 if(!PHYMOD_CORE_INIT_F_BYPASS_CRC_CHECK_GET(init_config)) { 1624 PHYMOD_IF_ERR_RETURN 1625 (blackhawk_tsc_check_ucode_crc(&core_copy.access, ucode.crc_value, 200)); 1626 } 1627 1628 for (lane = 0; lane < BLACKHAWK_NOF_LANES_IN_CORE; lane++) { 1629 phy_access_copy.access.lane_mask = 1 << lane; 1630 PHYMOD_IF_ERR_RETURN 1631 (blackhawk_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x0)); 1632 1633 } 1634 } 1635 else 1636 { 1637 PHYMOD_IF_ERR_RETURN 1638 (blackhawk_tsc_firmware_load_none_init_blackhawk_tsc_info(&core_copy.access)); 1639 } 1640 1641 /* AFE/PLL config */ 1642 if (init_config->afe_pll.afe_pll_change_default) { 1643 for (pll_index = 0; pll_index < 2; pll_index++) { 1644 core_copy.access.pll_idx = pll_index; 1645 PHYMOD_IF_ERR_RETURN 1646 (blackhawk_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 1647 } 1648 } 1649 1650 /* program the rx/tx polarity */ 1651 for (lane = 0; lane < BLACKHAWK_NOF_LANES_IN_CORE; lane++) { 1652 phy_access_copy.access.lane_mask = 1 << lane; 1653 tmp_pol.tx_polarity = (init_config->polarity_map.tx_polarity) >> lane & 0x1; 1654 tmp_pol.rx_polarity = (init_config->polarity_map.rx_polarity) >> lane & 0x1; 1655 PHYMOD_IF_ERR_RETURN 1656 (blackhawk_phy_polarity_set(&phy_access_copy, &tmp_pol)); 1657 /* clear the tmp vairiable */ 1658 PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol)); 1659 1660 } 1661 1662 /* default PLL config for both PLL0 and PLL1 plldiv*/ 1663 /* for now PLL0 will be set to 20.625G and PLL1 will be set to 25.78125G */ 1664 core_copy.access.pll_idx = 0; 1665 if (ref_clk_is_156p25) { 1666 PHYMOD_IF_ERR_RETURN 1667 (blackhawk_tsc_configure_pll_refclk_div(&core_copy.access, 1668 BLACKHAWK_TSC_PLL_REFCLK_156P25MHZ, 1669 init_config->pll0_div_init_value)); 1670 } else { 1671 PHYMOD_IF_ERR_RETURN 1672 (blackhawk_tsc_configure_pll_refclk_div(&core_copy.access, 1673 BLACKHAWK_TSC_PLL_REFCLK_312P5MHZ, 1674 init_config->pll0_div_init_value)); 1675 } 1676 1677 core_copy.access.pll_idx = 1; 1678 if (ref_clk_is_156p25) { 1679 PHYMOD_IF_ERR_RETURN 1680 (blackhawk_tsc_configure_pll_refclk_div(&core_copy.access, 1681 BLACKHAWK_TSC_PLL_REFCLK_156P25MHZ, 1682 init_config->pll1_div_init_value)); 1683 } else { 1684 PHYMOD_IF_ERR_RETURN 1685 (blackhawk_tsc_configure_pll_refclk_div(&core_copy.access, 1686 BLACKHAWK_TSC_PLL_REFCLK_312P5MHZ, 1687 init_config->pll1_div_init_value)); 1688 } 1689 1690 /*don't overide the fw that set in config set if not specified*/ 1691 firmware_core_config_tmp = init_config->firmware_core_config; 1692 firmware_core_config_tmp.CoreConfigFromPCS = 0; 1693 1694 PHYMOD_IF_ERR_RETURN 1695 (blackhawk_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp)); 1696 1697 1698 /* release core soft reset for both PLL's */ 1699 core_copy.access.lane_mask = 0x1; 1700 core_copy.access.pll_idx = 0; 1701 PHYMOD_IF_ERR_RETURN 1702 (blackhawk_tsc_core_dp_reset(&core_copy.access, 0)); 1703 core_copy.access.pll_idx = 1; 1704 PHYMOD_IF_ERR_RETURN 1705 (blackhawk_tsc_core_dp_reset(&core_copy.access, 0)); 1706 1707 return PHYMOD_E_NONE; 1708 } 1709 1710 int blackhawk_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 1711 { 1712 const phymod_access_t *pm_acc = &phy->access; 1713 phymod_phy_access_t pm_phy_copy; 1714 int start_lane, num_lane, i; 1715 int lane_bkup; 1716 phymod_firmware_lane_config_t firmware_lane_config; 1717 1718 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1719 1720 PHYMOD_IF_ERR_RETURN 1721 (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane)); 1722 /*per lane based dp reset release */ 1723 1724 lane_bkup = pm_phy_copy.access.lane_mask; 1725 1726 PHYMOD_IF_ERR_RETURN 1727 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 0)); 1728 1729 PHYMOD_IF_ERR_RETURN 1730 (blackhawk_lane_soft_reset(&pm_phy_copy.access, 1)); 1731 1732 pm_phy_copy.access.lane_mask = lane_bkup; 1733 1734 /* clearing all the lane config */ 1735 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 1736 1737 for (i = 0; i < num_lane; i++) { 1738 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1739 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1740 continue; 1741 } 1742 /* set tx parameters */ 1743 PHYMOD_IF_ERR_RETURN 1744 (blackhawk_phy_tx_set(&pm_phy_copy, &init_config->tx[i])); 1745 } 1746 1747 for (i = 0; i < num_lane; i++) { 1748 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1749 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1750 continue; 1751 } 1752 PHYMOD_IF_ERR_RETURN 1753 (blackhawk_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 1754 } 1755 1756 if(PHYMOD_PHY_INIT_F_ENABLE_PASS_THROUGH_CONFIGURATION_GET(init_config)) 1757 { 1758 for (i = 0; i < num_lane; i++) { 1759 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1760 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1761 continue; 1762 } 1763 PHYMOD_IF_ERR_RETURN 1764 (blackhawk_tsc_enable_pass_through_configuration(&pm_phy_copy.access, 1)); 1765 } 1766 } 1767 1768 return PHYMOD_E_NONE; 1769 1770 } 1771 1772 1773 /* this function gives the PMD_RX_LOCK_STATUS */ 1774 int blackhawk_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status) 1775 { 1776 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (blackhawk_phy_link_status_get) \n")); 1777 return PHYMOD_E_UNAVAIL; 1778 } 1779 1780 1781 int blackhawk_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* pmd_lock) 1782 { 1783 int start_lane, num_lane, i; 1784 phymod_phy_access_t pm_phy_copy; 1785 uint8_t tmp_lock; 1786 1787 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1788 *pmd_lock = 1; 1789 1790 PHYMOD_IF_ERR_RETURN 1791 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1792 1793 for (i = 0; i < num_lane; i++) { 1794 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1795 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1796 continue; 1797 } 1798 PHYMOD_IF_ERR_RETURN 1799 (blackhawk_tsc_pmd_lock_status(&pm_phy_copy.access, &tmp_lock)); 1800 *pmd_lock &= (uint32_t) tmp_lock; 1801 } 1802 return PHYMOD_E_NONE; 1803 1804 } 1805 1806 /* this function gives the PMD_RX_LOCK_STATUS */ 1807 int blackhawk_phy_rx_signal_detect_get(const phymod_phy_access_t* phy, uint32_t* signal_detect) 1808 { 1809 int start_lane, num_lane, i; 1810 phymod_phy_access_t pm_phy_copy; 1811 uint32_t tmp_detect; 1812 1813 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1814 *signal_detect = 1; 1815 1816 PHYMOD_IF_ERR_RETURN 1817 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1818 1819 for (i = 0; i < num_lane; i++) { 1820 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1821 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1822 continue; 1823 } 1824 PHYMOD_IF_ERR_RETURN 1825 (blackhawk_tsc_signal_detect(&pm_phy_copy.access, &tmp_detect)); 1826 *signal_detect &= tmp_detect; 1827 } 1828 return PHYMOD_E_NONE; 1829 1830 } 1831 1832 int blackhawk_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val) 1833 { 1834 PHYMOD_IF_ERR_RETURN(phymod_tscbh_iblk_read(&phy->access, reg_addr, val)); 1835 return PHYMOD_E_NONE; 1836 } 1837 1838 1839 int blackhawk_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val) 1840 { 1841 PHYMOD_IF_ERR_RETURN(phymod_tscbh_iblk_write(&phy->access, reg_addr, val)); 1842 return PHYMOD_E_NONE; 1843 } 1844 1845 int blackhawk_phy_tx_taps_default_get(const phymod_phy_access_t* phy, phymod_phy_signalling_method_t mode, phymod_tx_t* tx) 1846 { 1847 /*always default to 6-taps mode */ 1848 tx->tap_mode = phymodTxTapMode6Tap; 1849 if (mode == phymodSignallingMethodNRZ) { 1850 tx->pre2 = 0; 1851 tx->pre = -12; 1852 tx->main = 88; 1853 tx->post = -26; 1854 tx->post2 = 0; 1855 tx->post3 = 0; 1856 } else { 1857 tx->pre2 = 0; 1858 tx->pre = -24; 1859 tx->main = 132; 1860 tx->post = -12; 1861 tx->post2 = 0; 1862 tx->post3 = 0; 1863 } 1864 1865 return PHYMOD_E_NONE; 1866 } 1867 1868 int blackhawk_phy_lane_config_default_get(const phymod_phy_access_t* phy, phymod_phy_signalling_method_t mode, phymod_firmware_lane_config_t* lane_config) 1869 { 1870 /* default always assume backplane as the medium type and with dfe on */ 1871 if (mode == phymodSignallingMethodNRZ) { 1872 lane_config->ForceNRZMode = 1; 1873 lane_config->ForcePAM4Mode = 0; 1874 } else { 1875 lane_config->ForceNRZMode = 0; 1876 lane_config->ForcePAM4Mode = 1; 1877 } 1878 lane_config->LaneConfigFromPCS = 0; 1879 lane_config->AnEnabled = 0; 1880 lane_config->DfeOn = 1; 1881 lane_config->LpDfeOn = 0; 1882 lane_config->ForceBrDfe = 0; 1883 lane_config->MediaType = 0; 1884 lane_config->ScramblingDisable = 0; 1885 lane_config->Cl72AutoPolEn = 0; 1886 lane_config->Cl72RestTO = 0; 1887 lane_config->ForceExtenedReach = 0; 1888 lane_config->ForceNormalReach = 1; 1889 lane_config->LpPrecoderEnabled = 0; 1890 lane_config->UnreliableLos = 0; 1891 1892 return PHYMOD_E_NONE; 1893 } 1894 1895 int blackhawk_phy_pll_multiplier_get(const phymod_phy_access_t* phy, uint32_t* core_vco_pll_multiplier) 1896 { 1897 phymod_phy_access_t pm_phy_copy; 1898 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1899 1900 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_INTERNAL_read_pll_div(&pm_phy_copy.access, core_vco_pll_multiplier)); 1901 return PHYMOD_E_NONE; 1902 } 1903 1904 int blackhawk_phy_firmware_load_info_get(const phymod_phy_access_t* phy, phymod_firmware_load_info_t* info) 1905 { 1906 uint32_t ams_version; 1907 phymod_phy_access_t phy_copy; 1908 1909 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1910 phy_copy.access.lane_mask = 0x1; 1911 1912 PHYMOD_IF_ERR_RETURN 1913 (blackhawk_ams_version_get(&(phy_copy.access), &ams_version)); 1914 if (ams_version < 0xc0) { 1915 info->ucode_ptr = &blackhawk_ucode_rev0[0]; 1916 info->ucode_len = blackhawk_ucode_len_rev0; 1917 } else { 1918 info->ucode_ptr = &blackhawk_ucode_rev1[0]; 1919 info->ucode_len = blackhawk_ucode_len_rev1; 1920 } 1921 return PHYMOD_E_NONE; 1922 } 1923 1924 int blackhawk_phy_rx_adaptation_resume(const phymod_phy_access_t* phy) 1925 { 1926 phymod_phy_access_t phy_copy; 1927 uint8_t uc_lane_stopped; 1928 int start_lane, num_lane, i; 1929 1930 PHYMOD_IF_ERR_RETURN 1931 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1932 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1933 1934 for (i = 0; i < num_lane; i++) { 1935 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1936 continue; 1937 } 1938 phy_copy.access.lane_mask = 1 << (start_lane + i); 1939 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_stop_uc_lane_status(&phy_copy.access, &uc_lane_stopped)); 1940 if (uc_lane_stopped) { 1941 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_stop_rx_adaptation(&phy_copy.access, 0)); 1942 } 1943 } 1944 return PHYMOD_E_NONE; 1945 } 1946 1947 int blackhawk_phy_tx_pam4_precoder_enable_set(const phymod_phy_access_t* phy, int enable) 1948 { 1949 phymod_phy_access_t phy_copy; 1950 int start_lane, num_lane, i; 1951 1952 PHYMOD_IF_ERR_RETURN 1953 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1954 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1955 1956 PHYMOD_IF_ERR_RETURN 1957 (blackhawk_lane_soft_reset(&phy_copy.access, 1)); 1958 1959 for (i = 0; i < num_lane; i++) { 1960 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1961 continue; 1962 } 1963 phy_copy.access.lane_mask = 1 << (start_lane + i); 1964 PHYMOD_IF_ERR_RETURN 1965 (blackhawk_tsc_tx_pam4_precoder_enable_set(&phy_copy.access, enable)); 1966 } 1967 1968 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1969 PHYMOD_IF_ERR_RETURN 1970 (blackhawk_lane_soft_reset(&phy_copy.access, 0)); 1971 1972 return PHYMOD_E_NONE; 1973 } 1974 1975 /* Power down PLL*/ 1976 int blackhawk_phy_pll_pwrdn(const phymod_phy_access_t* phy, uint32_t pll_index, uint32_t pwrdn) 1977 { 1978 phymod_phy_access_t phy_copy; 1979 uint32_t is_pwrdn = 0; 1980 1981 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1982 phy_copy.access.lane_mask = 1 << 0; 1983 phy_copy.access.pll_idx = pll_index; 1984 1985 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_pll_pwrdn_get(&phy_copy.access, &is_pwrdn)); 1986 if (is_pwrdn != pwrdn) { 1987 if (pwrdn) { 1988 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_core_pwrdn(&phy_copy.access, PWRDN)); 1989 } else { 1990 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_core_pwrdn(&phy_copy.access, PWR_ON)); 1991 } 1992 } 1993 1994 return PHYMOD_E_NONE; 1995 } 1996 1997 int blackhawk_phy_tx_pam4_precoder_enable_get(const phymod_phy_access_t* phy, int *enable) 1998 { 1999 phymod_phy_access_t pm_phy_copy; 2000 2001 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 2002 PHYMOD_IF_ERR_RETURN 2003 (blackhawk_tsc_tx_pam4_precoder_enable_get(&pm_phy_copy.access, enable)); 2004 return PHYMOD_E_NONE; 2005 } 2006 2007 int blackhawk_phy_tx_phase_lock_set(const phymod_phy_access_t* phy, uint8_t enable) 2008 { 2009 phymod_phy_access_t phy_copy; 2010 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2011 2012 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_ext_loop_timing(&phy_copy.access, enable)); 2013 return PHYMOD_E_NONE; 2014 } 2015 2016 int blackhawk_phy_eye_margin_est_get(const phymod_phy_access_t* phy, phymod_eye_margin_mode_t eye_margin_mode, uint32_t* value) 2017 { 2018 int start_lane, num_lane; 2019 uint16_t hz_l, hz_r, vt_u, vt_d; 2020 phymod_phy_access_t phy_copy; 2021 2022 PHYMOD_IF_ERR_RETURN 2023 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2024 2025 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2026 phy_copy.access.lane_mask = 0x1 << start_lane; 2027 2028 PHYMOD_IF_ERR_RETURN 2029 (blackhawk_tsc_INTERNAL_get_eye_margin_est(&phy_copy.access, &hz_l, &hz_r, &vt_u, &vt_d)); 2030 2031 switch (eye_margin_mode) { 2032 case phymod_eye_marign_HZ_L: 2033 *value = hz_l; 2034 break; 2035 case phymod_eye_marign_HZ_R: 2036 *value = hz_r; 2037 break; 2038 case phymod_eye_marign_VT_U: 2039 *value = vt_u; 2040 break; 2041 case phymod_eye_marign_VT_D: 2042 *value = vt_d; 2043 break; 2044 default: 2045 *value = 0; 2046 break; 2047 } 2048 2049 return PHYMOD_E_NONE; 2050 2051 } 2052 2053 int blackhawk_phy_channel_loss_hint_set(const phymod_phy_access_t* phy, uint32_t channel_loss) 2054 { 2055 int i, start_lane, num_lane; 2056 phymod_phy_access_t phy_copy; 2057 uint32_t lane_reset; 2058 2059 PHYMOD_IF_ERR_RETURN 2060 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2061 2062 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2063 2064 /*first check if lane is in reset */ 2065 PHYMOD_IF_ERR_RETURN 2066 (blackhawk_lane_soft_reset_get(&phy_copy.access, &lane_reset)); 2067 2068 /* if lane is not in reset, then reset the lane first */ 2069 if (!lane_reset) { 2070 PHYMOD_IF_ERR_RETURN 2071 (blackhawk_lane_soft_reset(&phy_copy.access, 1)); 2072 } 2073 2074 for (i = 0; i < num_lane; i++) { 2075 phy_copy.access.lane_mask = 1 << (start_lane + i); 2076 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2077 continue; 2078 } 2079 PHYMOD_IF_ERR_RETURN 2080 (blackhawk_channel_loss_set(&phy_copy.access, channel_loss)); 2081 } 2082 2083 /* release the ln dp reset */ 2084 if (!lane_reset) { 2085 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2086 PHYMOD_IF_ERR_RETURN 2087 (blackhawk_lane_soft_reset(&phy_copy.access, 0)); 2088 } 2089 return PHYMOD_E_NONE; 2090 } 2091 2092 2093 int blackhawk_phy_channel_loss_hint_get(const phymod_phy_access_t* phy, uint32_t *channel_loss) 2094 { 2095 int start_lane, num_lane; 2096 phymod_phy_access_t phy_copy; 2097 2098 PHYMOD_IF_ERR_RETURN 2099 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2100 2101 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2102 phy_copy.access.lane_mask = 1 << start_lane; 2103 2104 PHYMOD_IF_ERR_RETURN 2105 (blackhawk_channel_loss_get(&phy_copy.access, channel_loss)); 2106 2107 return PHYMOD_E_NONE; 2108 } 2109 2110 int blackhawk_phy_pmd_info_init(const phymod_phy_access_t* phy) 2111 { 2112 phymod_phy_access_t phy_copy; 2113 2114 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2115 phy_copy.access.lane_mask = 0x1; 2116 2117 /* call PMD api to init the global PMD data structure */ 2118 PHYMOD_IF_ERR_RETURN 2119 (blackhawk_tsc_init_blackhawk_tsc_info(&phy_copy.access)); 2120 2121 return PHYMOD_E_NONE; 2122 } 2123 2124 2125 int blackhawk_phy_pmd_info_size_get(const phymod_phy_access_t* phy, uint32_t* pmd_size) 2126 { 2127 *pmd_size = sizeof(srds_info_t); 2128 2129 return PHYMOD_E_NONE; 2130 }