blackhawk_tsc_config.c (61447B)
1 /*********************************************************************************** 2 *********************************************************************************** 3 * File Name : blackhawk_tsc_config.c * 4 * Created On : 03 Nov 2015 * 5 * Created By : Brent Roberts * 6 * Description : APIs for Serdes IPs * 7 * Revision : * 8 * * 9 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 10 * 11 * Copyright 2007-2019 Broadcom Inc. All rights reserved. * 12 * No portions of this material may be reproduced in any form without * 13 * the written permission of: * 14 * Broadcom Corporation * 15 * 5300 California Avenue * 16 * Irvine, CA 92617 * 17 * * 18 * All information contained in this document is Broadcom Corporation * 19 * company private proprietary, and trade secret. * 20 */ 21 22 /** @file blackhawk_tsc_config.c 23 * Implementation of API config functions 24 */ 25 #include <phymod/phymod_system.h> 26 #include "blackhawk_tsc_config.h" 27 #include "blackhawk_tsc_access.h" 28 #include "blackhawk_tsc_common.h" 29 #include "blackhawk_tsc_functions.h" 30 #include "blackhawk_tsc_internal.h" 31 #include "blackhawk_tsc_internal_error.h" 32 #include "blackhawk_tsc_select_defns.h" 33 #include "blackhawk_tsc_enum.h" 34 #include "blackhawk_tsc_dependencies.h" 35 36 /* If SERDES_EVAL is defined, then is_ate_log_enabled() is queried to *\ 37 \* know whether to log ATE. blackhawk_tsc_access.h provides that function. */ 38 39 /* User specific implementation for creating syncronization object, used for critical section access in initialization routine below */ 40 /* USR_CREATE_LOCK; */ 41 42 /*******************************/ 43 /* Stop/Resume RX Adaptation */ 44 /*******************************/ 45 46 err_code_t blackhawk_tsc_stop_rx_adaptation(srds_access_t *sa__, uint8_t enable) { 47 48 if (enable) { 49 err_code_t err_code; 50 err_code = blackhawk_tsc_pmd_uc_control(sa__, CMD_UC_CTRL_STOP_GRACEFULLY,GRACEFUL_STOP_TIME); 51 if(err_code) { 52 uint8_t temp=0; 53 USR_PRINTF(("Warning Graceful stop request returned error %d; Requesting a forceful stop\n",err_code)); 54 temp = blackhawk_tsc_INTERNAL_stop_micro(sa__,0,&err_code); 55 /* return value from blackhawk_tsc_INTERNAL_stop_micro - immediate stop is not required */ 56 /* void casting to avoid compiler warning. */ 57 UNUSED(temp); 58 } 59 return(err_code); 60 } 61 else { 62 return(blackhawk_tsc_pmd_uc_control(sa__, CMD_UC_CTRL_RESUME,50)); 63 } 64 } 65 66 err_code_t blackhawk_tsc_request_stop_rx_adaptation(srds_access_t *sa__) { 67 68 return(blackhawk_tsc_pmd_uc_control_return_immediate(sa__, CMD_UC_CTRL_STOP_GRACEFULLY)); 69 } 70 71 /**********************/ 72 /* uCode CRC Verify */ 73 /**********************/ 74 75 err_code_t blackhawk_tsc_ucode_crc_verify(srds_access_t *sa__, uint16_t ucode_len,uint16_t expected_crc_value) { 76 uint16_t calc_crc; 77 UNUSED(sa__); 78 UNUSED(ucode_len); 79 80 ESTM(calc_crc = rdc_micro_cr_crc_checksum()); 81 if(calc_crc != expected_crc_value) { 82 EFUN_PRINTF(("Microcode CRC did not match expected=%04x : calculated=%04x\n",expected_crc_value, calc_crc)); 83 return(blackhawk_tsc_error(sa__, ERR_CODE_UC_CRC_NOT_MATCH)); 84 } 85 return(ERR_CODE_NONE); 86 } 87 88 err_code_t blackhawk_tsc_start_ucode_crc_calc(srds_access_t *sa__, uint16_t ucode_len) { 89 /* This is implemented for Backwards compatibility with Falcon16 code */ 90 return(ERR_CODE_NONE); 91 } 92 93 err_code_t blackhawk_tsc_check_ucode_crc(srds_access_t *sa__, uint16_t expected_crc_value, uint32_t timeout_ms) { 94 uint16_t calc_crc; 95 /* This is implemented for Backwards compatibility with Falcon16 code - preferred method is blackhawk_tsc_ucode_crc_verify(..)*/ 96 97 ESTM(calc_crc = rdc_micro_cr_crc_checksum()); 98 if(calc_crc != expected_crc_value) { 99 EFUN_PRINTF(("UC CRC did not match expected=%04x : calculated=%04x\n",expected_crc_value, calc_crc)); 100 return(blackhawk_tsc_error(sa__, ERR_CODE_UC_CRC_NOT_MATCH)); 101 } 102 103 return(ERR_CODE_NONE); 104 } 105 106 107 /**************************************************************/ 108 /* APIs to Write Lane Config and User variables into uC RAM */ 109 /**************************************************************/ 110 111 err_code_t blackhawk_tsc_set_uc_lane_cfg(srds_access_t *sa__, struct blackhawk_tsc_uc_lane_config_st struct_val) { 112 uint8_t reset_state; 113 ESTM(reset_state = rd_rx_lane_dp_reset_state()); 114 if(reset_state < 7) { 115 EFUN_PRINTF(("ERROR: blackhawk_tsc_set_uc_lane_cfg(..) called without ln_dp_s_rstb=0\n")); 116 return (blackhawk_tsc_error(sa__, ERR_CODE_LANE_DP_NOT_RESET)); 117 } 118 EFUN(blackhawk_tsc_INTERNAL_update_uc_lane_config_word(&struct_val)); 119 return(reg_wr_RX_CKRST_CTRL_TSC_LANE_UC_CONFIG(struct_val.word)); 120 } 121 122 /******************************************************************/ 123 /* APIs to Read Core/Lane Config and User variables from uC RAM */ 124 /******************************************************************/ 125 126 err_code_t blackhawk_tsc_get_uc_core_config(srds_access_t *sa__, struct blackhawk_tsc_uc_core_config_st *get_val) 127 { 128 129 if(!get_val) { 130 return blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT); 131 } 132 switch (blackhawk_tsc_get_pll_idx(sa__)) { 133 case 0: 134 ESTM(get_val->word = reg_rdc_CORE_PLL_COM_PLL_UC_CORE_CONFIG()); 135 break; 136 case 1: 137 ESTM(get_val->word = reg_rdc_CORE_PLL_COM_PLL_UC_CORE_CONFIG()); 138 break; 139 default: 140 EFUN(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 141 break; 142 } 143 EFUN(blackhawk_tsc_INTERNAL_update_uc_core_config_st(get_val)); 144 return ERR_CODE_NONE; 145 } 146 147 err_code_t blackhawk_tsc_get_uc_lane_cfg(srds_access_t *sa__, struct blackhawk_tsc_uc_lane_config_st *get_val) { 148 149 if(!get_val) { 150 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 151 } 152 ESTM(get_val->word = reg_rd_RX_CKRST_CTRL_TSC_LANE_UC_CONFIG()); 153 EFUN(blackhawk_tsc_INTERNAL_update_uc_lane_config_st(get_val)); 154 return (ERR_CODE_NONE); 155 } 156 157 /*--------------------------------------------*/ 158 /* APIs to Enable or Disable datapath reset */ 159 /*--------------------------------------------*/ 160 161 err_code_t blackhawk_tsc_tx_dp_reset(srds_access_t *sa__, uint8_t enable) { 162 if (enable) { 163 EFUN(wr_tx_ln_dp_s_rstb(0x0)); 164 } else { 165 EFUN(wr_tx_ln_dp_s_rstb(0x1)); 166 EFUN(wr_tx_uc_ack_lane_dp_reset(0x1)); 167 EFUN(wr_tx_uc_ack_lane_cfg_done(0x1)); 168 } 169 return ERR_CODE_NONE; 170 } 171 172 err_code_t blackhawk_tsc_rx_dp_reset(srds_access_t *sa__, uint8_t enable) { 173 if (enable) { 174 EFUN(wr_rx_ln_dp_s_rstb(0x0)); 175 } else { 176 EFUN(wr_rx_ln_dp_s_rstb(0x1)); 177 } 178 return ERR_CODE_NONE; 179 } 180 181 err_code_t blackhawk_tsc_core_dp_reset(srds_access_t *sa__, uint8_t enable){ 182 if (enable) { 183 EFUN(wrc_core_dp_s_rstb(0x0)); 184 } else { 185 EFUN(wrc_core_dp_s_rstb(0x1)); 186 } 187 return ERR_CODE_NONE; 188 } 189 190 /********************************/ 191 /* Loading ucode through PRAM */ 192 /********************************/ 193 err_code_t blackhawk_tsc_ucode_pram_load(srds_access_t *sa__, char const * ucode_image, uint32_t ucode_len) { 194 uint16_t ucode_len_remainder = ((ucode_len + 3) & 0xFFFFFFFC) - ucode_len; 195 196 if(!ucode_image) { 197 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 198 } 199 200 if (ucode_len > UCODE_MAX_SIZE) { /* uCode size should be less than UCODE_MAX_SIZE */ 201 return (blackhawk_tsc_error(sa__, ERR_CODE_INVALID_UCODE_LEN)); 202 } 203 204 EFUN(wrc_micro_master_clk_en(0x1)); /* Enable clock to microcontroller subsystem */ 205 EFUN(wrc_micro_master_rstb(0x1)); /* De-assert reset to microcontroller sybsystem */ 206 EFUN(wrc_micro_master_rstb(0x0)); /* Assert reset to microcontroller sybsystem - Toggling reset*/ 207 EFUN(wrc_micro_master_rstb(0x1)); /* De-assert reset to microcontroller sybsystem */ 208 EFUN(wrc_micro_cr_access_en(1)); /* Allow access to Code RAM */ 209 210 EFUN(wrc_micro_ra_init(0x1)); /* Set initialization command to initialize code RAM */ 211 EFUN(blackhawk_tsc_INTERNAL_poll_micro_ra_initdone(sa__, 250));/* Poll for micro_ra_initdone = 1 to indicate initialization done */ 212 213 EFUN(wrc_micro_ra_init(0x2)); /* Write command for data RAM initialization */ 214 EFUN(blackhawk_tsc_INTERNAL_poll_micro_ra_initdone(sa__, 250)); /* Poll status of data RAM initialization */ 215 216 EFUN(wrc_micro_ra_init(0x0)); /* Clear initialization command */ 217 218 EFUN(wrc_micro_cr_crc_prtsel(0)); 219 EFUN(wrc_micro_cr_prif_prtsel(0)); 220 EFUN(wrc_micro_cr_crc_init(1)); /* Initialize the HW CRC calculation */ 221 EFUN(wrc_micro_cr_crc_init(0)); 222 EFUN(wrc_micro_cr_crc_calc_en(1)); 223 EFUN(wrc_micro_cr_ignore_micro_code_writes(0)); /* Allow writing to program RAM */ 224 225 EFUN(wrc_micro_pramif_ahb_wraddr_msw(0x0000)); 226 EFUN(wrc_micro_pramif_ahb_wraddr_lsw(0x0000)); 227 EFUN(wrc_micro_pram_if_rstb(1)); 228 EFUN(wrc_micro_pramif_en(1)); 229 230 /* Wait 8 pram clocks */ 231 EFUN(USR_DELAY_US(1)); 232 233 /* write ucode into pram */ 234 while (ucode_len > 0) { 235 EFUN(blackhawk_tsc_pmd_wr_pram(sa__, *ucode_image)); 236 --ucode_len; 237 ++ucode_image; 238 } 239 240 /* Pad to 32 bits */ 241 while (ucode_len_remainder > 0) { 242 EFUN(blackhawk_tsc_pmd_wr_pram(sa__, 0)); 243 --ucode_len_remainder; 244 } 245 246 /* Wait 8 pram clocks */ 247 EFUN(USR_DELAY_US(1)); 248 249 EFUN(wrc_micro_cr_ignore_micro_code_writes(1)); /* Block writing to program RAM */ 250 EFUN(wrc_micro_cr_crc_calc_en(0)); 251 252 EFUN(wrc_micro_pramif_en(0)); 253 { 254 uint8_t micro_orig, num_micros, micro_idx; 255 ESTM(micro_orig = blackhawk_tsc_get_micro_idx(sa__)); 256 ESTM(num_micros = rdc_micro_num_uc_cores()); 257 for (micro_idx = 0; micro_idx < num_micros; micro_idx++) { 258 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_idx)); 259 EFUN(wrc_micro_core_clk_en(1)); 260 } 261 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_orig)); 262 } 263 /* EFUN(wrc_micro_core_rstb(1)); */ 264 return(ERR_CODE_NONE); 265 } 266 267 /************************************/ 268 /* Accessing core_config_from_pcs */ 269 /************************************/ 270 271 err_code_t blackhawk_tsc_set_core_config_from_pcs(srds_access_t *sa__, uint8_t core_cfg_from_pcs) { 272 struct blackhawk_tsc_uc_core_config_st core_config = {{0}}; 273 EFUN(blackhawk_tsc_get_uc_core_config(sa__, &core_config)); 274 core_config.field.core_cfg_from_pcs = core_cfg_from_pcs; 275 EFUN(blackhawk_tsc_INTERNAL_set_uc_core_config(sa__, core_config)); 276 return (ERR_CODE_NONE); 277 } 278 279 280 281 /******************/ 282 /* Lane Mapping */ 283 /******************/ 284 285 err_code_t blackhawk_tsc_map_lanes(srds_access_t *sa__, uint8_t num_lanes, uint8_t const *tx_lane_map, uint8_t const *rx_lane_map) { 286 uint8_t rd_val = 0; 287 288 /* Verify that the core data path is held in reset. */ 289 ESTM(rd_val = rdc_core_dp_s_rstb()); 290 if (rd_val != 0) { 291 EFUN_PRINTF(("ERROR: core data path reset is not de-asserted\n")); 292 return (ERR_CODE_UC_NOT_RESET); 293 } 294 295 /* Verify that all micros are held in reset. */ 296 297 { 298 uint8_t micro_orig, num_micros, micro_idx; 299 ESTM(micro_orig = blackhawk_tsc_get_micro_idx(sa__)); 300 ESTM(num_micros = rdc_micro_num_uc_cores()); 301 for (micro_idx = 0; micro_idx < num_micros; micro_idx++) { 302 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_idx)); 303 ESTM(rd_val |= rdc_micro_core_rstb()); 304 } 305 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_orig)); 306 } 307 if (rd_val != 0) { 308 return (ERR_CODE_UC_NOT_RESET); 309 } 310 311 /* Verify that the num_lanes parameter is correct. */ 312 ESTM(rd_val = rdc_revid_multiplicity()); 313 if (rd_val != num_lanes) { 314 return (ERR_CODE_BAD_LANE_COUNT); 315 } 316 317 /* Verify that tx_lane_map and rx_lane_map are valid. */ 318 { 319 uint8_t index1, index2; 320 #ifdef ENABLE_LANE_MAP_WARNING 321 uint8_t lp_message_printed = 0; 322 #endif /* ENABLE_LANE_MAP_WARNING */ 323 for (index1=0; index1<num_lanes; ++index1) { 324 325 /* Verify that a lane map is not to an invalid lane. */ 326 if ((tx_lane_map[index1] >= num_lanes) 327 || (rx_lane_map[index1] >= num_lanes)){ 328 return (ERR_CODE_BAD_LANE); 329 } 330 331 #ifdef ENABLE_LANE_MAP_WARNING 332 /* Warn if an RX lane mapping is not the same as TX. */ 333 if ((tx_lane_map[index1] != rx_lane_map[index1]) 334 && !lp_message_printed) { 335 ESTM_PRINTF(("Warning: In core %d, TX lane %d is mapped to %d, while RX lane %d is mapped to %d.\n Digital and remote loopback will not operate as expected.\n Further warnings are suppressed.\n", blackhawk_tsc_get_core(sa__), index1, tx_lane_map[index1], index1, rx_lane_map[index1])); 336 lp_message_printed = 1; 337 } 338 #endif /* ENABLE_LANE_MAP_WARNING */ 339 340 /* Verify that a lane map is not used twice. */ 341 for (index2=index1+1; index2<num_lanes; ++index2) { 342 if ((tx_lane_map[index1] == tx_lane_map[index2]) 343 || (rx_lane_map[index1] == rx_lane_map[index2])) { 344 return (ERR_CODE_BAD_LANE); 345 } 346 } 347 } 348 } 349 350 /* Write the map bitfields. 351 * Support up to 8 lanes. 352 */ 353 EFUN(wrc_tx_lane_addr_0(*(tx_lane_map++))); EFUN(wrc_rx_lane_addr_0(*(rx_lane_map++))); 354 #if defined(wrc_tx_lane_addr_1) 355 if (num_lanes > 1) { EFUN(wrc_tx_lane_addr_1(*(tx_lane_map++))); EFUN(wrc_rx_lane_addr_1(*(rx_lane_map++))); } 356 #if defined(wrc_tx_lane_addr_2) 357 if (num_lanes > 2) { EFUN(wrc_tx_lane_addr_2(*(tx_lane_map++))); EFUN(wrc_rx_lane_addr_2(*(rx_lane_map++))); } 358 #if defined(wrc_tx_lane_addr_3) 359 if (num_lanes > 3) { EFUN(wrc_tx_lane_addr_3(*(tx_lane_map++))); EFUN(wrc_rx_lane_addr_3(*(rx_lane_map++))); } 360 #if defined(wrc_tx_lane_addr_4) 361 if (num_lanes > 4) { EFUN(wrc_tx_lane_addr_4(*(tx_lane_map++))); EFUN(wrc_rx_lane_addr_4(*(rx_lane_map++))); } 362 #if defined(wrc_tx_lane_addr_5) 363 if (num_lanes > 5) { EFUN(wrc_tx_lane_addr_5(*(tx_lane_map++))); EFUN(wrc_rx_lane_addr_5(*(rx_lane_map++))); } 364 #if defined(wrc_tx_lane_addr_6) 365 if (num_lanes > 6) { EFUN(wrc_tx_lane_addr_6(*(tx_lane_map++))); EFUN(wrc_rx_lane_addr_6(*(rx_lane_map++))); } 366 #if defined(wrc_tx_lane_addr_7) 367 if (num_lanes > 7) { EFUN(wrc_tx_lane_addr_7(*(tx_lane_map++))); EFUN(wrc_rx_lane_addr_7(*(rx_lane_map++))); } 368 #endif 369 #endif 370 #endif 371 #endif 372 #endif 373 #endif 374 #endif 375 return (ERR_CODE_NONE); 376 } 377 378 /************************/ 379 /* Serdes API Version */ 380 /************************/ 381 382 err_code_t blackhawk_tsc_version(srds_access_t *sa__, uint32_t *api_version) { 383 384 if(!api_version) { 385 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 386 } 387 *api_version = 0xA1071C; 388 return (ERR_CODE_NONE); 389 } 390 391 /*****************/ 392 /* PMD_RX_LOCK */ 393 /*****************/ 394 395 err_code_t blackhawk_tsc_pmd_lock_status(srds_access_t *sa__, uint8_t *pmd_rx_lock) { 396 if(!pmd_rx_lock) { 397 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 398 } 399 ESTM(*pmd_rx_lock = rd_pmd_rx_lock()); 400 return (ERR_CODE_NONE); 401 } 402 403 /**********************************/ 404 /* Serdes TX disable/RX Restart */ 405 /**********************************/ 406 407 err_code_t blackhawk_tsc_tx_disable(srds_access_t *sa__, uint8_t enable) { 408 409 if (enable) { 410 EFUN(wr_sdk_tx_disable(0x1)); 411 } 412 else { 413 EFUN(wr_sdk_tx_disable(0x0)); 414 } 415 return(ERR_CODE_NONE); 416 } 417 418 err_code_t blackhawk_tsc_rx_restart(srds_access_t *sa__, uint8_t enable) { 419 420 EFUN(wr_rx_restart_pmd_hold(enable)); 421 return(ERR_CODE_NONE); 422 } 423 /******************************************************/ 424 /* Single function to set/get all RX AFE parameters */ 425 /******************************************************/ 426 427 err_code_t blackhawk_tsc_write_rx_afe(srds_access_t *sa__, enum srds_rx_afe_settings_enum param, int8_t val) { 428 /* Assumes the micro is not actively tuning */ 429 430 switch(param) { 431 case RX_AFE_PF: 432 return(blackhawk_tsc_INTERNAL_set_rx_pf_main(sa__, val)); 433 434 case RX_AFE_PF2: 435 return(blackhawk_tsc_INTERNAL_set_rx_pf2(sa__, val)); 436 437 case RX_AFE_VGA: 438 return(blackhawk_tsc_INTERNAL_set_rx_vga(sa__, val)); 439 440 case RX_AFE_DFE1: 441 return(blackhawk_tsc_INTERNAL_set_rx_dfe1(sa__, val)); 442 443 case RX_AFE_DFE2: 444 return(blackhawk_tsc_INTERNAL_set_rx_dfe2(sa__, val)); 445 446 case RX_AFE_DFE3: 447 return(blackhawk_tsc_INTERNAL_set_rx_dfe3(sa__, val)); 448 449 case RX_AFE_DFE4: 450 return(blackhawk_tsc_INTERNAL_set_rx_dfe4(sa__, val)); 451 452 case RX_AFE_DFE5: 453 return(blackhawk_tsc_INTERNAL_set_rx_dfe5(sa__, val)); 454 455 case RX_AFE_DFE6: 456 return (blackhawk_tsc_INTERNAL_set_rx_dfe6(sa__, val)); 457 458 case RX_AFE_DFE7: 459 return (blackhawk_tsc_INTERNAL_set_rx_dfe7(sa__, val)); 460 461 case RX_AFE_DFE8: 462 return (blackhawk_tsc_INTERNAL_set_rx_dfe8(sa__, val)); 463 464 case RX_AFE_DFE9: 465 return (blackhawk_tsc_INTERNAL_set_rx_dfe9(sa__, val)); 466 467 case RX_AFE_DFE10: 468 return (blackhawk_tsc_INTERNAL_set_rx_dfe10(sa__, val)); 469 470 case RX_AFE_DFE11: 471 return (blackhawk_tsc_INTERNAL_set_rx_dfe11(sa__, val)); 472 473 case RX_AFE_DFE12: 474 return (blackhawk_tsc_INTERNAL_set_rx_dfe12(sa__, val)); 475 476 case RX_AFE_DFE13: 477 return (blackhawk_tsc_INTERNAL_set_rx_dfe13(sa__, val)); 478 479 case RX_AFE_DFE14: 480 return (blackhawk_tsc_INTERNAL_set_rx_dfe14(sa__, val)); 481 case RX_AFE_PF3: 482 return(blackhawk_tsc_INTERNAL_set_rx_pf3(sa__, val)); 483 default: 484 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 485 } 486 } 487 488 err_code_t blackhawk_tsc_read_rx_afe(srds_access_t *sa__, enum srds_rx_afe_settings_enum param, int8_t *val) { 489 /* Assumes the micro is not actively tuning */ 490 491 uint8_t rd_val; 492 493 if(!val) { 494 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 495 } 496 497 switch(param) { 498 case RX_AFE_PF: 499 EFUN(blackhawk_tsc_INTERNAL_get_rx_pf_main(sa__, &rd_val)); 500 *val = (int8_t)rd_val; 501 break; 502 case RX_AFE_PF2: 503 EFUN(blackhawk_tsc_INTERNAL_get_rx_pf2(sa__, &rd_val)); 504 *val = (int8_t)rd_val; 505 break; 506 case RX_AFE_VGA: 507 EFUN(blackhawk_tsc_INTERNAL_get_rx_vga(sa__, &rd_val)); 508 *val = (int8_t)rd_val; 509 break; 510 511 case RX_AFE_DFE1: 512 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe1(sa__, val)); 513 break; 514 case RX_AFE_DFE2: 515 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe2(sa__, val)); 516 break; 517 case RX_AFE_DFE3: 518 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe3(sa__, val)); 519 break; 520 case RX_AFE_DFE4: 521 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe4(sa__, val)); 522 break; 523 case RX_AFE_DFE5: 524 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe5(sa__, val)); 525 break; 526 case RX_AFE_DFE6: 527 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe6(sa__, val)); 528 break; 529 case RX_AFE_DFE7: 530 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe7(sa__, val)); 531 break; 532 case RX_AFE_DFE8: 533 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe8(sa__, val)); 534 break; 535 case RX_AFE_DFE9: 536 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe9(sa__, val)); 537 break; 538 case RX_AFE_DFE10: 539 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe10(sa__, val)); 540 break; 541 case RX_AFE_DFE11: 542 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe11(sa__, val)); 543 break; 544 case RX_AFE_DFE12: 545 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe12(sa__, val)); 546 break; 547 case RX_AFE_DFE13: 548 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe13(sa__, val)); 549 break; 550 case RX_AFE_DFE14: 551 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe14(sa__, val)); 552 break; 553 case RX_AFE_PF3: 554 EFUN(blackhawk_tsc_INTERNAL_get_rx_pf3(sa__, &rd_val)); 555 *val = (int8_t)rd_val; 556 break; 557 default: 558 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 559 } 560 561 UNUSED(rd_val); 562 return(ERR_CODE_NONE); 563 } 564 565 err_code_t blackhawk_tsc_validate_txfir_cfg(srds_access_t *sa__, enum blackhawk_tsc_txfir_tap_enable_enum enable_taps, int16_t pre2, int16_t pre1, int16_t main, int16_t post1, int16_t post2, int16_t post3) { 566 blackhawk_tsc_txfir_st txfir; 567 568 ENULL_MEMSET(&txfir, 0, sizeof(blackhawk_tsc_txfir_st)); 569 if ((enable_taps == NRZ_6TAP) || (enable_taps == PAM4_6TAP)) { 570 txfir.tap[0] = pre2; 571 txfir.tap[1] = pre1; 572 txfir.tap[2] = main; 573 txfir.tap[3] = post1; 574 txfir.tap[4] = post2; 575 txfir.tap[5] = post3; 576 } 577 else { 578 txfir.tap[0] = pre1; 579 txfir.tap[1] = main; 580 txfir.tap[2] = post1; 581 if ((pre2 != 0) || (post2 != 0) || (post3 != 0)) { 582 EFUN_PRINTF(("ERROR: Selected 3 TAPs option, but other TAP inputs (pre2, post2, post3) have non-zero value\n")); 583 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 584 } 585 } 586 587 588 589 return blackhawk_tsc_validate_full_txfir_cfg(sa__, enable_taps, txfir); 590 } 591 592 err_code_t blackhawk_tsc_validate_full_txfir_cfg(srds_access_t *sa__, enum blackhawk_tsc_txfir_tap_enable_enum enable_taps, blackhawk_tsc_txfir_st txfir) { 593 uint8_t tap_num; 594 err_code_t err_code = ERR_CODE_NONE; 595 uint16_t abs_total = 0; 596 uint8_t in_nrz_range; 597 UNUSED(sa__); 598 599 in_nrz_range = ((enable_taps == NRZ_LP_3TAP) || (enable_taps == NRZ_6TAP)) ? 1 : 0; 600 if ((enable_taps == NRZ_6TAP) || (enable_taps == PAM4_6TAP)) { 601 tap_num=6; 602 } 603 else { 604 tap_num=3; 605 } 606 for (; tap_num<12; tap_num++) { 607 if (txfir.tap[tap_num]) { 608 /* txfir should be memset to zero and so this check catches bad accesses */ 609 EFUN_PRINTF(("ERROR: unused taps cannot be non zero values\n")); 610 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 611 } 612 } 613 for (tap_num=0; tap_num<6; tap_num++) { 614 if (((!in_nrz_range) && ((txfir.tap[tap_num] < TXFIR_PAM4_SW_TAP_MIN) || (txfir.tap[tap_num] > TXFIR_PAM4_SW_TAP_MAX))) || 615 ((in_nrz_range) && ((txfir.tap[tap_num] < TXFIR_NRZ_TAP_MIN) || (txfir.tap[tap_num] > TXFIR_NRZ_TAP_MAX)))) { 616 err_code |= ERR_CODE_TXFIR_MAIN_INVALID; 617 } 618 abs_total += SRDS_ABS(txfir.tap[tap_num]); 619 } 620 621 if (abs_total > (in_nrz_range ? TXFIR_NRZ_SUM_LIMIT: TXFIR_PAM4_SW_SUM_LIMIT)) { 622 err_code |= ERR_CODE_TXFIR_SUM_LIMIT; 623 } 624 return (blackhawk_tsc_error(sa__, err_code)); 625 } 626 627 static uint8_t const tap_num_invalid = 255; 628 629 /* Return the FIR tap index for the given parameter, or tap_num_invalid if the parameter is not an FIR tap. */ 630 static uint8_t _blackhawk_tsc_get_fir_tap_index(enum blackhawk_tsc_tx_afe_settings_enum param) { 631 switch(param) { 632 case TX_AFE_TAP0: return 0; 633 case TX_AFE_TAP1: return 1; 634 case TX_AFE_TAP2: return 2; 635 case TX_AFE_TAP3: return 3; 636 case TX_AFE_TAP4: return 4; 637 case TX_AFE_TAP5: return 5; 638 case TX_AFE_TAP6: return 6; 639 case TX_AFE_TAP7: return 7; 640 case TX_AFE_TAP8: return 8; 641 case TX_AFE_TAP9: return 9; 642 case TX_AFE_TAP10: return 10; 643 case TX_AFE_TAP11: return 11; 644 default: return tap_num_invalid; 645 } 646 } 647 648 err_code_t blackhawk_tsc_write_tx_afe(srds_access_t *sa__, enum blackhawk_tsc_tx_afe_settings_enum param, int16_t val) { 649 uint8_t const tap_num = _blackhawk_tsc_get_fir_tap_index(param); 650 uint8_t in_nrz_range; 651 652 ESTM(in_nrz_range = rd_txfir_nrz_tap_range_sel()); 653 654 if (tap_num != tap_num_invalid) { 655 if (((!in_nrz_range) && ((val < TXFIR_PAM4_SW_TAP_MIN) || (val > TXFIR_PAM4_SW_TAP_MAX))) || 656 ((in_nrz_range) && ((val < TXFIR_NRZ_TAP_MIN) || (val > TXFIR_NRZ_TAP_MAX)))) { 657 return(blackhawk_tsc_error(sa__, ERR_CODE_TXFIR_MAIN_INVALID)); 658 } 659 EFUN(blackhawk_tsc_INTERNAL_set_tx_tap(sa__, tap_num, val)); 660 EFUN(blackhawk_tsc_INTERNAL_load_txfir_taps(sa__)); 661 } else { 662 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 663 } 664 return(ERR_CODE_NONE); 665 } 666 667 err_code_t blackhawk_tsc_read_tx_afe(srds_access_t *sa__, enum blackhawk_tsc_tx_afe_settings_enum param, int16_t *val) { 668 if(!val) { 669 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 670 } 671 { 672 uint8_t const tap_num = _blackhawk_tsc_get_fir_tap_index(param); 673 if (tap_num != tap_num_invalid) { 674 EFUN(blackhawk_tsc_INTERNAL_get_tx_tap(sa__, tap_num, val)); 675 } else { 676 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 677 } 678 } 679 return(ERR_CODE_NONE); 680 } 681 err_code_t blackhawk_tsc_apply_txfir_cfg(srds_access_t *sa__, enum blackhawk_tsc_txfir_tap_enable_enum enable_taps, int16_t pre2, int16_t pre1, int16_t main, int16_t post1, int16_t post2, int16_t post3) { 682 blackhawk_tsc_txfir_st txfir; 683 684 ENULL_MEMSET(&txfir, 0, sizeof(blackhawk_tsc_txfir_st)); 685 if ((enable_taps == NRZ_6TAP) || (enable_taps == PAM4_6TAP)) { 686 txfir.tap[0] = pre2; 687 txfir.tap[1] = pre1; 688 txfir.tap[2] = main; 689 txfir.tap[3] = post1; 690 txfir.tap[4] = post2; 691 txfir.tap[5] = post3; 692 } 693 else { 694 txfir.tap[0] = pre1; 695 txfir.tap[1] = main; 696 txfir.tap[2] = post1; 697 if ((pre2 != 0) || (post2 != 0) || (post3 != 0)) { 698 EFUN_PRINTF(("ERROR: Selected 3 TAPs option, but other TAP inputs (pre2, post2, post3) have non-zero value\n")); 699 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 700 } 701 } 702 703 704 705 return blackhawk_tsc_apply_full_txfir_cfg(sa__, enable_taps, txfir); 706 } 707 708 err_code_t blackhawk_tsc_apply_full_txfir_cfg(srds_access_t *sa__, enum blackhawk_tsc_txfir_tap_enable_enum enable_taps, blackhawk_tsc_txfir_st txfir) { 709 uint8_t tap_num; 710 err_code_t failcode; 711 712 EFUN(wr_txfir_nrz_tap_range_sel(((enable_taps == NRZ_LP_3TAP) || (enable_taps == NRZ_6TAP)) ? 1 : 0)); 713 failcode = blackhawk_tsc_validate_full_txfir_cfg(sa__, enable_taps, txfir); 714 if (!failcode) { 715 for (tap_num=0; tap_num<12; tap_num++) { 716 failcode |= blackhawk_tsc_INTERNAL_set_tx_tap(sa__, tap_num, txfir.tap[tap_num]); 717 } 718 if ((enable_taps == NRZ_6TAP) || (enable_taps == PAM4_6TAP)) { 719 EFUN(wr_txfir_tap_en(1)); 720 } 721 else { 722 EFUN(wr_txfir_tap_en(0)); 723 } 724 EFUN(blackhawk_tsc_INTERNAL_load_txfir_taps(sa__)); 725 } 726 return (blackhawk_tsc_error(sa__, failcode)); 727 } 728 729 730 /**********************************************/ 731 /* Loopback and Ultra-Low Latency Functions */ 732 /**********************************************/ 733 734 /* Locks TX_PI to Loop timing */ 735 err_code_t blackhawk_tsc_loop_timing(srds_access_t *sa__, uint8_t enable) { 736 737 if (enable) { 738 EFUN(wr_tx_pi_loop_timing_src_sel(0x1)); /* RX phase_sum_val_logic enable */ 739 EFUN(wr_tx_pi_en(0x1)); /* TX_PI enable: 0 = diabled, 1 = enabled */ 740 EFUN(wr_tx_pi_jitter_filter_en(0x1)); /* Jitter filter enable to lock freq: 0 = diabled, 1 = enabled */ 741 EFUN(USR_DELAY_US(25)); /* Wait for tclk to lock to CDR */ 742 } 743 else { 744 EFUN(wr_tx_pi_jitter_filter_en(0x0)); /* Jitter filter enable to lock freq: 0 = diabled, 1 = enabled */ 745 EFUN(wr_tx_pi_en(0x0)); /* TX_PI enable: 0 = diabled, 1 = enabled */ 746 EFUN(wr_tx_pi_loop_timing_src_sel(0x0)); /* RX phase_sum_val_logic enable */ 747 } 748 return (ERR_CODE_NONE); 749 } 750 751 /* Setup Remote Loopback mode */ 752 err_code_t blackhawk_tsc_rmt_lpbk(srds_access_t *sa__, uint8_t enable) { 753 if (enable) { 754 EFUN(blackhawk_tsc_loop_timing(sa__, enable)); 755 EFUN(wr_tx_pi_ext_ctrl_en(0x1)); /* PD path enable: 0 = diabled, 1 = enabled */ 756 EFUN(wr_rmt_lpbk_en(0x1)); /* Remote Loopback Enable: 0 = diabled, 1 = enable */ 757 EFUN(USR_DELAY_US(50)); /* Wait for rclk and tclk phase lock before expecing good data from rmt loopback */ 758 } else { /* Might require longer wait time for smaller values of tx_pi_ext_phase_bwsel_integ */ 759 EFUN(wr_rmt_lpbk_en(0x0)); /* Remote Loopback Enable: 0 = diabled, 1 = enable */ 760 EFUN(wr_tx_pi_ext_ctrl_en(0x0)); /* PD path enable: 0 = diabled, 1 = enabled */ 761 EFUN(blackhawk_tsc_loop_timing(sa__, enable)); 762 } 763 return (ERR_CODE_NONE); 764 } 765 766 767 /********************************/ 768 /* TX_PI Fixed Frequency Mode */ 769 /********************************/ 770 /* TX_PI Frequency Override (Fixed Frequency Mode) */ 771 err_code_t blackhawk_tsc_tx_pi_freq_override(srds_access_t *sa__, uint8_t enable, int16_t freq_override_val) { 772 if (enable) { 773 EFUN(wr_tx_pi_en(0x1)); /* TX_PI enable : 0 = disabled, 1 = enabled */ 774 EFUN(wr_tx_pi_freq_override_en(0x1)); /* Fixed freq mode enable: 0 = disabled, 1 = enabled */ 775 EFUN(wr_tx_pi_freq_override_val(freq_override_val)); /* Fixed Freq Override Value (+/-8192) */ 776 } 777 else { 778 EFUN(wr_tx_pi_freq_override_val(0)); /* Fixed Freq Override Value to 0 */ 779 EFUN(wr_tx_pi_freq_override_en(0x0)); /* Fixed freq mode enable: 0 = disabled, 1 = enabled */ 780 EFUN(wr_tx_pi_en(0x0)); /* TX_PI enable : 0 = disabled, 1 = enabled */ 781 } 782 return (ERR_CODE_NONE); 783 } 784 785 /*********************************/ 786 /* uc_active and uc_reset APIs */ 787 /*********************************/ 788 err_code_t blackhawk_tsc_get_micro_num_uc_cores(srds_access_t *sa__, uint8_t *num_micros) { 789 ESTM(*num_micros = rdc_micro_num_uc_cores()); 790 return (ERR_CODE_NONE); 791 } 792 793 /* Enable or Disable the uC reset */ 794 err_code_t blackhawk_tsc_uc_reset(srds_access_t *sa__, uint8_t enable) { 795 ucode_info_t ucode_info = {0}; 796 EFUN_PRINTF(("\n*** WARNING: blackhawk_tsc_uc_reset() has been deprecated. Please replace it with blackhawk_tsc_uc_reset_with_info()\n\n")); 797 return blackhawk_tsc_uc_reset_with_info(sa__, enable, ucode_info); 798 } 799 800 err_code_t blackhawk_tsc_uc_reset_with_info(srds_access_t *sa__, uint8_t enable, ucode_info_t ucode_info) { 801 if (enable) { 802 #ifdef wrc_micro_micro_s_rstb 803 EFUN(wrc_micro_micro_s_rstb(0x0)); /* Toggle micro_reset to reset all micro registers to default value */ 804 EFUN(wrc_micro_micro_s_rstb(0x1)); 805 #else 806 /* Assert micro reset and reset all micro registers (all non-status registers written to default value) */ 807 EFUN(wrc_uc_active(0)); 808 { 809 uint8_t micro_orig, num_micros, micro_idx; 810 ESTM(micro_orig = blackhawk_tsc_get_micro_idx(sa__)); 811 EFUN(blackhawk_tsc_get_micro_num_uc_cores(sa__, &num_micros)); 812 for (micro_idx = 0; micro_idx < num_micros; micro_idx++) { 813 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_idx)); 814 EFUN(wrc_micro_core_rstb(0)); 815 EFUN(wrc_micro_core_clk_en(0)); /* Disable clocks to M0 cores */ 816 } 817 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_orig)); 818 } 819 820 EFUN(wrc_micro_master_clk_en(0x0)); /* Disable clock to microcontroller subsystem */ 821 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD200, 0x0000)); 822 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD201, 0x4000)); 823 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD202, 0x0000)); 824 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD204, 0x0000)); 825 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD205, 0x0000)); 826 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD206, 0x0000)); 827 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD207, 0x0000)); 828 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD208, 0x0000)); 829 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD209, 0x0000)); 830 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD20A, 0x0000)); 831 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD20B, 0x0000)); 832 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD20C, 0x0000)); 833 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD20D, 0x0000)); 834 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD20E, 0x0000)); 835 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD211, 0x0000)); 836 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD212, 0x0000)); 837 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD213, 0x0000)); 838 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD214, 0x0000)); 839 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD215, 0x0000)); 840 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD216, 0x0000)); 841 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD217, 0x0003)); 842 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD218, 0xffff)); 843 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD219, 0x0e01)); 844 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD220, 0x0000)); 845 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD221, 0x0000)); 846 847 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD225, 0x0000)); 848 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD226, 0x0000)); 849 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD227, 0x8382)); 850 851 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD229, 0x0000)); 852 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD22B, 0x0000)); /* fast_read_en = 0 for all BHK */ 853 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD22C, 0x0000)); 854 855 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD230, 0x0000)); 856 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD231, 0x0000)); 857 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD232, 0x0000)); 858 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD233, 0x0000)); 859 860 { 861 uint8_t micro_orig, num_micros, micro_idx; 862 ESTM(micro_orig = blackhawk_tsc_get_micro_idx(sa__)); 863 EFUN(blackhawk_tsc_get_micro_num_uc_cores(sa__, &num_micros)); 864 for (micro_idx = 0; micro_idx < num_micros; micro_idx++) { 865 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_idx)); 866 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD240, 0x0000)); /* Per micro registers */ 867 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD241, 0x8000)); 868 /* EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD243, 0x0003)); Micro sets this register (lane_sel) separately */ 869 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD244, 0x0000)); 870 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD245, 0x000e)); 871 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD24D, 0x0000)); 872 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD24E, 0x0000)); 873 } 874 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_orig)); 875 } 876 #endif /* wrc_micro_micro_s_rstb */ 877 878 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD22B, 0x0000)); /* fast_read_en = 0 for all BHK */ 879 880 /* Stack Size calculation */ 881 { 882 uint16_t stack_size; 883 if (ucode_info.stack_size != 0) { 884 stack_size = ucode_info.stack_size; 885 } else { 886 stack_size = 0x7f4; /* 8 lanes */ 887 } 888 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD22E, (0x8000 | (stack_size)<<2))); 889 } 890 891 /* CODE_RAM, DATA_RAM calculation */ 892 { 893 uint16_t ram_config_val = 0x0; 894 uint8_t i_am_b0 = 0; 895 EFUN(blackhawk_tsc_INTERNAL_ip_version_check(sa__, &i_am_b0)); 896 897 if(i_am_b0) { /* B0 */ 898 ram_config_val = 0; 899 if(ucode_info.ucode_size <= 0x14000) { /* 81920 */ 900 ram_config_val = 0x0000; 901 } else if((ucode_info.ucode_size > 0x14000) && (ucode_info.ucode_size <= 0x15000)) { /* 81921 - 86016 */ 902 /* 4KB of Data RAM to be used for storing CODE */ 903 ram_config_val = 0x400; 904 } else { 905 EFUN_PRINTF(("Image size not support\n")); 906 return (ERR_CODE_IMAGE_SIZE_NOT_SUPPORTED); 907 } 908 } else 909 { /* A0 */ 910 if(ucode_info.ucode_size <= 0x10000) { /* 65536 */ 911 ram_config_val = 0x0000; 912 } else if((ucode_info.ucode_size > 0x10000) && (ucode_info.ucode_size <= 0x10800)) { /* 65537 - 67584 */ 913 /* 2KB of Data RAM to be used for storing CODE */ 914 ram_config_val = 0x200; 915 } else if((ucode_info.ucode_size > 0x10800) && (ucode_info.ucode_size <= 0x11000)) { /* 67585 - 69632 */ 916 /* 4KB of Data RAM to be used for storing CODE */ 917 ram_config_val = 0x400; 918 } 919 else if((ucode_info.ucode_size > 0x11000) && (ucode_info.ucode_size <= 0x11C00)) { /* 69633 - 72704 */ 920 /* 7KB of Data RAM to be used for storing CODE */ 921 ram_config_val = 0x700; 922 } else { 923 EFUN_PRINTF(("Image size not support\n")); 924 return (ERR_CODE_IMAGE_SIZE_NOT_SUPPORTED); 925 } 926 } 927 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, 0xD228, ram_config_val)); /* RAM CONFIG */ 928 } 929 } 930 else { 931 #ifdef wrc_micro_micro_s_rstb 932 EFUN(wrc_micro_micro_s_rstb(0x1)); /* De-assert micro reset */ 933 #endif 934 /* De-assert micro reset - Start executing code */ 935 EFUN(wrc_micro_master_clk_en (0x1)); /* Enable clock to microcontroller subsystem */ 936 EFUN(wrc_micro_master_rstb (0x1)); /* De-assert reset to microcontroller sybsystem */ 937 EFUN(wrc_micro_cr_access_en (0x1)); 938 939 { 940 uint8_t micro_orig, num_micros; 941 int micro_idx; 942 ESTM(micro_orig = blackhawk_tsc_get_micro_idx(sa__)); 943 EFUN(blackhawk_tsc_get_micro_num_uc_cores(sa__, &num_micros)); 944 for (micro_idx = num_micros-1; micro_idx >= 0; micro_idx--) { 945 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_idx)); 946 EFUN(wrc_micro_core_clk_en (0x1)); /* Enable clock to M0 core */ 947 EFUN(wrc_micro_core_rstb (0x1)); 948 } 949 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_orig)); 950 } 951 } 952 return (ERR_CODE_NONE); 953 } 954 955 /* Wait for uC to become active */ 956 err_code_t blackhawk_tsc_wait_uc_active(srds_access_t *sa__) { 957 uint16_t loop; 958 for (loop = 0; loop < 10000; loop++) { 959 uint16_t rddata; 960 uint8_t core_uc_active=0; 961 ESTM(core_uc_active = rdc_uc_active()); 962 ESTM(rddata = (reg_rdc_MICRO_B_COM_RMI_MICRO_SDK_STATUS0() & 0xF)); 963 if ((rddata == 0xF) && (core_uc_active == 1)) { 964 return (ERR_CODE_NONE); 965 } 966 if (loop>10) { 967 EFUN(USR_DELAY_US(1)); 968 } 969 } 970 return (blackhawk_tsc_error(sa__, ERR_CODE_MICRO_INIT_NOT_DONE)); 971 } 972 err_code_t blackhawk_tsc_init_blackhawk_tsc_info(srds_access_t *sa__) { 973 uint32_t info_table[INFO_TABLE_END / sizeof(uint32_t)]; 974 uint32_t info_table_signature; 975 uint8_t info_table_version; 976 err_code_t err_code = ERR_CODE_NONE; 977 srds_info_t * blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr(sa__); 978 979 USR_ACQUIRE_LOCK; 980 /* Handle error cases when blackhawk_tsc_info_ptr returned as zero */ 981 if (blackhawk_tsc_info_ptr == NULL) { 982 EFUN_PRINTF(("ERROR: Info table pointer is null.\n")); 983 RELEASE_LOCK_AND_RETURN (blackhawk_tsc_error(sa__, ERR_CODE_INFO_TABLE_ERROR)); 984 } 985 #ifdef PHYMOD_SUPPORT 986 if (PHYMOD_ACC_F_PHYSIM_GET(sa__)) { 987 blackhawk_tsc_info_ptr->lane_count = 0x2; 988 blackhawk_tsc_info_ptr->trace_memory_descending_writes = 0x1; 989 blackhawk_tsc_info_ptr->core_var_ram_size = 0x40; 990 blackhawk_tsc_info_ptr->lane_var_ram_size = 0x340; 991 blackhawk_tsc_info_ptr->diag_mem_ram_size = 0x100; 992 blackhawk_tsc_info_ptr->trace_mem_ram_size = 0x200; 993 blackhawk_tsc_info_ptr->diag_mem_ram_base = 0x20000100; 994 blackhawk_tsc_info_ptr->trace_mem_ram_base = 0x20000100; 995 blackhawk_tsc_info_ptr->core_var_ram_base = 0x20000080; 996 blackhawk_tsc_info_ptr->micro_var_ram_base =0x20000300; 997 blackhawk_tsc_info_ptr->micro_var_ram_size = 0x10; 998 blackhawk_tsc_info_ptr->lane_var_ram_base = 0x20000800; 999 blackhawk_tsc_info_ptr->ucode_version = 0x0; 1000 blackhawk_tsc_info_ptr->signature = SRDS_INFO_SIGNATURE; 1001 } else { 1002 #endif /* PHYMOD_SUPPORT */ 1003 1004 /* Following check should NOT apply to SDK phymod due to warmboot. */ 1005 #ifndef PHYMOD_SUPPORT 1006 if (blackhawk_tsc_info_ptr->signature == SRDS_INFO_SIGNATURE) { 1007 /*Already initalized and so check for microcode version and exit with proper status*/ 1008 err_code = blackhawk_tsc_INTERNAL_match_ucode_from_info(sa__); 1009 1010 if (err_code == ERR_CODE_NONE) { 1011 /* ucode version match */ 1012 RELEASE_LOCK_AND_RETURN (ERR_CODE_NONE); 1013 } else { 1014 /* ucode version mismatch */ 1015 RELEASE_LOCK_AND_RETURN (blackhawk_tsc_error(sa__, ERR_CODE_MICRO_INIT_NOT_DONE)); 1016 } 1017 } 1018 #endif /* PHYMOD_SUPPORT */ 1019 1020 /*Never initialized so far, continue with initialization */ 1021 1022 err_code = blackhawk_tsc_rdblk_uc_prog_ram(sa__, (uint8_t *)info_table, INFO_TABLE_RAM_BASE, INFO_TABLE_END); 1023 /* Release lock before returning from the call to avoid deadlock */ 1024 if (ERR_CODE_NONE != err_code) { 1025 RELEASE_LOCK_AND_RETURN(blackhawk_tsc_error(sa__, err_code)); 1026 } 1027 1028 info_table_signature = info_table[INFO_TABLE_OFFS_SIGNATURE / sizeof(uint32_t)]; 1029 info_table_version = (uint8_t)(info_table_signature >> 24); 1030 if (((info_table_signature & 0x00FFFFFF) != 0x666E49) 1031 || (!( ((info_table_version >= 0x32) && (info_table_version <= 0x39)) 1032 || ((info_table_version >= 0x41) && (info_table_version <= 0x5A))))) { 1033 RELEASE_LOCK_AND_RETURN (blackhawk_tsc_error(sa__, ERR_CODE_INFO_TABLE_ERROR)); 1034 } 1035 1036 blackhawk_tsc_info_ptr->lane_count = info_table[INFO_TABLE_OFFS_OTHER_SIZE / sizeof(uint32_t)] & 0xFF; 1037 blackhawk_tsc_info_ptr->trace_memory_descending_writes = ((info_table[INFO_TABLE_OFFS_OTHER_SIZE / sizeof(uint32_t)] & 0x1000000) != 0); 1038 1039 blackhawk_tsc_info_ptr->core_var_ram_size = (info_table[INFO_TABLE_OFFS_OTHER_SIZE / sizeof(uint32_t)] >> 8) & 0xFF; 1040 1041 blackhawk_tsc_info_ptr->lane_var_ram_size = (info_table[INFO_TABLE_OFFS_TRACE_LANE_MEM_SIZE / sizeof(uint32_t)] >> 16) & 0xFFFF; 1042 1043 blackhawk_tsc_info_ptr->diag_mem_ram_size = (info_table[INFO_TABLE_OFFS_TRACE_LANE_MEM_SIZE / sizeof(uint32_t)] & 0xFFFF) / blackhawk_tsc_info_ptr->lane_count; 1044 blackhawk_tsc_info_ptr->trace_mem_ram_size = (info_table[INFO_TABLE_OFFS_TRACE_LANE_MEM_SIZE / sizeof(uint32_t)] & 0xFFFF); 1045 1046 blackhawk_tsc_info_ptr->diag_mem_ram_base = info_table[INFO_TABLE_OFFS_TRACE_MEM_PTR / sizeof(uint32_t)]; 1047 blackhawk_tsc_info_ptr->trace_mem_ram_base = blackhawk_tsc_info_ptr->diag_mem_ram_base; 1048 1049 blackhawk_tsc_info_ptr->core_var_ram_base = info_table[INFO_TABLE_OFFS_CORE_MEM_PTR / sizeof(uint32_t)]; 1050 1051 blackhawk_tsc_info_ptr->micro_var_ram_base = info_table[INFO_TABLE_OFFS_MICRO_MEM_PTR / sizeof(uint32_t)]; 1052 blackhawk_tsc_info_ptr->micro_var_ram_size = (info_table[INFO_TABLE_OFFS_OTHER_SIZE_2 / sizeof(uint32_t)] >> 4) & 0xFF; 1053 1054 blackhawk_tsc_info_ptr->lane_var_ram_base = info_table[INFO_TABLE_OFFS_LANE_MEM_PTR / sizeof(uint32_t)]; 1055 1056 1057 1058 if (info_table_version < 0x34) { 1059 blackhawk_tsc_info_ptr->micro_count = 1; 1060 } else { 1061 blackhawk_tsc_info_ptr->micro_count = info_table[INFO_TABLE_OFFS_OTHER_SIZE_2 / sizeof(uint32_t)] & 0xF; 1062 } 1063 1064 if (info_table_version < 0x36) { 1065 blackhawk_tsc_info_ptr->grp_ram_size = 0x1fd0; /*size of micro stacksize */ 1066 } else { 1067 blackhawk_tsc_info_ptr->grp_ram_size = info_table[INFO_TABLE_OFFS_GROUP_RAM_SIZE / sizeof(uint32_t)] & 0xFFFF; 1068 } 1069 blackhawk_tsc_info_ptr->ucode_version = info_table[INFO_TABLE_OFFS_UC_VERSION /sizeof(uint32_t)]; 1070 blackhawk_tsc_info_ptr->signature = SRDS_INFO_SIGNATURE; 1071 #ifdef PHYMOD_SUPPORT 1072 } 1073 #endif /* PHYMOD_SUPPORT */ 1074 1075 RELEASE_LOCK_AND_RETURN (ERR_CODE_NONE); 1076 } 1077 1078 err_code_t blackhawk_tsc_firmware_load_none_init_blackhawk_tsc_info(srds_access_t *sa__) { 1079 srds_info_t * const blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr(sa__); 1080 1081 blackhawk_tsc_info_ptr->lane_count = 8; 1082 return (ERR_CODE_NONE); 1083 } 1084 1085 /*-----------------*/ 1086 /* Configure PLL */ 1087 /*-----------------*/ 1088 1089 err_code_t blackhawk_tsc_configure_pll_refclk_div(srds_access_t *sa__, 1090 enum blackhawk_tsc_pll_refclk_enum refclk, 1091 enum blackhawk_tsc_pll_div_enum srds_div) { 1092 return blackhawk_tsc_INTERNAL_configure_pll(sa__, refclk, srds_div, 0, BLACKHAWK_TSC_PLL_OPTION_NONE); 1093 } 1094 1095 err_code_t blackhawk_tsc_configure_pll_refclk_vco(srds_access_t *sa__, 1096 enum blackhawk_tsc_pll_refclk_enum refclk, 1097 uint32_t vco_freq_khz) { 1098 return blackhawk_tsc_INTERNAL_configure_pll(sa__, refclk, BLACKHAWK_TSC_PLL_DIV_UNKNOWN, vco_freq_khz, BLACKHAWK_TSC_PLL_OPTION_NONE); 1099 } 1100 1101 err_code_t blackhawk_tsc_configure_pll_div_vco(srds_access_t *sa__, 1102 enum blackhawk_tsc_pll_div_enum srds_div, 1103 uint32_t vco_freq_khz) { 1104 return blackhawk_tsc_INTERNAL_configure_pll(sa__, BLACKHAWK_TSC_PLL_REFCLK_UNKNOWN, srds_div, vco_freq_khz, BLACKHAWK_TSC_PLL_OPTION_NONE); 1105 } 1106 1107 /* following routines divide refclk input by 2 to prevent fracn mode */ 1108 err_code_t blackhawk_tsc_configure_pll_refclk_div_div2refclk(srds_access_t *sa__, 1109 enum blackhawk_tsc_pll_refclk_enum refclk, 1110 enum blackhawk_tsc_pll_div_enum srds_div) { 1111 return blackhawk_tsc_INTERNAL_configure_pll(sa__, refclk, srds_div, 0, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV2_EN); 1112 } 1113 1114 err_code_t blackhawk_tsc_configure_pll_refclk_vco_div2refclk(srds_access_t *sa__, 1115 enum blackhawk_tsc_pll_refclk_enum refclk, 1116 uint32_t vco_freq_khz) { 1117 return blackhawk_tsc_INTERNAL_configure_pll(sa__, refclk, BLACKHAWK_TSC_PLL_DIV_UNKNOWN, vco_freq_khz, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV2_EN); 1118 } 1119 1120 err_code_t blackhawk_tsc_configure_pll_div_vco_div2refclk(srds_access_t *sa__, 1121 enum blackhawk_tsc_pll_div_enum srds_div, 1122 uint32_t vco_freq_khz) { 1123 return blackhawk_tsc_INTERNAL_configure_pll(sa__, BLACKHAWK_TSC_PLL_REFCLK_UNKNOWN, srds_div, vco_freq_khz, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV2_EN); 1124 } 1125 /* following routines divide refclk input by 2 to prevent fracn mode */ 1126 err_code_t blackhawk_tsc_configure_pll_refclk_div_div4refclk(srds_access_t *sa__, 1127 enum blackhawk_tsc_pll_refclk_enum refclk, 1128 enum blackhawk_tsc_pll_div_enum srds_div) { 1129 return blackhawk_tsc_INTERNAL_configure_pll(sa__, refclk, srds_div, 0, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV4_EN); 1130 } 1131 1132 err_code_t blackhawk_tsc_configure_pll_refclk_vco_div4refclk(srds_access_t *sa__, 1133 enum blackhawk_tsc_pll_refclk_enum refclk, 1134 uint32_t vco_freq_khz) { 1135 return blackhawk_tsc_INTERNAL_configure_pll(sa__, refclk, BLACKHAWK_TSC_PLL_DIV_UNKNOWN, vco_freq_khz, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV4_EN); 1136 } 1137 1138 err_code_t blackhawk_tsc_configure_pll_div_vco_div4refclk(srds_access_t *sa__, 1139 enum blackhawk_tsc_pll_div_enum srds_div, 1140 uint32_t vco_freq_khz) { 1141 return blackhawk_tsc_INTERNAL_configure_pll(sa__, BLACKHAWK_TSC_PLL_REFCLK_UNKNOWN, srds_div, vco_freq_khz, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV4_EN); 1142 } 1143 1144 err_code_t blackhawk_tsc_configure_pll_refclk_div_refclk_2x(srds_access_t *sa__, 1145 enum blackhawk_tsc_pll_refclk_enum refclk, 1146 enum blackhawk_tsc_pll_div_enum srds_div) { 1147 return blackhawk_tsc_INTERNAL_configure_pll(sa__, refclk, srds_div, 0, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DOUBLER_EN); 1148 } 1149 1150 err_code_t blackhawk_tsc_configure_pll_refclk_vco_refclk_2x(srds_access_t *sa__, 1151 enum blackhawk_tsc_pll_refclk_enum refclk, 1152 uint32_t vco_freq_khz) { 1153 return blackhawk_tsc_INTERNAL_configure_pll(sa__, refclk, BLACKHAWK_TSC_PLL_DIV_UNKNOWN, vco_freq_khz, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DOUBLER_EN); 1154 } 1155 1156 err_code_t blackhawk_tsc_configure_pll_div_vco_refclk_2x(srds_access_t *sa__, 1157 enum blackhawk_tsc_pll_div_enum srds_div, 1158 uint32_t vco_freq_khz) { 1159 return blackhawk_tsc_INTERNAL_configure_pll(sa__, BLACKHAWK_TSC_PLL_REFCLK_UNKNOWN, srds_div, vco_freq_khz, BLACKHAWK_TSC_PLL_OPTION_REFCLK_DOUBLER_EN); 1160 } 1161 1162 err_code_t blackhawk_tsc_get_vco_from_refclk_div(srds_access_t *sa__, uint32_t refclk_freq_hz, enum blackhawk_tsc_pll_div_enum srds_div, uint32_t *vco_freq_khz, enum blackhawk_tsc_pll_option_enum pll_option) { 1163 EFUN(blackhawk_tsc_INTERNAL_get_vco_from_refclk_div(sa__, refclk_freq_hz, srds_div, vco_freq_khz, pll_option)); 1164 return (ERR_CODE_NONE); 1165 } 1166 1167 1168 /***********************************************/ 1169 /* Microcode Load into Program RAM Functions */ 1170 /***********************************************/ 1171 1172 /* uCode Load through Register (MDIO) Interface [Return Val = Error_Code (0 = PASS)] */ 1173 err_code_t blackhawk_tsc_ucode_mdio_load(srds_access_t *sa__, uint8_t *ucode_image, uint32_t ucode_len) { 1174 uint32_t ucode_len_padded, count = 0; 1175 uint16_t wrdata_lsw; 1176 uint8_t wrdata_lsb; 1177 1178 if(!ucode_image) { 1179 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1180 } 1181 1182 if (ucode_len > UCODE_MAX_SIZE) { /* uCode size should be less than UCODE_MAX_SIZE */ 1183 return (blackhawk_tsc_error(sa__, ERR_CODE_INVALID_UCODE_LEN)); 1184 } 1185 1186 EFUN(wrc_micro_master_clk_en(0x1)); /* Enable clock to microcontroller subsystem */ 1187 EFUN(wrc_micro_master_rstb(0x1)); /* De-assert reset to microcontroller sybsystem */ 1188 EFUN(wrc_micro_master_rstb(0x0)); /* Assert reset to microcontroller sybsystem - Toggling reset*/ 1189 EFUN(wrc_micro_master_rstb(0x1)); /* De-assert reset to microcontroller sybsystem */ 1190 EFUN(wrc_micro_cr_access_en(1)); /* Allow access to Code RAM */ 1191 1192 EFUN(wrc_micro_ra_init(0x1)); /* Set initialization command to initialize code RAM */ 1193 EFUN(blackhawk_tsc_INTERNAL_poll_micro_ra_initdone(sa__, 250)); /* Poll for micro_ra_initdone = 1 to indicate initialization done */ 1194 1195 EFUN(wrc_micro_ra_init(0x2)); /* Write command for data RAM initialization */ 1196 EFUN(blackhawk_tsc_INTERNAL_poll_micro_ra_initdone(sa__, 250)); /* Poll status of data RAM initialization */ 1197 1198 EFUN(wrc_micro_ra_init(0x0)); /* Clear initialization command */ 1199 EFUN(wrc_micro_cr_crc_prtsel(0)); 1200 EFUN(wrc_micro_cr_crc_init(1)); /* Initialize the HW CRC calculation */ 1201 EFUN(wrc_micro_cr_crc_init(0)); 1202 EFUN(wrc_micro_cr_crc_calc_en(1)); 1203 EFUN(wrc_micro_cr_ignore_micro_code_writes(0)); /* Allow writing to program RAM */ 1204 1205 ucode_len_padded = ((ucode_len + 3) & 0xFFFFFFFC); /* Aligning ucode size to 4-byte boundary */ 1206 1207 /* Code to Load microcode */ 1208 EFUN(wrc_micro_autoinc_wraddr_en(0x1)); /* To auto increment RAM write address */ 1209 EFUN(wrc_micro_ra_wrdatasize(0x1)); /* Select 16bit transfers */ 1210 EFUN(wrc_micro_ra_wraddr_msw(0x0)); /* Upper 16bits of start address of Program RAM where the ucode is to be loaded */ 1211 EFUN(wrc_micro_ra_wraddr_lsw(0x0)); /* Lower 16bits of start address of Program RAM where the ucode is to be loaded */ 1212 1213 do { /* ucode_image loaded 16bits at a time */ 1214 wrdata_lsb = (count < ucode_len) ? ucode_image[count] : 0x0; /* wrdata_lsb read from ucode_image; zero padded to 4byte boundary */ 1215 count++; 1216 wrdata_lsw = (count < ucode_len) ? ucode_image[count] : 0x0; /* wrdata_msb read from ucode_image; zero padded to 4byte boundary */ 1217 count++; 1218 wrdata_lsw = ((wrdata_lsw << 8) | wrdata_lsb); /* 16bit wrdata_lsw formed from 8bit msb and lsb values read from ucode_image */ 1219 EFUN(wrc_micro_ra_wrdata_lsw(wrdata_lsw)); /* Program RAM lower 16bits write data */ 1220 } while (count < ucode_len_padded); /* Loop repeated till entire image loaded (upto the 4byte boundary) */ 1221 1222 EFUN(wrc_micro_ra_wrdatasize(0x2)); /* Select 32bit transfers as default */ 1223 EFUN(wrc_micro_cr_ignore_micro_code_writes(1)); /* block writing to program RAM */ 1224 EFUN(wrc_micro_cr_crc_calc_en(0)); 1225 1226 { 1227 uint8_t micro_orig, num_micros, micro_idx; 1228 ESTM(micro_orig = blackhawk_tsc_get_micro_idx(sa__)); 1229 EFUN(blackhawk_tsc_get_micro_num_uc_cores(sa__, &num_micros)); 1230 for (micro_idx = 0; micro_idx < num_micros; micro_idx++) { 1231 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_idx)); 1232 EFUN(wrc_micro_core_clk_en(0x1)); /* Enable clock to M0 core */ 1233 } 1234 EFUN(blackhawk_tsc_set_micro_idx(sa__, micro_orig)); 1235 } 1236 /* EFUN(wrc_micro_core_rstb(0x1)); */ /* De-assert reset to micro to start executing microcode */ 1237 return (ERR_CODE_NONE); /* NO Errors while loading microcode (uCode Load PASS) */ 1238 } 1239 1240 1241 /* Read-back uCode from Program RAM and verify against ucode_image [Return Val = Error_Code (0 = PASS)] */ 1242 err_code_t blackhawk_tsc_ucode_load_verify(srds_access_t *sa__, uint8_t *ucode_image, uint32_t ucode_len) { 1243 1244 uint32_t ucode_len_padded, count = 0; 1245 uint16_t rddata_lsw; 1246 uint16_t data_lsw; 1247 uint8_t rddata_lsb; 1248 1249 if(!ucode_image) { 1250 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1251 } 1252 1253 ucode_len_padded = ((ucode_len + 3) & 0xFFFFFFFC); /* Aligning ucode size to 4-byte boundary */ 1254 1255 if (ucode_len_padded > UCODE_MAX_SIZE) { /* uCode size should be less than UCODE_MAX_SIZE */ 1256 return (blackhawk_tsc_error(sa__, ERR_CODE_INVALID_UCODE_LEN)); 1257 } 1258 1259 EFUN(wrc_micro_autoinc_rdaddr_en(0x1)); /* To auto increment RAM read address */ 1260 EFUN(wrc_micro_ra_rddatasize(0x1)); /* Select 16bit transfers */ 1261 EFUN(wrc_micro_ra_rdaddr_msw(0x0)); /* Upper 16bits of start address of Program RAM from where to read ucode */ 1262 EFUN(wrc_micro_ra_rdaddr_lsw(0x0)); /* Lower 16bits of start address of Program RAM from where to read ucode */ 1263 1264 do { /* ucode_image read 16bits at a time */ 1265 rddata_lsb = (count < ucode_len) ? ucode_image[count] : 0x0; /* rddata_lsb read from ucode_image; zero padded to 4byte boundary */ 1266 count++; 1267 rddata_lsw = (count < ucode_len) ? ucode_image[count] : 0x0; /* rddata_msb read from ucode_image; zero padded to 4byte boundary */ 1268 count++; 1269 rddata_lsw = ((rddata_lsw << 8) | rddata_lsb); /* 16bit rddata_lsw formed from 8bit msb and lsb values read from ucode_image */ 1270 /* Compare Program RAM ucode to ucode_image (Read to micro_ra_rddata_lsw reg auto-increments the ram_address) */ 1271 ESTM(data_lsw = rdc_micro_ra_rddata_lsw()); 1272 if (data_lsw != rddata_lsw) { 1273 EFUN_PRINTF(("Ucode_Load_Verify_FAIL: Addr = 0x%x: Read_data = 0x%x : Expected_data = 0x%x \n",(count-2),data_lsw,rddata_lsw)); 1274 return (blackhawk_tsc_error(sa__, ERR_CODE_UCODE_VERIFY_FAIL)); /* Verify uCode FAIL */ 1275 } 1276 1277 } while (count < ucode_len_padded); /* Loop repeated till entire image loaded (upto the 4byte boundary) */ 1278 1279 EFUN(wrc_micro_ra_rddatasize(0x2)); /* Select 32bit transfers ad default */ 1280 return (ERR_CODE_NONE); /* Verify uCode PASS */ 1281 } 1282 1283 /******************************************************************/ 1284 /* APIs to Align TX clocks */ 1285 /******************************************************************/ 1286 err_code_t blackhawk_tsc_tx_clock_align(srds_access_t *sa__, int num_lanes, int enable) { 1287 int current_lane, lane; 1288 1289 ESTM(current_lane = blackhawk_tsc_get_lane(sa__)); 1290 1291 for(lane = 0;lane<num_lanes;++lane) { 1292 EFUN(blackhawk_tsc_set_lane(sa__,lane)); 1293 if(enable) { 1294 if(lane == current_lane) { /* Current Lane should be the master lane */ 1295 EFUN(wr_ams_tx_sel_txmaster(1)); /* Select one lane as txmaster. For all other lanes, this should be 0. */ 1296 } else { 1297 /* Initial TX lane clock phase alignment. Program following registers only for slave lanes, master lane registers should not be programmed (can be kept in default values). */ 1298 EFUN(wr_tx_pi_pd_bypass_vco(1)); /* for quick phase lock time */ 1299 EFUN(wr_tx_pi_pd_bypass_flt(1)); /* for quick phase lock time */ 1300 #ifdef wr_tx_pi_hs_fifo_phserr_sel 1301 EFUN(wr_tx_pi_hs_fifo_phserr_sel(1)); /* selects PD from afe as input */ 1302 #else 1303 EFUN(wr_tx_pi_repeater_mode_en(1)); /* selects external PD from afe as input to tx_pi */ 1304 #endif 1305 #ifdef wr_tx_pi_ext_pd_sel 1306 EFUN(wr_tx_pi_ext_pd_sel(0)); /* selects PD path based on tx_pi_repeater_mode_en */ 1307 #endif 1308 EFUN(wr_tx_pi_en(1)); /* Enable TX_PI */ 1309 EFUN(wr_tx_pi_jitter_filter_en(0)); /* turn off frequency lock for tx_pi as all te tclk clocks are derived from VCO and same frequency */ 1310 EFUN(wr_tx_pi_ext_ctrl_en(1)); /* turn on PD path to TX_PI to lock the clocks */ 1311 EFUN(USR_DELAY_US(25)); /* wait for the slave lane clocks to lock to the master lane clock */ 1312 EFUN(wr_tx_pi_ext_phase_bwsel_integ(3)); /* 0 to 7: higher value means faster lock time */ 1313 EFUN(wr_tx_pi_pd_bypass_vco(0)); /* disable filter bypass for more accurate lock */ 1314 EFUN(wr_tx_pi_pd_bypass_flt(0)); /* disable filter bypass for more accurate lock */ 1315 EFUN(USR_DELAY_US(60)); /* wait for the slave lane clocks to lock to the master lane clock withing 1/16th of UI. */ 1316 /* that all TX lane clocks are correct frequency and aligned together within 1/16th of UI. */ 1317 } 1318 1319 } else { 1320 if(lane == current_lane) { /* Current Lane should be the master lane */ 1321 EFUN(wr_ams_tx_sel_txmaster(0)); /* Select one lane as txmaster. For all other lanes, this should be 0. */ 1322 } else { 1323 /* Initial TX lane clock phase alignment. Program following registers only for slave lanes, master lane registers should not be programmed (can be kept in default values). */ 1324 EFUN(wr_tx_pi_pd_bypass_vco(0)); /* for quick phase lock time */ 1325 EFUN(wr_tx_pi_pd_bypass_flt(0)); /* for quick phase lock time */ 1326 #ifdef wr_tx_pi_hs_fifo_phserr_sel 1327 EFUN(wr_tx_pi_hs_fifo_phserr_sel(0)); /* selects PD from afe as input */ 1328 #else 1329 EFUN(wr_tx_pi_repeater_mode_en(1)); /* selects external PD from afe as input to tx_pi */ 1330 #endif 1331 #ifdef wr_tx_pi_ext_pd_sel 1332 EFUN(wr_tx_pi_ext_pd_sel(0)); /* selects PD path based on tx_pi_repeater_mode_en */ 1333 #endif 1334 EFUN(wr_tx_pi_en(0)); /* Enable TX_PI */ 1335 EFUN(wr_tx_pi_jitter_filter_en(0)); /* turn off frequency lock for tx_pi as all te tclk clocks are derived from VCO and same frequency */ 1336 EFUN(wr_tx_pi_ext_ctrl_en(0)); /* turn on PD path to TX_PI to lock the clocks */ 1337 EFUN(wr_tx_pi_ext_phase_bwsel_integ(0)); /* 0 to 7: higher value means faster lock time */ 1338 EFUN(wr_tx_pi_pd_bypass_vco(0)); /* disable filter bypass for more accurate lock */ 1339 /* that all TX lane clocks are correct frequency and aligned together within 1/16th of UI. */ 1340 } 1341 1342 } 1343 } 1344 EFUN(blackhawk_tsc_set_lane(sa__,current_lane)); /* return lane to previous state */ 1345 return(ERR_CODE_NONE); 1346 }