blackhawk_tsc_internal.c (114651B)
1 /*********************************************************************************** 2 *********************************************************************************** 3 * File Name : blackhawk_tsc_internal.c * 4 * Created On : 13/02/2014 * 5 * Created By : Justin Gaither * 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_internal.c 23 * Implementation of API functions 24 */ 25 #include <phymod/phymod_system.h> 26 #include "blackhawk_tsc_internal.h" 27 #include "blackhawk_tsc_internal_error.h" 28 #include "blackhawk_tsc_access.h" 29 #include "blackhawk_tsc_common.h" 30 #include "blackhawk_tsc_config.h" 31 #include "blackhawk_tsc_functions.h" 32 #include "blackhawk_tsc_select_defns.h" 33 #include "blackhawk_tsc_prbs.h" 34 #include "blackhawk_tsc_debug_functions.h" 35 36 37 38 39 /* If SERDES_EVAL is defined, then is_ate_log_enabled() is queried to *\ 40 \* know whether to log ATE. blackhawk_tsc_access.h provides that function. */ 41 uint32_t blackhawk_tsc_INTERNAL_mult_with_overflow_check(uint32_t a, uint32_t b, uint8_t *of) { 42 uint16_t c,d; 43 uint32_t r,s; 44 if (a > b) return blackhawk_tsc_INTERNAL_mult_with_overflow_check(b, a, of); 45 *of = 0; 46 c = b >> 16; 47 d = UINT16_MAX & b; 48 r = a * c; 49 s = a * d; 50 if (r > UINT16_MAX) *of = 1; 51 r <<= 16; 52 return (s + r); 53 } 54 55 #ifdef SERDES_MULTI_INFO_TABLE_EN 56 srds_info_t blackhawk_tsc_info[NUM_SERDES_INFO_TABLES]; 57 #endif 58 59 60 srds_info_t *blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr_with_check(srds_access_t *sa__) { 61 err_code_t err_code = ERR_CODE_NONE; 62 srds_info_t * blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr(sa__); 63 #ifdef PHYMOD_SUPPORT 64 if ( blackhawk_tsc_info_ptr == NULL ) { 65 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 66 } else if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) { 67 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 68 } 69 #endif /* PHYMOD_SUPPORT */ 70 if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) { 71 err_code = blackhawk_tsc_init_blackhawk_tsc_info(sa__); 72 if (err_code != ERR_CODE_NONE){ 73 EFUN_PRINTF(("ERROR: %s Failed: 0x%04X \n", API_FUNCTION_NAME, err_code)); 74 return 0; 75 } 76 } 77 return blackhawk_tsc_info_ptr; 78 } 79 80 err_code_t blackhawk_tsc_INTERNAL_match_ucode_from_info(srds_access_t *sa__) { 81 uint16_t ucode_version_major; 82 uint8_t ucode_version_minor; 83 uint32_t ucode_version; 84 85 srds_info_t * blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr(sa__); 86 CHECK_AND_RETURN_IF_NULL(blackhawk_tsc_info_ptr, ERR_CODE_INVALID_INFO_TABLE_ADDR); 87 88 ESTM(ucode_version_major = rdcv_common_ucode_version()); 89 ESTM(ucode_version_minor = rdcv_common_ucode_minor_version()); 90 ucode_version = (ucode_version_major << 8) | ucode_version_minor; 91 if (ucode_version == blackhawk_tsc_info_ptr->ucode_version) { 92 return(ERR_CODE_NONE); 93 } else { 94 EFUN_PRINTF(("ERROR: ucode version of the current thread not matching with stored blackhawk_tsc_info->ucode_version, Expected 0x%08X, but received 0x%08X.\n", 95 blackhawk_tsc_info_ptr->ucode_version, ucode_version)); 96 return(ERR_CODE_UCODE_VERIFY_FAIL); 97 } 98 } 99 100 err_code_t blackhawk_tsc_INTERNAL_verify_blackhawk_tsc_info(srds_info_t *blackhawk_tsc_info_ptr, srds_access_t *sa__) 101 { 102 err_code_t err_code = ERR_CODE_NONE; 103 104 CHECK_AND_RETURN_IF_NULL(blackhawk_tsc_info_ptr, ERR_CODE_INVALID_INFO_TABLE_ADDR); 105 106 if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) { 107 EFUN_PRINTF(("ERROR: Mismatch in blackhawk_tsc_info signature. Expected 0x%08X, but received 0x%08X.\n", 108 SRDS_INFO_SIGNATURE, blackhawk_tsc_info_ptr->signature)); 109 return (blackhawk_tsc_error(sa__, ERR_CODE_INFO_TABLE_ERROR)); 110 } 111 err_code = blackhawk_tsc_INTERNAL_match_ucode_from_info(sa__); 112 if (err_code != ERR_CODE_NONE) { 113 /* ucode version mismatch */ 114 return(ERR_CODE_MICRO_INIT_NOT_DONE); 115 } 116 return (ERR_CODE_NONE); 117 } 118 119 120 int blackhawk_tsc_osr_mode_enum_to_int_x1000(uint8_t osr_mode) { 121 switch(osr_mode) { 122 case BLACKHAWK_TSC_OSX1: return 1000; 123 case BLACKHAWK_TSC_OSX2: return 2000; 124 case BLACKHAWK_TSC_OSX4: return 4000; 125 case BLACKHAWK_TSC_OSX8: return 8000; 126 case BLACKHAWK_TSC_OSX16P5: return 16500; 127 case BLACKHAWK_TSC_OSX20P625: return 20625; 128 case BLACKHAWK_TSC_OSX16: return 16000; 129 case BLACKHAWK_TSC_OSX32: return 32000; 130 case BLACKHAWK_TSC_OSX21P25: return 21250; 131 #ifdef wr_ams_rx_rxclk_div2p5 132 case BLACKHAWK_TSC_OSX2P5: return 2500; 133 #endif 134 default: return 1000; 135 } 136 } 137 138 err_code_t blackhawk_tsc_INTERNAL_get_num_bits_per_ms(srds_access_t *sa__, uint32_t *num_bits_per_ms) { 139 uint8_t osr_mode = 0; 140 #if defined(rd_rx_pam4_mode) 141 uint8_t pam4_mode = 0; 142 #endif 143 uint8_t pll_select = 0, prev_pll = 0; 144 struct blackhawk_tsc_uc_core_config_st core_config = {{0}}; 145 146 { 147 blackhawk_tsc_osr_mode_st osr_mode_st; 148 ENULL_MEMSET(&osr_mode_st, 0, sizeof(blackhawk_tsc_osr_mode_st)); 149 EFUN(blackhawk_tsc_INTERNAL_get_osr_mode(sa__, &osr_mode_st)); 150 osr_mode = osr_mode_st.rx; 151 } 152 153 #if defined(rd_rx_pam4_mode) 154 ESTM(pam4_mode = rd_rx_pam4_mode()); 155 #endif 156 157 #if defined(rd_rx_pll_select) 158 ESTM(prev_pll = blackhawk_tsc_get_pll_idx(sa__)); 159 ESTM(pll_select = rd_rx_pll_select()); 160 EFUN(blackhawk_tsc_set_pll_idx(sa__,pll_select)); 161 #endif 162 EFUN(blackhawk_tsc_get_uc_core_config(sa__, &core_config)); 163 *num_bits_per_ms = (((uint32_t)core_config.vco_rate_in_Mhz * 100000UL) / blackhawk_tsc_osr_mode_enum_to_int_x1000(osr_mode))*10; 164 165 #if defined(rd_rx_pam4_mode) 166 if(pam4_mode > 0) *num_bits_per_ms <<= 1; 167 #endif 168 EFUN(blackhawk_tsc_set_pll_idx(sa__,prev_pll)); 169 return(ERR_CODE_NONE); 170 } 171 172 err_code_t blackhawk_tsc_INTERNAL_display_BER(srds_access_t *sa__, uint16_t time_ms) { 173 char string[10]; 174 EFUN(blackhawk_tsc_INTERNAL_get_BER_string(sa__,time_ms,string)); 175 USR_PRINTF(("%s",string)); 176 return(ERR_CODE_NONE); 177 } 178 179 err_code_t blackhawk_tsc_INTERNAL_get_BER_string(srds_access_t *sa__, uint16_t time_ms, char *string) { 180 char string2[3]; 181 struct ber_data_st ber_data_local; 182 183 ENULL_MEMSET(&ber_data_local, 0, sizeof(ber_data_local)); 184 if(string == NULL) { 185 return(ERR_CODE_BAD_PTR_OR_INVALID_INPUT); 186 } 187 188 EFUN(blackhawk_tsc_INTERNAL_get_BER_data(sa__, time_ms, &ber_data_local, USE_HW_TIMERS)); 189 190 if(ber_data_local.prbs_chk_en == 0) { 191 USR_STRCPY(string,""); 192 return(ERR_CODE_NONE); 193 } else { 194 USR_STRCPY(string2," "); 195 } 196 197 if((COMPILER_64_HI(ber_data_local.num_errs) == 0) && 198 (COMPILER_64_LO(ber_data_local.num_errs) < 3) && 199 (ber_data_local.lcklost == 0)) { /* lcklost = 0 */ 200 USR_STRNCAT(string2,"<",1); 201 COMPILER_64_SET(ber_data_local.num_errs, 0, 3); 202 } else { 203 USR_STRNCAT(string2," ",1); 204 } 205 if(ber_data_local.lcklost == 1) { /* lcklost = 1 */ 206 USR_STRCPY(string," !Lock "); 207 } else { /* lcklost = 0 */ 208 uint16_t x=0,y=0,z=0,srds_div; 209 210 if(COMPILER_64_GE(ber_data_local.num_errs, ber_data_local.num_bits)) { 211 x = 1;y=0;z=0; 212 }else { 213 uint64_t temp_dividend; 214 uint64_t temp_divisor; 215 while(1) { 216 COMPILER_64_COPY(temp_dividend, ber_data_local.num_errs); 217 COMPILER_64_SHL(temp_dividend, 1); 218 COMPILER_64_ADD_64(temp_dividend, ber_data_local.num_bits); 219 220 COMPILER_64_COPY(temp_divisor, ber_data_local.num_bits); 221 COMPILER_64_SHL(temp_divisor, 1); 222 223 COMPILER_64_UDIV_64(temp_dividend, temp_divisor); 224 225 srds_div = (uint16_t) COMPILER_64_LO( temp_dividend ); 226 227 if(srds_div>=10) { 228 break; 229 } 230 231 COMPILER_64_UMUL_32(ber_data_local.num_errs, 10); 232 z=z+1; 233 } 234 if(srds_div>=100) { 235 srds_div = srds_div/10; 236 z=z-1; 237 } 238 x=srds_div/10; 239 y = srds_div - 10*x; 240 z=z-1; 241 } 242 USR_SPRINTF(string,"%s%d.%1de-%02d",string2,x,y,z); 243 244 } 245 return(ERR_CODE_NONE); 246 247 } 248 249 err_code_t blackhawk_tsc_INTERNAL_get_BER_data(srds_access_t *sa__, uint16_t time_ms, struct ber_data_st *ber_data, enum blackhawk_tsc_prbs_chk_timer_selection_enum timer_sel) { 250 uint8_t lcklost = 0; 251 uint32_t err_cnt= 0; 252 const uint8_t ITER_MAX=10; 253 uint8_t iter=0 ; 254 255 256 if(ber_data == NULL) { 257 return(ERR_CODE_BAD_PTR_OR_INVALID_INPUT); 258 } 259 260 ESTM(ber_data->prbs_chk_en = rd_prbs_chk_en()); 261 if(ber_data->prbs_chk_en == 0) 262 return(ERR_CODE_NONE); 263 264 /* hardware timer's limitation - 448ms Max */ 265 if((time_ms <= PRBS_MAX_HW_TIMER_TIMEOUT) && (timer_sel == USE_HW_TIMERS)) { 266 uint8_t prbs_chk_mode_bak = 0; 267 uint32_t num_bits_per_ms=0; 268 uint16_t time_ms_adjusted = 0; 269 uint8_t prbs_chk_lock = 0; 270 struct prbs_chk_hw_timer_ctrl_st prbs_chk_hw_timer_ctrl_bak; 271 USR_MEMSET(&prbs_chk_hw_timer_ctrl_bak, 0, sizeof(struct prbs_chk_hw_timer_ctrl_st)); 272 /* STEP 1: save prbs chk mode */ 273 ESTM(prbs_chk_mode_bak = rd_prbs_chk_mode()); 274 275 /* STEP 2: force prbs mode 2, initial seed without hysteresis */ /* ??????????????????? */ 276 EFUN(wr_prbs_chk_mode(PRBS_INITIAL_SEED_NO_HYSTERESIS)); 277 278 /* STEP 3: save prbs hardware timer config registers */ 279 EFUN(blackhawk_tsc_get_prbs_chk_hw_timer_ctrl(sa__, &prbs_chk_hw_timer_ctrl_bak)); 280 281 /* STEP 4: Configure hardware timer to count prbs errors */ 282 EFUN(blackhawk_tsc_config_prbs_chk_hw_timer(sa__, time_ms, &time_ms_adjusted)); 283 284 /* STEP 5: Clear prbs error counters and lock lost status */ 285 EFUN(blackhawk_tsc_prbs_err_count_state(sa__, &err_cnt,&lcklost)); /* clear error counters */ 286 287 /* STEP 6: toggle checker enable to start hardware timers and error counters */ 288 EFUN(blackhawk_tsc_prbs_chk_en_toggle(sa__)); 289 290 /* STEP 7: Confirm that prbs lock was achieved */ 291 ESTM(prbs_chk_lock = rd_prbs_chk_lock()); 292 if(!prbs_chk_lock) { 293 /* If prbs lock was not achieved, set lcklost = 1 and skip the wait for error accumulation */ 294 ber_data->lcklost = 1; 295 } else { 296 /* STEP 8: wait time_ms for hardware timeout */ 297 EFUN(USR_DELAY_MS(time_ms_adjusted)); 298 /* STEP 9: Poll prbs_chk_lock to make sure timers expired */ 299 do { 300 EFUN(USR_DELAY_MS(1)); 301 ESTM(prbs_chk_lock = rd_prbs_chk_lock()); 302 iter++; 303 } while(prbs_chk_lock && iter<ITER_MAX); 304 305 if(prbs_chk_lock) { 306 /* timer hasn't expired or it expired and lock didn't go away */ 307 ber_data->lcklost = 1; 308 return ERR_CODE_PRBS_CHK_HW_TIMERS_NOT_EXPIRED; 309 } 310 311 /* STEP 10: Read error counters */ 312 EFUN(blackhawk_tsc_prbs_err_count_state(sa__, &err_cnt,&lcklost)); 313 314 /* STEP 11: Update the BER data structure */ 315 EFUN(blackhawk_tsc_INTERNAL_get_num_bits_per_ms(sa__,&num_bits_per_ms)); 316 COMPILER_64_SET(ber_data->num_bits, 0, num_bits_per_ms); 317 COMPILER_64_UMUL_32(ber_data->num_bits, time_ms_adjusted); 318 COMPILER_64_SET(ber_data->num_errs, 0, err_cnt); 319 /* 320 ber_data->num_bits = (uint64_t)num_bits_per_ms*(uint64_t)time_ms_adjusted; 321 ber_data->num_errs = err_cnt; 322 */ 323 ber_data->lcklost = 0; 324 } 325 /* STEP 12: restore prbs hardware timer config registers */ 326 EFUN(blackhawk_tsc_set_prbs_chk_hw_timer_ctrl(sa__, &prbs_chk_hw_timer_ctrl_bak)); 327 /* STEP 13: Restore prbs check mode */ 328 EFUN(wr_prbs_chk_mode(prbs_chk_mode_bak)); 329 } else 330 { 331 UNUSED(timer_sel); 332 EFUN(USR_DELAY_MS(time_ms)); 333 EFUN(blackhawk_tsc_prbs_err_count_state(sa__, &err_cnt,&lcklost)); 334 ber_data->lcklost = lcklost; 335 if(ber_data->lcklost == 0) { 336 uint32_t num_bits_per_ms=0; 337 EFUN(blackhawk_tsc_INTERNAL_get_num_bits_per_ms(sa__,&num_bits_per_ms)); 338 COMPILER_64_SET(ber_data->num_bits, 0, num_bits_per_ms); 339 COMPILER_64_UMUL_32(ber_data->num_bits, time_ms); 340 COMPILER_64_SET(ber_data->num_errs, 0, err_cnt); 341 /* 342 ber_data->num_bits = (uint64_t)num_bits_per_ms*(uint64_t)time_ms; 343 ber_data->num_errs = err_cnt; 344 */ 345 ESTM(lcklost = rd_prbs_chk_lock_lost_lh()); 346 347 } 348 } 349 350 351 352 return(ERR_CODE_NONE); 353 } 354 355 err_code_t blackhawk_tsc_INTERNAL_get_prbs_timeout_count_from_time(uint16_t time_ms, uint16_t * time_ms_adjusted, struct prbs_chk_hw_timer_ctrl_st * const prbs_chk_hw_timer_ctrl ) { 356 uint8_t timeout_value; 357 uint8_t iter = 0; 358 if(time_ms > PRBS_HW_LUT_MAX_MINUS_1) { 359 UNUSED(timeout_value); 360 *time_ms_adjusted = PRBS_MAX_HW_TIMER_TIMEOUT; 361 return ERR_CODE_NONE; 362 } 363 364 *time_ms_adjusted = time_ms; 365 366 if(time_ms < 8) { /* Linear */ 367 timeout_value = (uint8_t)time_ms; 368 } else { 369 for(iter=8; iter>2; iter--) { 370 if((time_ms>>iter)&0x1) 371 break; 372 } 373 374 timeout_value = ((iter-1)<<2) + ((time_ms>>(iter-2))&(0x3)); 375 376 if((time_ms-((time_ms>>(iter-2))<<(iter-2)))>0) { /* time_ms is not found in the map, using a possible value larger than provided */ 377 timeout_value = timeout_value + 1; 378 *time_ms_adjusted = ((1<<(((timeout_value)>>2)+1)) + (((timeout_value)&3)*(1<<(((timeout_value)>>2)-1)))); 379 } 380 } 381 prbs_chk_hw_timer_ctrl->prbs_chk_en_timeout = timeout_value; 382 prbs_chk_hw_timer_ctrl->prbs_chk_en_timer_mode = 0x3; /* 1ms unit */ 383 return ERR_CODE_NONE; 384 } 385 386 387 388 int16_t blackhawk_tsc_INTERNAL_ladder_setting_to_mV(srds_access_t *sa__, int8_t ctrl, uint8_t range_250) { 389 uint16_t absv; /* Absolute value of ctrl */ 390 int16_t nlmv; /* Non-linear value */ 391 392 /* Get absolute value */ 393 absv = SRDS_ABS(ctrl); 394 395 { 396 UNUSED(range_250); 397 398 nlmv = absv*263/127; 399 } 400 /* Add sign and return */ 401 return( (ctrl>=0) ? nlmv : -nlmv); 402 } 403 404 err_code_t blackhawk_tsc_INTERNAL_pam4_to_bin(srds_access_t *sa__, char var, char bin[]) { 405 if(!bin) { 406 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 407 } 408 409 switch (var) { 410 case '0': ENULL_STRCPY(bin,"00"); 411 break; 412 case '1': ENULL_STRCPY(bin,"01"); 413 break; 414 case '2': ENULL_STRCPY(bin,"11"); /* To account for PAM4 Gray coding */ 415 break; 416 case '3': ENULL_STRCPY(bin,"10"); /* To account for PAM4 Gray coding */ 417 break; 418 case '_': ENULL_STRCPY(bin,""); 419 break; 420 default : ENULL_STRCPY(bin,""); 421 EFUN_PRINTF(("ERROR: Invalid PAM4 format Pattern\n")); 422 return (blackhawk_tsc_error(sa__, ERR_CODE_CFG_PATT_INVALID_PAM4)); 423 } 424 return (ERR_CODE_NONE); 425 } 426 427 err_code_t blackhawk_tsc_INTERNAL_compute_bin(srds_access_t *sa__, char var, char bin[]) { 428 if(!bin) { 429 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 430 } 431 432 switch (var) { 433 case '0': ENULL_STRCPY(bin,"0000"); 434 break; 435 case '1': ENULL_STRCPY(bin,"0001"); 436 break; 437 case '2': ENULL_STRCPY(bin,"0010"); 438 break; 439 case '3': ENULL_STRCPY(bin,"0011"); 440 break; 441 case '4': ENULL_STRCPY(bin,"0100"); 442 break; 443 case '5': ENULL_STRCPY(bin,"0101"); 444 break; 445 case '6': ENULL_STRCPY(bin,"0110"); 446 break; 447 case '7': ENULL_STRCPY(bin,"0111"); 448 break; 449 case '8': ENULL_STRCPY(bin,"1000"); 450 break; 451 case '9': ENULL_STRCPY(bin,"1001"); 452 break; 453 case 'a': 454 case 'A': ENULL_STRCPY(bin,"1010"); 455 break; 456 case 'b': 457 case 'B': ENULL_STRCPY(bin,"1011"); 458 break; 459 case 'c': 460 case 'C': ENULL_STRCPY(bin,"1100"); 461 break; 462 case 'd': 463 case 'D': ENULL_STRCPY(bin,"1101"); 464 break; 465 case 'e': 466 case 'E': ENULL_STRCPY(bin,"1110"); 467 break; 468 case 'f': 469 case 'F': ENULL_STRCPY(bin,"1111"); 470 break; 471 case '_': ENULL_STRCPY(bin,""); 472 break; 473 default : ENULL_STRCPY(bin,""); 474 EFUN_PRINTF(("ERROR: Invalid Hexadecimal Pattern\n")); 475 return (blackhawk_tsc_error(sa__, ERR_CODE_CFG_PATT_INVALID_HEX)); 476 } 477 return (ERR_CODE_NONE); 478 } 479 480 481 err_code_t blackhawk_tsc_INTERNAL_compute_hex(srds_access_t *sa__, char bin[],uint8_t *hex) { 482 if(!hex) { 483 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 484 } 485 486 if (!USR_STRCMP(bin,"0000")) { 487 *hex = 0x0; 488 } 489 else if (!USR_STRCMP(bin,"0001")) { 490 *hex = 0x1; 491 } 492 else if (!USR_STRCMP(bin,"0010")) { 493 *hex = 0x2; 494 } 495 else if (!USR_STRCMP(bin,"0011")) { 496 *hex = 0x3; 497 } 498 else if (!USR_STRCMP(bin,"0100")) { 499 *hex = 0x4; 500 } 501 else if (!USR_STRCMP(bin,"0101")) { 502 *hex = 0x5; 503 } 504 else if (!USR_STRCMP(bin,"0110")) { 505 *hex = 0x6; 506 } 507 else if (!USR_STRCMP(bin,"0111")) { 508 *hex = 0x7; 509 } 510 else if (!USR_STRCMP(bin,"1000")) { 511 *hex = 0x8; 512 } 513 else if (!USR_STRCMP(bin,"1001")) { 514 *hex = 0x9; 515 } 516 else if (!USR_STRCMP(bin,"1010")) { 517 *hex = 0xA; 518 } 519 else if (!USR_STRCMP(bin,"1011")) { 520 *hex = 0xB; 521 } 522 else if (!USR_STRCMP(bin,"1100")) { 523 *hex = 0xC; 524 } 525 else if (!USR_STRCMP(bin,"1101")) { 526 *hex = 0xD; 527 } 528 else if (!USR_STRCMP(bin,"1110")) { 529 *hex = 0xE; 530 } 531 else if (!USR_STRCMP(bin,"1111")) { 532 *hex = 0xF; 533 } 534 else { 535 EFUN_PRINTF(("ERROR: Invalid Binary to Hex Conversion\n")); 536 *hex = 0x0; 537 return (blackhawk_tsc_error(sa__, ERR_CODE_CFG_PATT_INVALID_BIN2HEX)); 538 } 539 return (ERR_CODE_NONE); 540 } 541 542 uint8_t blackhawk_tsc_INTERNAL_stop_micro(srds_access_t *sa__, uint8_t graceful, err_code_t *err_code_p) { 543 uint8_t stop_state = 0; 544 545 if(!err_code_p) { 546 return(0xFF); 547 } 548 549 /* Log current micro stop status */ 550 EPSTM2((stop_state = rdv_usr_sts_micro_stopped()),0xFF); 551 552 /* Stop micro only if micro is not stopped currently */ 553 if (!(stop_state & 0x7F)) { 554 if (graceful) { 555 EPFUN2((blackhawk_tsc_stop_rx_adaptation(sa__, 1)),0xFF); 556 } 557 else { 558 EPFUN2((blackhawk_tsc_pmd_uc_control(sa__, CMD_UC_CTRL_STOP_IMMEDIATE,GRACEFUL_STOP_TIME)),0xFF); 559 } 560 } 561 562 /* Return the previous micro stop status */ 563 return(stop_state); 564 } 565 566 567 568 569 /********************************************************/ 570 /* Global RAM access through Micro Register Interface */ 571 /********************************************************/ 572 /* Micro Global RAM Byte Read */ 573 uint8_t blackhawk_tsc_INTERNAL_rdb_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 574 uint8_t rddata; 575 576 if(!err_code_p) { 577 return(0); 578 } 579 EPSTM(rddata = blackhawk_tsc_rdb_uc_ram(sa__, err_code_p, addr)); /* Use Micro register interface for reading RAM */ 580 return (rddata); 581 } 582 583 /* Micro Global RAM Word Read */ 584 uint16_t blackhawk_tsc_INTERNAL_rdw_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 585 uint16_t rddata; 586 587 if(!err_code_p) { 588 return(0); 589 } 590 if (addr%2 != 0) { /* Validate even address */ 591 *err_code_p = ERR_CODE_INVALID_RAM_ADDR; 592 USR_PRINTF(("Error incorrect addr x%04x\n",addr)); 593 return (0); 594 } 595 EPSTM(rddata = blackhawk_tsc_rdw_uc_ram(sa__, err_code_p, (addr))); /* Use Micro register interface for reading RAM */ 596 return (rddata); 597 } 598 599 /* Micro Global RAM Byte Write */ 600 err_code_t blackhawk_tsc_INTERNAL_wrb_uc_var(srds_access_t *sa__, uint16_t addr, uint8_t wr_val) { 601 602 return (blackhawk_tsc_wrb_uc_ram(sa__, addr, wr_val)); /* Use Micro register interface for writing RAM */ 603 } 604 605 /* Micro Global RAM Word Write */ 606 err_code_t blackhawk_tsc_INTERNAL_wrw_uc_var(srds_access_t *sa__, uint16_t addr, uint16_t wr_val) { 607 if (addr%2 != 0) { /* Validate even address */ 608 USR_PRINTF(("Error incorrect addr x%04x\n",addr)); 609 return (blackhawk_tsc_error(sa__, ERR_CODE_INVALID_RAM_ADDR)); 610 } 611 return (blackhawk_tsc_wrw_uc_ram(sa__, addr, wr_val)); /* Use Micro register interface for writing RAM */ 612 } 613 614 615 /***********************/ 616 /* Event Log Display */ 617 /***********************/ 618 err_code_t blackhawk_tsc_INTERNAL_event_log_dump_callback(void *arg, uint8_t byte_count, uint16_t data) { 619 blackhawk_tsc_INTERNAL_event_log_dump_state_t * const state_ptr = (blackhawk_tsc_INTERNAL_event_log_dump_state_t *)arg; 620 const uint8_t bytes_per_row=16; 621 622 if (byte_count == 0) { 623 if (state_ptr->line_start_index != state_ptr->index) { 624 EFUN_PRINTF(("%*s %d\n", 4*(bytes_per_row - state_ptr->index + state_ptr->line_start_index), "", state_ptr->line_start_index)); 625 } 626 return (ERR_CODE_NONE); 627 } 628 if (byte_count == 1) { 629 /* There is a trailing byte in the event log. 630 * The simplest way to handle it is to print out a whole word, but mask 631 * the invalid upper byte. 632 */ 633 data &= 0xFF; 634 } 635 EFUN_PRINTF((" 0x%04x", ((data & 0xFF) << 8) | (data >> 8))); 636 state_ptr->index += 2; 637 if (state_ptr->index % bytes_per_row == 0) { 638 EFUN_PRINTF((" %d\n", state_ptr->line_start_index)); 639 state_ptr->line_start_index = state_ptr->index; 640 } 641 642 return(ERR_CODE_NONE); 643 } 644 645 err_code_t blackhawk_tsc_INTERNAL_read_event_log_with_callback(srds_access_t *sa__, 646 uint8_t micro_num, 647 uint8_t bypass_micro, 648 void *arg, 649 err_code_t (*callback)(void *, uint8_t, uint16_t)) { 650 uint16_t rd_idx; 651 uint8_t current_lane; 652 srds_info_t * blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr_with_check(sa__); 653 654 #ifdef PHYMOD_SUPPORT 655 if ( blackhawk_tsc_info_ptr == NULL ) { 656 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 657 } else if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) { 658 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 659 } 660 #endif /* PHYMOD_SUPPORT */ 661 662 EFUN(blackhawk_tsc_INTERNAL_verify_blackhawk_tsc_info(blackhawk_tsc_info_ptr, sa__)); 663 664 if (micro_num >= blackhawk_tsc_info_ptr->micro_count) { 665 return (blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 666 } 667 /* Read Current lane so that it can be restored at the end of function */ 668 current_lane = blackhawk_tsc_get_lane(sa__); 669 /* Blackhawk has 2 lanes per micro, set lane appropriate for the desired micro */ 670 EFUN(blackhawk_tsc_set_lane(sa__,micro_num<<1)); 671 EFUN_PRINTF(("\n\n********************************************\n")); 672 EFUN_PRINTF(( "**** SERDES UC TRACE MEMORY DUMP ***********\n")); 673 EFUN_PRINTF(( "********************************************\n")); 674 675 if (bypass_micro) { 676 ESTM(rd_idx = rducv_trace_mem_wr_idx()); 677 if (blackhawk_tsc_info_ptr->trace_memory_descending_writes) { 678 ++rd_idx; 679 if (rd_idx >= blackhawk_tsc_info_ptr->trace_mem_ram_size) { 680 rd_idx = 0; 681 } 682 } else { 683 if (rd_idx == 0) { 684 rd_idx = blackhawk_tsc_info_ptr->trace_mem_ram_size; 685 } 686 --rd_idx; 687 } 688 } else { 689 /* Start Read to stop uC logging and read the word at last event written by uC */ 690 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_EVENT_LOG_READ, CMD_EVENT_LOG_READ_START, GRACEFUL_STOP_TIME)); 691 ESTM(rd_idx = rducv_trace_mem_rd_idx()); 692 } 693 694 EFUN_PRINTF(( "\n DEBUG INFO: trace memory read index = 0x%04x\n", rd_idx)); 695 696 EFUN_PRINTF((" DEBUG INFO: trace memory size = 0x%04x\n\n", blackhawk_tsc_info_ptr->trace_mem_ram_size)); 697 698 if (blackhawk_tsc_info_ptr->trace_memory_descending_writes) { 699 /* Micro writes trace memory using descending addresses. 700 * So read using ascending addresses using block read 701 */ 702 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, 703 blackhawk_tsc_info_ptr->trace_mem_ram_base + blackhawk_tsc_info_ptr->grp_ram_size*micro_num, 704 blackhawk_tsc_info_ptr->trace_mem_ram_size, 705 rd_idx, 706 blackhawk_tsc_info_ptr->trace_mem_ram_size, 707 arg, 708 callback)); 709 } else { 710 /* Micro writes trace memory using descending addresses. 711 * So read using ascending addresses using block read 712 */ 713 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram_descending(sa__, 714 blackhawk_tsc_info_ptr->trace_mem_ram_base + blackhawk_tsc_info_ptr->grp_ram_size*micro_num, 715 blackhawk_tsc_info_ptr->trace_mem_ram_size, 716 rd_idx, 717 blackhawk_tsc_info_ptr->trace_mem_ram_size, 718 arg, 719 callback)); 720 } 721 722 if (!bypass_micro) { 723 /* Read Done to resume logging */ 724 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_EVENT_LOG_READ, CMD_EVENT_LOG_READ_DONE, 50)); 725 } 726 EFUN(blackhawk_tsc_set_lane(sa__,current_lane)); 727 return(ERR_CODE_NONE); 728 } 729 730 #ifdef TO_FLOATS 731 /* convert uint32_t to float8 */ 732 float8_t blackhawk_tsc_INTERNAL_int32_to_float8(uint32_t input) { 733 int8_t cnt; 734 uint8_t output; 735 736 if(input == 0) { 737 return(0); 738 } else if(input == 1) { 739 return(0xe0); 740 } else { 741 cnt = 0; 742 input = input & 0x7FFFFFFF; /* get rid of MSB which may be lock indicator */ 743 do { 744 input = input << 1; 745 cnt++; 746 } while ((input & 0x80000000) == 0); 747 748 output = (uint8_t)((input & 0x70000000)>>23)+(31 - cnt%32); 749 return(output); 750 } 751 } 752 #endif 753 754 /* convert float8 to uint32_t */ 755 uint32_t blackhawk_tsc_INTERNAL_float8_to_int32(float8_t input) { 756 uint32_t x; 757 if(input == 0) return(0); 758 x = (input>>5) + 8; 759 if((input & 0x1F) < 3) { 760 return(x>>(3-(input & 0x1f))); 761 } 762 return(x<<((input & 0x1F)-3)); 763 } 764 765 /* Convert uint8 to 8-bit gray code */ 766 uint8_t blackhawk_tsc_INTERNAL_uint8_to_gray(uint8_t input) { 767 return input ^ (input >> 1); 768 } 769 770 /* Convert 8-bit gray code to uint8 */ 771 uint8_t blackhawk_tsc_INTERNAL_gray_to_uint8(uint8_t input) { 772 input = input ^ (input >> 4); 773 input = input ^ (input >> 2); 774 input = input ^ (input >> 1); 775 return input; 776 } 777 778 /* Convert seconds to hr:min:sec */ 779 uint8_t blackhawk_tsc_INTERNAL_seconds_to_displayformat(uint32_t seconds, uint8_t *hrs, uint8_t *mins, uint8_t *secs) { 780 *hrs = (seconds / 3600); 781 seconds = (seconds % 3600); 782 *mins = (seconds / 60); 783 *secs = (seconds % 60); 784 return(ERR_CODE_NONE); 785 } 786 787 /* convert float12 to uint32 */ 788 uint32_t blackhawk_tsc_INTERNAL_float12_to_uint32(uint8_t input, uint8_t multi) { 789 790 return(((uint32_t)input)<<multi); 791 } 792 793 794 err_code_t blackhawk_tsc_INTERNAL_set_rx_pf_main(srds_access_t *sa__, uint8_t val) { 795 if (val > 31) 796 { 797 return (blackhawk_tsc_error(sa__, ERR_CODE_PF_INVALID)); 798 } 799 EFUN(WR_RX_PF_CTRL(val)); 800 return(ERR_CODE_NONE); 801 } 802 803 err_code_t blackhawk_tsc_INTERNAL_get_rx_pf_main(srds_access_t *sa__, uint8_t *val) { 804 ESTM(*val = RD_RX_PF_CTRL()); 805 return (ERR_CODE_NONE); 806 } 807 808 err_code_t blackhawk_tsc_INTERNAL_set_rx_pf2(srds_access_t *sa__, uint8_t val) { 809 if (val > 7) { 810 return (blackhawk_tsc_error(sa__, ERR_CODE_PF_INVALID)); 811 } 812 EFUN(WR_RX_PF2_CTRL(val)); 813 return(ERR_CODE_NONE); 814 } 815 816 err_code_t blackhawk_tsc_INTERNAL_get_rx_pf2(srds_access_t *sa__, uint8_t *val) { 817 ESTM(*val = RD_RX_PF2_CTRL()); 818 return (ERR_CODE_NONE); 819 } 820 821 err_code_t blackhawk_tsc_INTERNAL_set_rx_pf3(srds_access_t *sa__, uint8_t val) { 822 if (val > 15) { 823 return (blackhawk_tsc_error(sa__, ERR_CODE_PF_INVALID)); 824 } 825 EFUN(wr_ams_rx_pf3_ctrl(blackhawk_tsc_INTERNAL_uint8_to_gray(val))); 826 return(ERR_CODE_NONE); 827 } 828 829 err_code_t blackhawk_tsc_INTERNAL_get_rx_pf3(srds_access_t *sa__, uint8_t *val) { 830 ESTM(*val = blackhawk_tsc_INTERNAL_gray_to_uint8(rd_ams_rx_pf3_ctrl())); 831 return (ERR_CODE_NONE); 832 } 833 834 err_code_t blackhawk_tsc_INTERNAL_set_rx_vga(srds_access_t *sa__, uint8_t val) { 835 836 EFUN(blackhawk_tsc_INTERNAL_check_uc_lane_stopped(sa__)); /* make sure uC is stopped to avoid race conditions */ 837 838 if (val > RX_VGA_CTRL_VAL_MAX) { 839 return (blackhawk_tsc_error(sa__, ERR_CODE_VGA_INVALID)); 840 } 841 #if defined(RX_VGA_CTRL_VAL_MIN) && (RX_VGA_CTRL_VAL_MIN > 0) 842 if (val < RX_VGA_CTRL_VAL_MIN) { 843 return (blackhawk_tsc_error(sa__, ERR_CODE_VGA_INVALID)); 844 } 845 #endif 846 847 EFUN(wr_rx_vga_val(val)); 848 return(ERR_CODE_NONE); 849 } 850 851 err_code_t blackhawk_tsc_INTERNAL_get_rx_vga(srds_access_t *sa__, uint8_t *val) { 852 ESTM(*val = rd_rx_vga_status()); 853 return (ERR_CODE_NONE); 854 } 855 856 857 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe1(srds_access_t *sa__, int8_t val) { 858 enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ; 859 EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode)); 860 861 if(pam_mode != NRZ) { 862 EFUN_PRINTF(("ERROR: RX DFE1 is only available in NRZ mode\n")); 863 return(ERR_CODE_INVALID_RX_PAM_MODE); 864 } 865 EFUN(blackhawk_tsc_INTERNAL_check_uc_lane_stopped(sa__)); /* make sure uC is stopped to avoid race conditions */ 866 867 EFUN(wr_rx_afe_override_sel(1)); /* Select data23 slicer */ 868 EFUN(wr_rx_afe_override_val(val)); 869 EFUN(wr_rx_afe_override_write(1)); 870 return(ERR_CODE_NONE); 871 } 872 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe1(srds_access_t *sa__, int8_t *val) { 873 { 874 enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ; 875 EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode)); 876 877 if(pam_mode != NRZ) { 878 EFUN_PRINTF(("ERROR: RX DFE1 is only available in NRZ mode (core %d lane %d)\n",blackhawk_tsc_get_core(sa__),blackhawk_tsc_get_lane(sa__))); 879 return(ERR_CODE_INVALID_RX_PAM_MODE); 880 } 881 } 882 ESTM(*val = (int8_t)rd_rx_data23_status()); 883 return (ERR_CODE_NONE); 884 } 885 886 887 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe2(srds_access_t *sa__, int8_t val) { 888 if ((val > 15) || (val < -15)) 889 { 890 USR_PRINTF(("Exceeded range of DFE tap limit = 15, request %d\n",val)); 891 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 892 } 893 EFUN(wr_rx_afe_override_sel(6)); 894 EFUN(wr_rxa_dfe_tap2_val(val)); 895 EFUN(wr_rxa_dfe_tap2_write(1)); 896 EFUN(wr_rxb_dfe_tap2_val(val)); 897 EFUN(wr_rxb_dfe_tap2_write(1)); 898 EFUN(wr_rxc_dfe_tap2_val(val)); 899 EFUN(wr_rxc_dfe_tap2_write(1)); 900 EFUN(wr_rxd_dfe_tap2_val(val)); 901 EFUN(wr_rxd_dfe_tap2_write(1)); 902 return(ERR_CODE_NONE); 903 } 904 905 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe2(srds_access_t *sa__, int8_t *val) { 906 ESTM(*val = ((rd_rxa_dfe_tap2_status() + rd_rxb_dfe_tap2_status() + rd_rxc_dfe_tap2_status() + rd_rxd_dfe_tap2_status())>>2)); 907 return (ERR_CODE_NONE); 908 } 909 910 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe3(srds_access_t *sa__, int8_t val) { 911 if ((val > 15) || (val < -15)) 912 { 913 USR_PRINTF(("Exceeded range of DFE tap limit = 15, request %d\n",val)); 914 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 915 } 916 EFUN(wr_rx_afe_override_sel(6)); 917 EFUN(wr_rxa_dfe_tap3_val(val)); 918 EFUN(wr_rxa_dfe_tap3_write(1)); 919 EFUN(wr_rxb_dfe_tap3_val(val)); 920 EFUN(wr_rxb_dfe_tap3_write(1)); 921 EFUN(wr_rxc_dfe_tap3_val(val)); 922 EFUN(wr_rxc_dfe_tap3_write(1)); 923 EFUN(wr_rxd_dfe_tap3_val(val)); 924 EFUN(wr_rxd_dfe_tap3_write(1)); 925 return(ERR_CODE_NONE); 926 } 927 928 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe3(srds_access_t *sa__, int8_t *val) { 929 ESTM(*val = (rd_rxa_dfe_tap3_status() + rd_rxb_dfe_tap3_status() + rd_rxc_dfe_tap3_status() + rd_rxd_dfe_tap3_status())>>2); 930 return (ERR_CODE_NONE); 931 } 932 933 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe4(srds_access_t *sa__, int8_t val) { 934 if ((val > 15) || (val < -15)) 935 { 936 USR_PRINTF(("Exceeded range of DFE tap limit = 15, request %d\n",val)); 937 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 938 } 939 EFUN(wr_rxa_dfe_tap4(val)); 940 EFUN(wr_rxb_dfe_tap4(val)); 941 EFUN(wr_rxc_dfe_tap4(val)); 942 EFUN(wr_rxd_dfe_tap4(val)); 943 return(ERR_CODE_NONE); 944 } 945 946 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe4(srds_access_t *sa__, int8_t *val) { 947 ESTM(*val = (rd_rxa_dfe_tap4() + rd_rxb_dfe_tap4() + rd_rxc_dfe_tap4() + rd_rxd_dfe_tap4())>>2); 948 return (ERR_CODE_NONE); 949 } 950 951 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe5(srds_access_t *sa__, int8_t val) { 952 if ((val > 7) || (val < -7)) 953 { 954 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 955 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 956 } 957 EFUN(wr_rxa_dfe_tap5(val)); 958 EFUN(wr_rxb_dfe_tap5(val)); 959 EFUN(wr_rxc_dfe_tap5(val)); 960 EFUN(wr_rxd_dfe_tap5(val)); 961 return(ERR_CODE_NONE); 962 } 963 964 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe5(srds_access_t *sa__, int8_t *val) { 965 ESTM(*val = (rd_rxa_dfe_tap5() + rd_rxb_dfe_tap5() + rd_rxc_dfe_tap5() + rd_rxd_dfe_tap5())>>2); 966 return (ERR_CODE_NONE); 967 } 968 969 970 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe6(srds_access_t *sa__, int8_t val) { 971 if ((val > 7) || (val < -7)) 972 { 973 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 974 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 975 } 976 EFUN(wr_rxa_dfe_tap6(val)); 977 EFUN(wr_rxb_dfe_tap6(val)); 978 EFUN(wr_rxc_dfe_tap6(val)); 979 EFUN(wr_rxd_dfe_tap6(val)); 980 return(ERR_CODE_NONE); 981 } 982 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe6(srds_access_t *sa__, int8_t *val) { 983 ESTM(*val = (rd_rxa_dfe_tap6() + rd_rxb_dfe_tap6() + rd_rxc_dfe_tap6() + rd_rxd_dfe_tap6())>>2); 984 return (ERR_CODE_NONE); 985 } 986 987 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe7(srds_access_t *sa__, int8_t val) { 988 if ((val > 7) || (val < -7)) 989 { 990 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 991 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 992 } 993 EFUN(wr_rxa_dfe_tap7(val)); 994 EFUN(wr_rxb_dfe_tap7(val)); 995 EFUN(wr_rxc_dfe_tap7(val)); 996 EFUN(wr_rxd_dfe_tap7(val)); 997 return(ERR_CODE_NONE); 998 } 999 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe7(srds_access_t *sa__, int8_t *val) { 1000 ESTM(*val = (rd_rxa_dfe_tap7() + rd_rxb_dfe_tap7() + rd_rxc_dfe_tap7() + rd_rxd_dfe_tap7())>>2); 1001 return (ERR_CODE_NONE); 1002 } 1003 1004 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe8(srds_access_t *sa__, int8_t val) { 1005 if ((val > 7) || (val < -7)) 1006 { 1007 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 1008 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 1009 } 1010 EFUN(wr_rxa_dfe_tap8(val)); 1011 EFUN(wr_rxb_dfe_tap8(val)); 1012 EFUN(wr_rxc_dfe_tap8(val)); 1013 EFUN(wr_rxd_dfe_tap8(val)); 1014 return(ERR_CODE_NONE); 1015 } 1016 1017 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe8(srds_access_t *sa__, int8_t *val) { 1018 ESTM(*val = (rd_rxa_dfe_tap8() + rd_rxb_dfe_tap8() + rd_rxc_dfe_tap8() + rd_rxd_dfe_tap8())>>2); 1019 return (ERR_CODE_NONE); 1020 } 1021 1022 1023 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe9(srds_access_t *sa__, int8_t val) { 1024 if ((val > 7) || (val < -7)) 1025 { 1026 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 1027 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 1028 } 1029 EFUN(wr_rxa_dfe_tap9(val)); 1030 EFUN(wr_rxb_dfe_tap9(val)); 1031 EFUN(wr_rxc_dfe_tap9(val)); 1032 EFUN(wr_rxd_dfe_tap9(val)); 1033 return(ERR_CODE_NONE); 1034 } 1035 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe9(srds_access_t *sa__, int8_t *val) { 1036 ESTM(*val = (rd_rxa_dfe_tap9() + rd_rxb_dfe_tap9() + rd_rxc_dfe_tap9() + rd_rxd_dfe_tap9())>>2); 1037 return (ERR_CODE_NONE); 1038 } 1039 1040 1041 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe10(srds_access_t *sa__, int8_t val) { 1042 if ((val > 7) || (val < -7)) 1043 { 1044 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 1045 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 1046 } 1047 EFUN(wr_rxa_dfe_tap10(val)); 1048 EFUN(wr_rxb_dfe_tap10(val)); 1049 EFUN(wr_rxc_dfe_tap10(val)); 1050 EFUN(wr_rxd_dfe_tap10(val)); 1051 return(ERR_CODE_NONE); 1052 } 1053 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe10(srds_access_t *sa__, int8_t *val) { 1054 ESTM(*val = (rd_rxa_dfe_tap10() + rd_rxb_dfe_tap10() + rd_rxc_dfe_tap10() + rd_rxd_dfe_tap10())>>2); 1055 return (ERR_CODE_NONE); 1056 } 1057 1058 1059 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe11(srds_access_t *sa__, int8_t val) { 1060 if ((val > 7) || (val < -7)) 1061 { 1062 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 1063 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 1064 } 1065 EFUN(wr_rxa_dfe_tap11(val)); 1066 EFUN(wr_rxb_dfe_tap11(val)); 1067 EFUN(wr_rxc_dfe_tap11(val)); 1068 EFUN(wr_rxd_dfe_tap11(val)); 1069 return(ERR_CODE_NONE); 1070 } 1071 1072 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe11(srds_access_t *sa__, int8_t *val) { 1073 ESTM(*val = (rd_rxa_dfe_tap11() + rd_rxb_dfe_tap11() + rd_rxc_dfe_tap11() + rd_rxd_dfe_tap11())>>2); 1074 return (ERR_CODE_NONE); 1075 } 1076 1077 1078 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe12(srds_access_t *sa__, int8_t val) { 1079 if ((val > 7) || (val < -7)) 1080 { 1081 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 1082 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 1083 } 1084 EFUN(wr_rxa_dfe_tap12(val)); 1085 EFUN(wr_rxb_dfe_tap12(val)); 1086 EFUN(wr_rxc_dfe_tap12(val)); 1087 EFUN(wr_rxd_dfe_tap12(val)); 1088 return(ERR_CODE_NONE); 1089 } 1090 1091 1092 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe12(srds_access_t *sa__, int8_t *val) { 1093 ESTM(*val = (rd_rxa_dfe_tap12() + rd_rxb_dfe_tap12() + rd_rxc_dfe_tap12() + rd_rxd_dfe_tap12())>>2); 1094 return (ERR_CODE_NONE); 1095 } 1096 1097 1098 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe13(srds_access_t *sa__, int8_t val) { 1099 if ((val > 7) || (val < -7)) 1100 { 1101 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 1102 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 1103 } 1104 EFUN(wr_rxa_dfe_tap13(val)); 1105 EFUN(wr_rxb_dfe_tap13(val)); 1106 EFUN(wr_rxc_dfe_tap13(val)); 1107 EFUN(wr_rxd_dfe_tap13(val)); 1108 return(ERR_CODE_NONE); 1109 } 1110 1111 1112 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe13(srds_access_t *sa__, int8_t *val) { 1113 ESTM(*val = (rd_rxa_dfe_tap13() + rd_rxb_dfe_tap13() + rd_rxc_dfe_tap13() + rd_rxd_dfe_tap13())>>2); 1114 return (ERR_CODE_NONE); 1115 } 1116 1117 1118 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe14(srds_access_t *sa__, int8_t val) { 1119 1120 if ((val > 7) || (val < -7)) 1121 { 1122 USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val)); 1123 return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP)); 1124 } 1125 EFUN(wr_rxa_dfe_tap14(val)); 1126 EFUN(wr_rxb_dfe_tap14(val)); 1127 EFUN(wr_rxc_dfe_tap14(val)); 1128 EFUN(wr_rxd_dfe_tap14(val)); 1129 return(ERR_CODE_NONE); 1130 } 1131 1132 1133 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe14(srds_access_t *sa__, int8_t *val) { 1134 ESTM(*val = (rd_rxa_dfe_tap14() + rd_rxb_dfe_tap14() + rd_rxc_dfe_tap14() + rd_rxd_dfe_tap14())>>2); 1135 return (ERR_CODE_NONE); 1136 } 1137 1138 err_code_t blackhawk_tsc_INTERNAL_ip_version_check(srds_access_t *sa__, uint8_t *i_am_b0) { 1139 uint8_t ams_tx_version_id = 0; 1140 1141 1142 ESTM(ams_tx_version_id = rd_ams_tx_version_id()); 1143 *i_am_b0 = ams_tx_version_id == 0xC0; 1144 1145 return ERR_CODE_NONE; 1146 } 1147 1148 1149 1150 err_code_t blackhawk_tsc_INTERNAL_load_txfir_taps(srds_access_t *sa__){ 1151 EFUN(wr_txfir_tap_load(1)); /* Load the tap coefficients into TXFIR. */ 1152 1153 return(ERR_CODE_NONE); 1154 } 1155 1156 err_code_t blackhawk_tsc_INTERNAL_set_tx_tap(srds_access_t *sa__, uint8_t tap_num, int16_t val) { 1157 1158 1159 switch (tap_num) { 1160 case 0: EFUN(wr_txfir_tap0_coeff (val)); break; 1161 case 1: EFUN(wr_txfir_tap1_coeff (val)); break; 1162 case 2: EFUN(wr_txfir_tap2_coeff (val)); break; 1163 case 3: EFUN(wr_txfir_tap3_coeff (val)); break; 1164 case 4: EFUN(wr_txfir_tap4_coeff (val)); break; 1165 case 5: EFUN(wr_txfir_tap5_coeff (val)); break; 1166 case 6: EFUN(wr_txfir_tap6_coeff ((uint8_t)val)); break; 1167 case 7: EFUN(wr_txfir_tap7_coeff ((uint8_t)val)); break; 1168 case 8: EFUN(wr_txfir_tap8_coeff ((uint8_t)val)); break; 1169 case 9: EFUN(wr_txfir_tap9_coeff ((uint8_t)val)); break; 1170 case 10: EFUN(wr_txfir_tap10_coeff((uint8_t)val)); break; 1171 case 11: EFUN(wr_txfir_tap11_coeff((uint8_t)val)); break; 1172 default: 1173 return (blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1174 } 1175 1176 return(ERR_CODE_NONE); 1177 } 1178 1179 err_code_t blackhawk_tsc_INTERNAL_get_tx_tap(srds_access_t *sa__, uint8_t tap_num, int16_t *val) { 1180 1181 switch (tap_num) { 1182 case 0: ESTM(*val = rd_txfir_tap0_coeff ()); break; 1183 case 1: ESTM(*val = rd_txfir_tap1_coeff ()); break; 1184 case 2: ESTM(*val = rd_txfir_tap2_coeff ()); break; 1185 case 3: ESTM(*val = rd_txfir_tap3_coeff ()); break; 1186 case 4: ESTM(*val = rd_txfir_tap4_coeff ()); break; 1187 case 5: ESTM(*val = rd_txfir_tap5_coeff ()); break; 1188 case 6: ESTM(*val = rd_txfir_tap6_coeff ()); break; 1189 case 7: ESTM(*val = rd_txfir_tap7_coeff ()); break; 1190 case 8: ESTM(*val = rd_txfir_tap8_coeff ()); break; 1191 case 9: ESTM(*val = rd_txfir_tap9_coeff ()); break; 1192 case 10: ESTM(*val = rd_txfir_tap10_coeff()); break; 1193 case 11: ESTM(*val = rd_txfir_tap11_coeff()); break; 1194 default: 1195 return (blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1196 } 1197 1198 1199 return(ERR_CODE_NONE); 1200 } 1201 1202 1203 1204 1205 err_code_t blackhawk_tsc_INTERNAL_core_clkgate(srds_access_t *sa__, uint8_t enable) { 1206 UNUSED(sa__); 1207 1208 if (enable) { 1209 } 1210 else { 1211 } 1212 return (ERR_CODE_NONE); 1213 } 1214 1215 err_code_t blackhawk_tsc_INTERNAL_lane_clkgate(srds_access_t *sa__, uint8_t enable) { 1216 1217 if (enable) { 1218 /* Use frc/frc_val to force all RX and TX clk_vld signals to 0 */ 1219 EFUN(wr_pmd_rx_clk_vld_frc_val(0x0)); 1220 EFUN(wr_pmd_rx_clk_vld_frc(0x1)); 1221 EFUN(wr_pmd_tx_clk_vld_frc_val(0x0)); 1222 EFUN(wr_pmd_tx_clk_vld_frc(0x1)); 1223 1224 /* Use frc_on to force clkgate */ 1225 EFUN(wr_ln_rx_s_clkgate_frc_on(0x1)); 1226 1227 EFUN(wr_ln_tx_s_clkgate_frc_on(0x1)); 1228 1229 } 1230 else { 1231 EFUN(wr_pmd_rx_clk_vld_frc_val(0x0)); 1232 EFUN(wr_pmd_rx_clk_vld_frc(0x0)); 1233 EFUN(wr_pmd_tx_clk_vld_frc_val(0x0)); 1234 EFUN(wr_pmd_tx_clk_vld_frc(0x0)); 1235 1236 EFUN(wr_ln_rx_s_clkgate_frc_on(0x0)); 1237 1238 EFUN(wr_ln_tx_s_clkgate_frc_on(0x0)); 1239 } 1240 return (ERR_CODE_NONE); 1241 } 1242 1243 /*-----------------------------------------------*/ 1244 /* Get dynamic eye margin estimation values */ 1245 /*-----------------------------------------------*/ 1246 err_code_t blackhawk_tsc_INTERNAL_get_eye_margin_est(srds_access_t *sa__, uint16_t *left_eye_mUI, uint16_t *right_eye_mUI, uint16_t *upper_eye_mV, uint16_t *lower_eye_mV) { 1247 uint8_t ladder_range = 0; 1248 ESTM(*left_eye_mUI = blackhawk_tsc_INTERNAL_eye_to_mUI(sa__, rdv_usr_sts_heye_left())); 1249 ESTM(*right_eye_mUI = blackhawk_tsc_INTERNAL_eye_to_mUI(sa__, rdv_usr_sts_heye_right())); 1250 ESTM(*upper_eye_mV = blackhawk_tsc_INTERNAL_eye_to_mV(sa__, rdv_usr_sts_veye_upper(), ladder_range)); 1251 ESTM(*lower_eye_mV = blackhawk_tsc_INTERNAL_eye_to_mV(sa__, rdv_usr_sts_veye_lower(), ladder_range)); 1252 1253 return (ERR_CODE_NONE); 1254 } 1255 1256 /*----------------------------------------------------*/ 1257 /* Get dynamic eye margin estimation values (PAM) */ 1258 /*----------------------------------------------------*/ 1259 err_code_t blackhawk_tsc_INTERNAL_get_pam_eye_margin_est(srds_access_t *sa__, eye_margin_t *eye_margin) { 1260 uint8_t ladder_range = 0; 1261 uint8_t i; 1262 for(i=0; i<NUM_PAM_EYES; i++) { 1263 ESTM(eye_margin->left_eye_mUI [i] = blackhawk_tsc_INTERNAL_eye_to_mUI(sa__, rdv_usr_sts_pam_heye_left(i))); 1264 ESTM(eye_margin->right_eye_mUI[i] = blackhawk_tsc_INTERNAL_eye_to_mUI(sa__, rdv_usr_sts_pam_heye_right(i))); 1265 ESTM(eye_margin->upper_eye_mV [i] = blackhawk_tsc_INTERNAL_eye_to_mV (sa__, rdv_usr_sts_pam_veye_upper(i), ladder_range)); 1266 ESTM(eye_margin->lower_eye_mV [i] = blackhawk_tsc_INTERNAL_eye_to_mV (sa__, rdv_usr_sts_pam_veye_lower(i), ladder_range)); 1267 } 1268 return (ERR_CODE_NONE); 1269 } 1270 1271 /*------------------------------------------------------*/ 1272 /* Print dynamic eye margin estimation values (PAM) */ 1273 /*------------------------------------------------------*/ 1274 err_code_t blackhawk_tsc_display_pam_eye_margin_est(srds_access_t *sa__) { 1275 int8_t i; 1276 eye_margin_t eye_margin; 1277 1278 ESTM(blackhawk_tsc_INTERNAL_get_pam_eye_margin_est(sa__, &eye_margin)); 1279 1280 EFUN_PRINTF(("Eye margin: L(mUI),R(mUI),U(mV),D(mV)\n")); 1281 for(i=NUM_PAM_EYES-1; i>=0; i--) { 1282 EFUN_PRINTF(("%s eye: ", i==2?"Upper ":i==1?"Middle":"Lower ")); 1283 EFUN_PRINTF(("%6d,%6d,%5d,%5d\n", eye_margin.left_eye_mUI[i], eye_margin.right_eye_mUI[i], eye_margin.upper_eye_mV[i], eye_margin.lower_eye_mV[i])); 1284 } 1285 return (ERR_CODE_NONE); 1286 } 1287 1288 uint16_t blackhawk_tsc_INTERNAL_eye_to_mUI(srds_access_t *sa__, uint8_t var) 1289 { 1290 UNUSED(sa__); 1291 /* var is in units of 1/512 th UI, so need to multiply by 1000/512 */ 1292 return ((uint16_t)var)*125/64; 1293 } 1294 1295 1296 uint16_t blackhawk_tsc_INTERNAL_eye_to_mV(srds_access_t *sa__, uint8_t var, uint8_t ladder_range) 1297 { 1298 /* find nearest two vertical levels */ 1299 uint16_t vl = blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, var, ladder_range); 1300 return (vl); 1301 } 1302 1303 err_code_t blackhawk_tsc_INTERNAL_get_osr_mode(srds_access_t *sa__, blackhawk_tsc_osr_mode_st *imode) { 1304 blackhawk_tsc_osr_mode_st mode; 1305 1306 ENULL_MEMSET(&mode, 0, sizeof(blackhawk_tsc_osr_mode_st)); 1307 1308 if(!imode) 1309 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1310 1311 ESTM(mode.tx = rd_tx_osr_mode()); 1312 ESTM(mode.rx = rd_rx_osr_mode()); 1313 mode.tx_rx = 255; 1314 #ifdef wr_ams_rx_rxclk_div2p5 /* Analog 2p5 OSR mode */ 1315 { 1316 uint8_t osr_2p5, osr_2p5_pwrup; 1317 ESTM(osr_2p5 = rd_ams_tx_txclk_div2p5()); 1318 ESTM(osr_2p5_pwrup = rd_ams_tx_txclk_div2p5_pwrup()); 1319 if ((mode.tx == BLACKHAWK_TSC_OSX1) && (osr_2p5 == 1) && (osr_2p5_pwrup == 1)) { 1320 mode.tx = BLACKHAWK_TSC_OSX2P5; 1321 } 1322 ESTM(osr_2p5 = rd_ams_rx_rxclk_div2p5()); 1323 ESTM(osr_2p5_pwrup = rd_ams_rx_rxclk_div2p5_pwrup()); 1324 if ((mode.rx == BLACKHAWK_TSC_OSX1) && (osr_2p5 == 1) && (osr_2p5_pwrup == 1)) { 1325 mode.rx = BLACKHAWK_TSC_OSX2P5; 1326 } 1327 } 1328 #endif 1329 *imode = mode; 1330 return (ERR_CODE_NONE); 1331 1332 } 1333 1334 err_code_t blackhawk_tsc_INTERNAL_get_rx_pam_mode(srds_access_t *sa__, enum blackhawk_tsc_rx_pam_mode_enum *pmode) { 1335 uint8_t rx_pam4_mode, rx_pam4_es_mode; 1336 1337 ESTM(rx_pam4_mode = rd_rx_pam4_mode()); 1338 ESTM(rx_pam4_es_mode = rd_rx_pam4_er_mode()); 1339 if (rx_pam4_mode == 0) { 1340 *pmode = NRZ; 1341 } 1342 else if (rx_pam4_mode == 1) { 1343 *pmode = (rx_pam4_es_mode) ? PAM4_ES : PAM4_NS; 1344 } 1345 else { 1346 return(blackhawk_tsc_error(sa__, ERR_CODE_INVALID_RX_PAM_MODE)); 1347 } 1348 1349 return (ERR_CODE_NONE); 1350 } 1351 1352 err_code_t blackhawk_tsc_INTERNAL_decode_br_os_mode(srds_access_t *sa__, uint8_t *br_pd_en){ 1353 enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ; 1354 uint8_t os_pattern_enhanced=0, os_all_edges=0; 1355 1356 ESTM(os_pattern_enhanced = rd_os_pattern_enhanced()); 1357 ESTM(os_all_edges = rd_os_all_edges()); 1358 EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode)); 1359 if(pam_mode == NRZ) { 1360 ESTM(*br_pd_en = rd_br_pd_en()); 1361 } else { 1362 *br_pd_en = (uint8_t)(!((!os_pattern_enhanced) & os_all_edges)); 1363 } 1364 return (ERR_CODE_NONE); 1365 } 1366 1367 err_code_t blackhawk_tsc_INTERNAL_pmd_lock_status(srds_access_t *sa__, uint8_t *pmd_lock, uint8_t *pmd_lock_chg) { 1368 uint16_t rddata; 1369 #if defined(reg_rd_TLB_RX_RXDBG_PMD_RX_LOCK_STATUS) 1370 ESTM(rddata = reg_rd_TLB_RX_RXDBG_PMD_RX_LOCK_STATUS()); 1371 ESTM(*pmd_lock = ex_TLB_RX_RXDBG_PMD_RX_LOCK_STATUS__dbg_pmd_rx_lock(rddata)); 1372 ESTM(*pmd_lock_chg = ex_TLB_RX_RXDBG_PMD_RX_LOCK_STATUS__dbg_pmd_rx_lock_change(rddata)); 1373 #elif defined(reg_rd_TLB_RX_DBG_PMD_RX_LOCK_STATUS) 1374 ESTM(rddata = reg_rd_TLB_RX_DBG_PMD_RX_LOCK_STATUS()); 1375 ESTM(*pmd_lock = ex_TLB_RX_DBG_PMD_RX_LOCK_STATUS__dbg_pmd_rx_lock(rddata)); 1376 ESTM(*pmd_lock_chg = ex_TLB_RX_DBG_PMD_RX_LOCK_STATUS__dbg_pmd_rx_lock_change(rddata)); 1377 #else 1378 #error "Unknown core for blackhawk_tsc_INTERNAL_pmd_lock_status()" 1379 #endif 1380 return(ERR_CODE_NONE); 1381 } 1382 1383 err_code_t blackhawk_tsc_INTERNAL_sigdet_status(srds_access_t *sa__, uint8_t *sig_det, uint8_t *sig_det_chg) { 1384 uint16_t rddata; 1385 1386 ESTM(rddata = reg_rd_SIGDET_SDSTATUS_0()); 1387 ESTM(*sig_det = ex_SIGDET_SDSTATUS_0__signal_detect(rddata)); 1388 ESTM(*sig_det_chg = ex_SIGDET_SDSTATUS_0__signal_detect_change(rddata)); 1389 return(ERR_CODE_NONE); 1390 } 1391 1392 err_code_t blackhawk_tsc_INTERNAL_pll_lock_status(srds_access_t *sa__, uint8_t *pll_lock, uint8_t *pll_lock_chg) { 1393 1394 uint16_t rddata; 1395 ESTM(rddata = reg_rdc_PLL_CAL_COM_CTL_STATUS_0()); 1396 ESTM(*pll_lock = exc_PLL_CAL_COM_CTL_STATUS_0__pll_lock(rddata)); 1397 ESTM(*pll_lock_chg = exc_PLL_CAL_COM_CTL_STATUS_0__pll_lock_lh_ll(rddata)); 1398 return(ERR_CODE_NONE); 1399 } 1400 1401 err_code_t blackhawk_tsc_INTERNAL_read_lane_state(srds_access_t *sa__, blackhawk_tsc_lane_state_st *istate) { 1402 1403 blackhawk_tsc_lane_state_st state; 1404 1405 ENULL_MEMSET(&state, 0, sizeof(blackhawk_tsc_lane_state_st)); 1406 1407 if(!istate) 1408 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1409 1410 EFUN(blackhawk_tsc_INTERNAL_pmd_lock_status(sa__,&state.rx_lock, &state.rx_lock_chg)); 1411 { 1412 err_code_t err_code = 0; 1413 state.stop_state = blackhawk_tsc_INTERNAL_stop_micro(sa__,state.rx_lock,&err_code); 1414 if(err_code) USR_PRINTF(("WARNING: Unable to stop microcontroller, following data is suspect\n")); 1415 } 1416 1417 { blackhawk_tsc_osr_mode_st osr_mode; 1418 ENULL_MEMSET(&osr_mode, 0, sizeof(blackhawk_tsc_osr_mode_st)); 1419 EFUN(blackhawk_tsc_INTERNAL_get_osr_mode(sa__, &osr_mode)); 1420 state.osr_mode = osr_mode; 1421 } 1422 { 1423 enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ; 1424 EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode)); 1425 state.rx_pam_mode = (uint8_t)pam_mode; 1426 } 1427 { 1428 struct blackhawk_tsc_uc_lane_config_st lane_cfg; 1429 EFUN(blackhawk_tsc_get_uc_lane_cfg(sa__, &lane_cfg)); 1430 state.ucv_config = lane_cfg.word; 1431 } 1432 ESTM(state.ucv_status = rdv_status_byte()); 1433 ESTM(state.reset_state = rd_rx_lane_dp_reset_state()); 1434 ESTM(state.tx_reset_state = rd_tx_lane_dp_reset_state()); 1435 ESTM(state.tx_pll_select = rd_tx_pll_select()); 1436 ESTM(state.rx_pll_select = rd_rx_pll_select()); 1437 EFUN(blackhawk_tsc_INTERNAL_sigdet_status(sa__,&state.sig_det, &state.sig_det_chg)); 1438 ESTM(state.rx_ppm = rd_cdr_integ_reg()/84); 1439 { 1440 int8_t reg_data; 1441 ESTM(reg_data = rdv_usr_sts_phase_hoffset()); 1442 state.clk90 = reg_data; 1443 } 1444 EFUN(blackhawk_tsc_INTERNAL_decode_br_os_mode(sa__, &state.br_pd_en)); 1445 /* drop the MSB, the result is actually valid modulo 128 */ 1446 /* Also flip the sign to account for d-m1, versus m1-d */ 1447 1448 EFUN(blackhawk_tsc_read_rx_afe(sa__, RX_AFE_PF, &state.pf_main)); 1449 state.pf_hiz = 0; 1450 EFUN(blackhawk_tsc_read_rx_afe(sa__, RX_AFE_PF2, &state.pf2_ctrl)); 1451 EFUN(blackhawk_tsc_read_rx_afe(sa__, RX_AFE_PF3, &state.pf3_ctrl)); 1452 ESTM(state.bwr_ctrl = rdv_afe_bw_adjust()); 1453 EFUN(blackhawk_tsc_read_rx_afe(sa__, RX_AFE_VGA, &state.vga)); 1454 1455 ESTM(state.dc_offset = rd_dc_offset_bin()); 1456 ESTM(state.p1_lvl = rdv_usr_main_tap_est()/32); 1457 state.p1_lvl = blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, (int8_t)state.p1_lvl, 0); 1458 if (state.rx_pam_mode == NRZ) { 1459 ESTM(state.m1_lvl = rd_rx_phase02_status()); 1460 state.m1_lvl = blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, (int8_t)state.m1_lvl, 0); 1461 state.usr_status_eq_debug1 = 0; 1462 state.afe_bw = 0; 1463 } 1464 else { 1465 ESTM(state.m1_lvl = rdv_usr_ctrl_pam4_chn_loss()); 1466 1467 ESTM(state.usr_status_eq_debug1 = rdv_usr_status_eq_debug1()); 1468 { 1469 uint16_t ucode_version_major; 1470 uint8_t ucode_version_minor; 1471 /*Extracting the major version number*/ 1472 ESTM(ucode_version_major = rdcv_common_ucode_version() & 0xFFF); 1473 ESTM(ucode_version_minor = rdcv_common_ucode_minor_version()); 1474 if ((ucode_version_major == 0x2) && (ucode_version_minor >= 0x3) && (ucode_version_minor < 0x8)) { 1475 uint8_t afe_bw_dbg0, afe_bw_dbg1; 1476 uint8_t afe_bw[4] = {1, 2, 0, 3}; 1477 ESTM(afe_bw_dbg0 = rdv_afe_bw_dbg_0()); 1478 ESTM(afe_bw_dbg1 = rdv_afe_bw_dbg_1()); 1479 1480 afe_bw_dbg0 &= 0x01; 1481 afe_bw_dbg1 &= 0x01; 1482 state.afe_bw = afe_bw[((afe_bw_dbg0 << 1) | afe_bw_dbg1)]; 1483 } else if (((ucode_version_major == 0x2) && (ucode_version_minor >= 0x8)) || (ucode_version_major > 0x2)) { 1484 /*tag D002_08 has the changes to afe_bw calculation along with trunk before branching for tag D002_08*/ 1485 ESTM(state.afe_bw = rdv_afe_bw_dbg_0()); 1486 } else { 1487 state.afe_bw = 0xFF; /* assign to a invalid value. */ 1488 } 1489 } 1490 } 1491 1492 ESTM(state.blind_ctle_ctrl = rdv_usr_status_eq_debug3()); 1493 ESTM(state.blind_ctle_trnsum = rdv_usr_status_eq_debug14()); 1494 if ((state.blind_ctle_ctrl == 0) && (state.blind_ctle_trnsum < 0)) { 1495 state.afe_bw_metric = state.blind_ctle_trnsum; 1496 } else { 1497 state.afe_bw_metric = state.blind_ctle_ctrl; 1498 } 1499 ESTM(state.tp_metric_prec1 = rdv_usr_status_tp_metric_1()); 1500 1501 if (state.rx_pam_mode == NRZ) { 1502 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe1(sa__, &state.dfe1)); 1503 } 1504 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe2(sa__, &state.dfe2)); 1505 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe3(sa__, &state.dfe3)); 1506 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe4(sa__, &state.dfe4)); 1507 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe5(sa__, &state.dfe5)); 1508 1509 EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe6(sa__, &state.dfe6)); 1510 1511 /* tx_ppm = register/10.84 */ 1512 ESTM(state.tx_ppm = (int16_t)(((int32_t)(rd_tx_pi_integ2_reg()))*3125/32768)); 1513 1514 ESTM(state.tx_prec_en = rd_pam4_precoder_en()); 1515 ESTM(state.linktrn_en = rd_linktrn_ieee_training_enable()); 1516 ESTM(state.txfir_use_pam4_range = rd_txfir_nrz_tap_range_sel() ? 0 : 1); 1517 { 1518 uint8_t tap_num; 1519 for (tap_num=0; tap_num<12; ++tap_num) { 1520 EFUN(blackhawk_tsc_INTERNAL_get_tx_tap(sa__, tap_num, &state.txfir.tap[tap_num])); 1521 } 1522 } 1523 EFUN(blackhawk_tsc_INTERNAL_get_eye_margin_est(sa__, &state.heye_left, &state.heye_right, &state.veye_upper, &state.veye_lower)); 1524 1525 ESTM(state.link_time = (((uint32_t)rdv_usr_sts_link_time())*8)/10); /* convert from 80us to 0.1 ms units */ 1526 { 1527 /* read lock status at end and combine them to handle transient cases */ 1528 uint8_t rx_lock_at_end=0, rx_lock_chg_at_end=0; 1529 EFUN(blackhawk_tsc_INTERNAL_pmd_lock_status(sa__,&rx_lock_at_end, &rx_lock_chg_at_end)); 1530 if (state.rx_lock != rx_lock_at_end) { 1531 USR_PRINTF(("rx_lock has changed while reading the lane state rx_lock_start=%d, rx_lock_chg_start=%d, rx_lock_at_end=%d, rx_lock_chg_at_end=%d\n", 1532 state.rx_lock, 1533 state.rx_lock_chg, 1534 rx_lock_at_end, 1535 rx_lock_chg_at_end)); 1536 } 1537 state.rx_lock &= rx_lock_at_end; 1538 state.rx_lock_chg |= rx_lock_chg_at_end; 1539 } 1540 1541 if (!state.stop_state || (state.stop_state == 0xFF)) { 1542 /* manually check error code instead of EFUN*/ 1543 { 1544 err_code_t resume_status = ERR_CODE_NONE; 1545 resume_status = blackhawk_tsc_stop_rx_adaptation(sa__, 0); 1546 if (resume_status) { 1547 USR_PRINTF(("WARNING: Resuming micro after lane state capture failed \n")); 1548 } 1549 } 1550 } 1551 1552 *istate = state; 1553 1554 1555 return (ERR_CODE_NONE); 1556 } 1557 1558 err_code_t blackhawk_tsc_INTERNAL_display_lane_state_no_newline(srds_access_t *sa__) { 1559 uint16_t lane_idx; 1560 blackhawk_tsc_lane_state_st state; 1561 1562 const char* e2s_osr_mode_enum[14] = { 1563 "x1 ", 1564 "x2 ", 1565 "x4 ", 1566 "ERR ", 1567 "x21.2", 1568 "x8 ", 1569 "ERR ", 1570 "ERR ", 1571 "x16.5", 1572 "x16 ", 1573 "ERR ", 1574 "ERR ", 1575 "x20.6", 1576 "x32 " 1577 }; 1578 1579 const char* e2s_tx_osr_mode_enum[14] = { 1580 "x1", 1581 "x2", 1582 "x4", 1583 "ER", 1584 "xL", 1585 "x8", 1586 "ER", 1587 "ER", 1588 "xH", 1589 "xG", 1590 "ER", 1591 "ER", 1592 "xK", 1593 "xW" 1594 }; 1595 1596 const char* e2s_rx_pam_mode_enum[3] = { 1597 "NRZ", 1598 "P4N", 1599 "P4E" 1600 }; 1601 1602 1603 ENULL_MEMSET(&state, 0, sizeof(blackhawk_tsc_lane_state_st)); 1604 1605 EFUN(blackhawk_tsc_INTERNAL_read_lane_state(sa__, &state)); 1606 1607 lane_idx = blackhawk_tsc_get_lane(sa__); 1608 EFUN_PRINTF(("%2d ", lane_idx)); 1609 if(state.osr_mode.tx_rx != 255) { 1610 char *s; 1611 s = (char *)e2s_osr_mode_enum[state.osr_mode.tx_rx]; 1612 EFUN_PRINTF(("(%2s%s, 0x%04x, 0x%02x ,", (state.br_pd_en) ? "BR" : "OS", s, state.ucv_config,state.ucv_status)); 1613 } else { 1614 char *s; 1615 char *r; 1616 s = (char *)e2s_tx_osr_mode_enum[state.osr_mode.tx]; 1617 r = (char *)e2s_tx_osr_mode_enum[state.osr_mode.rx]; 1618 { 1619 char *t; 1620 uint8_t tx, rx; 1621 t = (char *)e2s_rx_pam_mode_enum[state.rx_pam_mode]; 1622 ESTM(tx = rd_tx_pam4_mode()); 1623 ESTM(rx = rd_rx_pam4_mode()); 1624 EFUN_PRINTF(("(%3s%s,%2s%s:%s, 0x%04x, 0x%02x ,", t,(tx == rx) ? " ": "~", (state.br_pd_en) ? "BR" : "OS", s,r, state.ucv_config,state.ucv_status)); 1625 } 1626 } 1627 EFUN_PRINTF((" %01x,%01x, %01x, %1d,%1d)",state.tx_reset_state,state.reset_state,state.stop_state,state.tx_pll_select,state.rx_pll_select)); 1628 EFUN_PRINTF((" %1d%s", state.sig_det, state.sig_det_chg ? "*" : " ")); 1629 EFUN_PRINTF((" %1d%s", state.rx_lock, state.rx_lock_chg ? "*" : " ")); 1630 EFUN_PRINTF(("%4d ", state.rx_ppm)); 1631 EFUN_PRINTF((" %3d ", state.clk90)); 1632 EFUN_PRINTF((" %2d,%1d,%2d,%2d", state.pf_main, state.pf2_ctrl, state.pf3_ctrl, state.bwr_ctrl)); 1633 EFUN_PRINTF((" %2d ", state.vga)); 1634 EFUN_PRINTF(("%3d ", state.dc_offset)); 1635 EFUN_PRINTF(("%3d ", state.p1_lvl)); 1636 if (state.afe_bw == 0xFF) { 1637 /* afe_bw calculation is not supported in this microcode version and so invalid value 0xFF*/ 1638 EFUN_PRINTF(("(%4d,%+5d, x,%3d,%3d)", 1639 state.m1_lvl, /* pam4 _chn_loss */ 1640 state.afe_bw_metric, 1641 state.usr_status_eq_debug1, 1642 state.tp_metric_prec1)); 1643 } else { 1644 EFUN_PRINTF(("(%4d,%+5d,%2d,%3d,%3d)", 1645 state.m1_lvl, /* pam4 _chn_loss */ 1646 state.afe_bw_metric, 1647 state.afe_bw, 1648 state.usr_status_eq_debug1, 1649 state.tp_metric_prec1)); 1650 } 1651 if (state.rx_pam_mode == NRZ) { 1652 EFUN_PRINTF(("%3d,%3d,%3d,%3d,%3d,%3d", state.dfe1, state.dfe2, state.dfe3, state.dfe4, state.dfe5, state.dfe6)); 1653 } 1654 else { 1655 EFUN_PRINTF((" x ,%3d,%3d,%3d,%3d,%3d", state.dfe2, state.dfe3, state.dfe4, state.dfe5, state.dfe6)); 1656 } 1657 EFUN_PRINTF((" %4d ", state.tx_ppm)); 1658 { 1659 uint8_t enable_6taps; 1660 if (state.tx_prec_en) { 1661 EFUN_PRINTF((" P")); 1662 } 1663 else { 1664 EFUN_PRINTF((" ")); 1665 } 1666 if(state.linktrn_en) { 1667 EFUN_PRINTF(("T")); 1668 } 1669 else { 1670 EFUN_PRINTF((" ")); 1671 } 1672 ESTM(enable_6taps = rd_txfir_tap_en()); 1673 if (!enable_6taps) { 1674 EFUN_PRINTF((" x ,%3d,%3d,%3d, x , x ", state.txfir.tap[0], state.txfir.tap[1], state.txfir.tap[2])); 1675 } 1676 else { 1677 EFUN_PRINTF(("%3d,%3d,%3d,%3d,%3d,%3d ", 1678 state.txfir.tap[0], state.txfir.tap[1], state.txfir.tap[2], 1679 state.txfir.tap[3], state.txfir.tap[4], state.txfir.tap[5])); 1680 } 1681 } 1682 EFUN_PRINTF((" %3d,%3d,%3d,%3d ", state.heye_left, state.heye_right, state.veye_upper, state.veye_lower)); 1683 /* Check to see if link_time is max value after 80us to 0.1msec unit conversion */ 1684 if (state.link_time == 0xCCCC) { 1685 EFUN_PRINTF((" >%4d.%01d", state.link_time/10, state.link_time%10)); 1686 EFUN_PRINTF((" ")); 1687 } else { 1688 EFUN_PRINTF((" %4d.%01d", state.link_time/10, state.link_time%10)); 1689 EFUN_PRINTF((" ")); 1690 } 1691 EFUN(blackhawk_tsc_INTERNAL_display_BER(sa__,100)); 1692 1693 1694 return (ERR_CODE_NONE); 1695 } 1696 1697 err_code_t blackhawk_tsc_INTERNAL_read_core_state(srds_access_t *sa__, blackhawk_tsc_core_state_st *istate) { 1698 blackhawk_tsc_core_state_st state; 1699 struct blackhawk_tsc_uc_core_config_st core_cfg; 1700 1701 ENULL_MEMSET(&state, 0, sizeof(blackhawk_tsc_core_state_st)); 1702 ENULL_MEMSET(&core_cfg, 0, sizeof(struct blackhawk_tsc_uc_core_config_st)); 1703 1704 if(!istate) 1705 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1706 EFUN(blackhawk_tsc_get_uc_core_config(sa__, &core_cfg)); 1707 1708 { 1709 uint8_t rescal_frc; 1710 ESTM(rescal_frc = rdc_rescal_frc()); 1711 if (1 == rescal_frc) { 1712 /* rescal_frc_val is read, since the rescal value is overriden. */ 1713 ESTM(state.rescal = rdc_rescal_frc_val()); 1714 } else { 1715 ESTM(state.rescal = rd_ams_tx_ana_rescal()); 1716 } 1717 } 1718 ESTM(state.core_reset = rdc_core_dp_reset_state()); 1719 ESTM(state.uc_active = rdc_uc_active()); 1720 ESTM(state.comclk_mhz = rdc_heartbeat_count_1us()); 1721 ESTM(state.pll_pwrdn = rdc_pll_pwrdn_or()); 1722 ESTM(state.ucode_version = rdcv_common_ucode_version()); 1723 EFUN(blackhawk_tsc_version(sa__, &state.api_version)); 1724 ESTM(state.ucode_minor_version = rdcv_common_ucode_minor_version()); 1725 ESTM(state.afe_hardware_version = rdcv_afe_hardware_version()); 1726 ESTM(state.temp_idx = rdcv_temp_idx()); 1727 { int16_t die_temp = 0; 1728 EFUN(blackhawk_tsc_read_die_temperature(sa__, &die_temp)); 1729 state.die_temp = die_temp; 1730 } 1731 ESTM(state.avg_tmon = _bin_to_degC(rdcv_avg_tmon_reg13bit()>>3)); 1732 state.vco_rate_mhz = (uint16_t)core_cfg.vco_rate_in_Mhz; 1733 ESTM(state.analog_vco_range = rdc_ams_pll_range()); 1734 EFUN(blackhawk_tsc_INTERNAL_measure_pll_comp_thresh(sa__, &state.pll_comp_thresh)); 1735 EFUN(blackhawk_tsc_INTERNAL_read_pll_div(sa__, &state.pll_div)); 1736 EFUN(blackhawk_tsc_INTERNAL_pll_lock_status(sa__, &state.pll_lock, &state.pll_lock_chg)); 1737 ESTM(state.core_status = rdcv_status_byte()); 1738 ESTM(state.refclk_doubler = rdc_ams_pll_refclk_doubler()); 1739 1740 *istate = state; 1741 return (ERR_CODE_NONE); 1742 } 1743 1744 err_code_t blackhawk_tsc_INTERNAL_measure_pll_comp_thresh(srds_access_t *sa__, int16_t *thresh) { 1745 uint8_t pll_comp_thresh=0; 1746 uint8_t pll_low=0; 1747 uint8_t pll_comp_thresh_bak; 1748 1749 if(!thresh) 1750 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1751 1752 ESTM(pll_comp_thresh_bak = rdc_ams_pll_comp_thresh()); 1753 1754 for(pll_comp_thresh = 0; pll_comp_thresh < 8; pll_comp_thresh++) { 1755 EFUN(wrc_ams_pll_comp_thresh(pll_comp_thresh)); 1756 ESTM(pll_low = rdc_ams_pll_low()); 1757 if(pll_low == 1) break; 1758 } 1759 1760 EFUN(wrc_ams_pll_comp_thresh(pll_comp_thresh_bak)); 1761 1762 *thresh = ((pll_comp_thresh==0) ? 0 : (-50*pll_comp_thresh - 50)); 1763 1764 return(ERR_CODE_NONE); 1765 } 1766 1767 err_code_t blackhawk_tsc_INTERNAL_display_core_state_no_newline(srds_access_t *sa__) { 1768 blackhawk_tsc_core_state_st state; 1769 blackhawk_tsc_core_state_st state_pll1; 1770 1771 ENULL_MEMSET(&state_pll1, 0, sizeof(state_pll1)); 1772 ENULL_MEMSET(&state , 0, sizeof(state )); 1773 { 1774 uint8_t pll_orig; 1775 ESTM(pll_orig = blackhawk_tsc_get_pll_idx(sa__)); 1776 EFUN(blackhawk_tsc_set_pll_idx(sa__, 0)); 1777 EFUN(blackhawk_tsc_INTERNAL_read_core_state(sa__, &state)); 1778 EFUN(blackhawk_tsc_set_pll_idx(sa__, 1)); 1779 EFUN(blackhawk_tsc_INTERNAL_read_core_state(sa__, &state_pll1)); 1780 EFUN(blackhawk_tsc_set_pll_idx(sa__, pll_orig)); 1781 } 1782 1783 if ((state.avg_tmon<-50)||(state.avg_tmon>135)) { 1784 EFUN_PRINTF(("\n*** WARNING: Core die temperature (LIVE_TEMP) out of bounds -50C to 130C\n")); 1785 } 1786 if ((state.rescal < 6) || (state.rescal > 13)) { 1787 EFUN_PRINTF(("\n*** WARNING: RESCAL value is out of bounds 6 to 13\n")); 1788 } 1789 if ((state_pll1.rescal < 6) || (state_pll1.rescal > 13)) { 1790 EFUN_PRINTF(("\n*** WARNING: RESCAL PLL1 value is out of bounds 6 to 13\n")); 1791 } 1792 1793 EFUN_PRINTF((" %02d " , blackhawk_tsc_get_core(sa__))); 1794 EFUN_PRINTF((" %x,%x,%02x " , state.core_reset, state_pll1.core_reset, state.core_status)); 1795 EFUN_PRINTF((" %1d,%1d " , state.pll_pwrdn,state_pll1.pll_pwrdn)); 1796 EFUN_PRINTF((" %1d " , state.uc_active)); 1797 EFUN_PRINTF((" %3d.%2dMHz" , (state.comclk_mhz/4),((state.comclk_mhz%4)*25))); /* comclk in Mhz = heartbeat_count_1us / 4 */ 1798 EFUN_PRINTF((" %4X_%02X " , state.ucode_version, state.ucode_minor_version)); 1799 EFUN_PRINTF((" %06X " , state.api_version)); 1800 EFUN_PRINTF((" 0x%02x " , state.afe_hardware_version)); 1801 EFUN_PRINTF((" %3dC " , state.die_temp)); 1802 EFUN_PRINTF((" (%02d)%3dC " , state.temp_idx, state.avg_tmon)); 1803 EFUN_PRINTF((" 0x%02x " , state.rescal)); 1804 EFUN_PRINTF((" %2d.%03d,%2d.%03dGHz ", (state .vco_rate_mhz / 1000), 1805 (state .vco_rate_mhz % 1000), 1806 (state_pll1.vco_rate_mhz / 1000), 1807 (state_pll1.vco_rate_mhz % 1000))); 1808 EFUN_PRINTF((" %03d,%03d " , state .analog_vco_range, 1809 state_pll1.analog_vco_range)); 1810 EFUN(blackhawk_tsc_INTERNAL_display_pll_to_divider(sa__, state .pll_div)); 1811 EFUN_PRINTF((",")); 1812 EFUN(blackhawk_tsc_INTERNAL_display_pll_to_divider(sa__, state_pll1.pll_div)); 1813 EFUN_PRINTF((" %01d%s," , state.pll_lock, state.pll_lock_chg ? "*" : " ")); 1814 EFUN_PRINTF((" %01d%s" , state_pll1.pll_lock, state_pll1.pll_lock_chg ? "*" : " ")); 1815 EFUN_PRINTF((" %+4dmV,%+4dmV " , state.pll_comp_thresh,state_pll1.pll_comp_thresh)); 1816 1817 1818 return (ERR_CODE_NONE); 1819 } 1820 1821 1822 1823 /* returns 000111 (7 = 8-1), for n = 3 */ 1824 #define BFMASK(n) ((1<<((n)))-1) 1825 1826 err_code_t blackhawk_tsc_INTERNAL_update_uc_lane_config_st(struct blackhawk_tsc_uc_lane_config_st *st) { 1827 uint16_t in = st->word; 1828 st->field.lane_cfg_from_pcs = in & BFMASK(1); in >>= 1; 1829 st->field.an_enabled = in & BFMASK(1); in >>= 1; 1830 st->field.dfe_on = in & BFMASK(1); in >>= 1; 1831 st->field.dfe_lp_mode = in & BFMASK(1); in >>= 1; 1832 st->field.force_brdfe_on = in & BFMASK(1); in >>= 1; 1833 st->field.media_type = in & BFMASK(2); in >>= 2; 1834 st->field.unreliable_los = in & BFMASK(1); in >>= 1; 1835 st->field.scrambling_dis = in & BFMASK(1); in >>= 1; 1836 st->field.cl72_auto_polarity_en = in & BFMASK(1); in >>= 1; 1837 st->field.cl72_restart_timeout_en = in & BFMASK(1); in >>= 1; 1838 st->field.force_es = in & BFMASK(1); in >>= 1; 1839 st->field.force_ns = in & BFMASK(1); in >>= 1; 1840 st->field.lp_has_prec_en = in & BFMASK(1); in >>= 1; 1841 st->field.force_pam4_mode = in & BFMASK(1); in >>= 1; 1842 st->field.force_nrz_mode = in & BFMASK(1); in >>= 1; 1843 return(ERR_CODE_NONE); 1844 } 1845 err_code_t blackhawk_tsc_INTERNAL_update_usr_ctrl_disable_functions_st(struct blackhawk_tsc_usr_ctrl_disable_functions_st *st) { 1846 uint16_t in = st->word; 1847 st->field.pf_adaptation = in & BFMASK(1); in >>= 1; 1848 st->field.pf2_adaptation = in & BFMASK(1); in >>= 1; 1849 st->field.pf3_adaptation = in & BFMASK(1); in >>= 1; 1850 st->field.dc_adaptation = in & BFMASK(1); in >>= 1; 1851 st->field.vga_adaptation = in & BFMASK(1); in >>= 1; 1852 st->field.slicer_voffset_tuning = in & BFMASK(1); in >>= 1; 1853 st->field.slicer_hoffset_tuning = in & BFMASK(1); in >>= 1; 1854 st->field.phase_offset_adaptation = in & BFMASK(1); in >>= 1; 1855 st->field.eye_adaptation = in & BFMASK(1); in >>= 1; 1856 st->field.all_adaptation = in & BFMASK(1); in >>= 1; 1857 st->field.deq_adaptation = in & BFMASK(1); in >>= 1; 1858 st->field.pam_eye_margin_estimation = in & BFMASK(1); in >>= 1; 1859 st->field.reserved = in & BFMASK(4); 1860 return ERR_CODE_NONE; 1861 } 1862 1863 1864 err_code_t blackhawk_tsc_INTERNAL_update_usr_ctrl_disable_dfe_functions_st(struct blackhawk_tsc_usr_ctrl_disable_dfe_functions_st *st) { 1865 uint8_t in = st->byte; 1866 st->field.dfe_tap1_adaptation = in & BFMASK(1); in >>= 1; 1867 st->field.dfe_fx_taps_adaptation = in & BFMASK(1); in >>= 1; 1868 st->field.dfe_fl_taps_adaptation = in & BFMASK(1); in >>= 1; 1869 st->field.dfe_dcd_adaptation = in & BFMASK(1); in >>= 1; 1870 return ERR_CODE_NONE; 1871 } 1872 /* word to fields, for display */ 1873 err_code_t blackhawk_tsc_INTERNAL_update_uc_core_config_st(struct blackhawk_tsc_uc_core_config_st *st) { 1874 uint16_t in = st->word; 1875 st->field.vco_rate = in & BFMASK(8); in >>= 8; 1876 st->field.core_cfg_from_pcs = in & BFMASK(1); in >>= 1; 1877 st->field.reserved = in & BFMASK(7); 1878 st->vco_rate_in_Mhz = VCO_RATE_TO_MHZ(st->field.vco_rate); 1879 return ERR_CODE_NONE; 1880 } 1881 1882 /* fields to word, to write into uC RAM */ 1883 err_code_t blackhawk_tsc_INTERNAL_update_uc_core_config_word(struct blackhawk_tsc_uc_core_config_st *st) { 1884 uint16_t in = 0; 1885 in <<= 7; in |= 0/*st->field.reserved*/ & BFMASK(7); 1886 in <<= 1; in |= st->field.core_cfg_from_pcs & BFMASK(1); 1887 in <<= 8; in |= st->field.vco_rate & BFMASK(8); 1888 st->word = in; 1889 return ERR_CODE_NONE; 1890 } 1891 1892 err_code_t blackhawk_tsc_INTERNAL_update_uc_lane_config_word(struct blackhawk_tsc_uc_lane_config_st *st) { 1893 uint16_t in = 0; 1894 in <<= 1; in |= st->field.force_nrz_mode & BFMASK(1); 1895 in <<= 1; in |= st->field.force_pam4_mode & BFMASK(1); 1896 in <<= 1; in |= st->field.lp_has_prec_en & BFMASK(1); 1897 in <<= 1; in |= st->field.force_ns & BFMASK(1); 1898 in <<= 1; in |= st->field.force_es & BFMASK(1); 1899 in <<= 1; in |= st->field.cl72_restart_timeout_en & BFMASK(1); 1900 in <<= 1; in |= st->field.cl72_auto_polarity_en & BFMASK(1); 1901 in <<= 1; in |= st->field.scrambling_dis & BFMASK(1); 1902 in <<= 1; in |= st->field.unreliable_los & BFMASK(1); 1903 in <<= 2; in |= st->field.media_type & BFMASK(2); 1904 in <<= 1; in |= st->field.force_brdfe_on & BFMASK(1); 1905 in <<= 1; in |= st->field.dfe_lp_mode & BFMASK(1); 1906 in <<= 1; in |= st->field.dfe_on & BFMASK(1); 1907 in <<= 1; in |= st->field.an_enabled & BFMASK(1); 1908 in <<= 1; in |= st->field.lane_cfg_from_pcs & BFMASK(1); 1909 st->word = in; 1910 return ERR_CODE_NONE; 1911 } 1912 err_code_t blackhawk_tsc_INTERNAL_update_usr_ctrl_disable_functions_byte(struct blackhawk_tsc_usr_ctrl_disable_functions_st *st) { 1913 uint16_t in = 0; 1914 in <<= 5; in |= 0/*st->field.reserved*/ & BFMASK(4); 1915 in <<= 1; in |= st->field.pam_eye_margin_estimation & BFMASK(1); 1916 in <<= 1; in |= st->field.deq_adaptation & BFMASK(1); 1917 in <<= 1; in |= st->field.all_adaptation & BFMASK(1); 1918 in <<= 1; in |= st->field.eye_adaptation & BFMASK(1); 1919 in <<= 1; in |= st->field.phase_offset_adaptation & BFMASK(1); 1920 in <<= 1; in |= st->field.slicer_hoffset_tuning & BFMASK(1); 1921 in <<= 1; in |= st->field.slicer_voffset_tuning & BFMASK(1); 1922 in <<= 1; in |= st->field.vga_adaptation & BFMASK(1); 1923 in <<= 1; in |= st->field.dc_adaptation & BFMASK(1); 1924 in <<= 1; in |= st->field.pf3_adaptation & BFMASK(1); 1925 in <<= 1; in |= st->field.pf2_adaptation & BFMASK(1); 1926 in <<= 1; in |= st->field.pf_adaptation & BFMASK(1); 1927 st->word = in; 1928 return ERR_CODE_NONE; 1929 } 1930 1931 err_code_t blackhawk_tsc_INTERNAL_update_usr_ctrl_disable_dfe_functions_byte(struct blackhawk_tsc_usr_ctrl_disable_dfe_functions_st *st) { 1932 uint8_t in = 0; 1933 in <<= 1; in |= st->field.dfe_dcd_adaptation & BFMASK(1); 1934 in <<= 1; in |= st->field.dfe_fl_taps_adaptation & BFMASK(1); 1935 in <<= 1; in |= st->field.dfe_fx_taps_adaptation & BFMASK(1); 1936 in <<= 1; in |= st->field.dfe_tap1_adaptation & BFMASK(1); 1937 st->byte = in; 1938 return ERR_CODE_NONE; 1939 } 1940 1941 #undef BFMASK 1942 1943 err_code_t blackhawk_tsc_INTERNAL_check_uc_lane_stopped(srds_access_t *sa__) { 1944 1945 uint8_t is_micro_stopped; 1946 ESTM(is_micro_stopped = rdv_usr_sts_micro_stopped() || (rd_rx_lane_dp_reset_state() > 0)); 1947 if (!is_micro_stopped) { 1948 return(blackhawk_tsc_error(sa__, ERR_CODE_UC_NOT_STOPPED)); 1949 } else { 1950 return(ERR_CODE_NONE); 1951 } 1952 } 1953 1954 err_code_t blackhawk_tsc_INTERNAL_calc_patt_gen_mode_sel(srds_access_t *sa__, uint8_t *mode_sel, uint8_t *zero_pad_len, uint8_t patt_length) { 1955 1956 if(!mode_sel) { 1957 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1958 } 1959 if(!zero_pad_len) { 1960 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 1961 } 1962 1963 /* Select the correct Pattern generator Mode depending on Pattern length */ 1964 if (!(140 % patt_length)) { 1965 *mode_sel = 6; 1966 *zero_pad_len = 100; 1967 } 1968 else if (!(160 % patt_length)) { 1969 *mode_sel = 5; 1970 *zero_pad_len = 80; 1971 } 1972 else if (!(180 % patt_length)) { 1973 *mode_sel = 4; 1974 *zero_pad_len = 60; 1975 } 1976 else if (!(200 % patt_length)) { 1977 *mode_sel = 3; 1978 *zero_pad_len = 40; 1979 } 1980 else if (!(220 % patt_length)) { 1981 *mode_sel = 2; 1982 *zero_pad_len = 20; 1983 } 1984 else if (!(240 % patt_length)) { 1985 *mode_sel = 1; 1986 *zero_pad_len = 0; 1987 } else { 1988 EFUN_PRINTF(("ERROR: Unsupported Pattern Length\n")); 1989 return (blackhawk_tsc_error(sa__, ERR_CODE_CFG_PATT_INVALID_PATT_LENGTH)); 1990 } 1991 return(ERR_CODE_NONE); 1992 } 1993 1994 /*-----------------------------------------*/ 1995 /* Write Core Config variables to uC RAM */ 1996 /*-----------------------------------------*/ 1997 1998 err_code_t blackhawk_tsc_INTERNAL_set_uc_core_config(srds_access_t *sa__, struct blackhawk_tsc_uc_core_config_st struct_val) { 1999 { uint8_t reset_state; 2000 ESTM(reset_state = rdc_core_dp_reset_state()); 2001 if(reset_state < 7) { 2002 EFUN_PRINTF(("ERROR: blackhawk_tsc_INTERNAL_set_uc_core_config(..) called without core_dp_s_rstb=0\n")); 2003 return (blackhawk_tsc_error(sa__, ERR_CODE_CORE_DP_NOT_RESET)); 2004 } 2005 } 2006 if(struct_val.vco_rate_in_Mhz > 0) { 2007 struct_val.field.vco_rate = MHZ_TO_VCO_RATE(struct_val.vco_rate_in_Mhz); 2008 } 2009 EFUN(blackhawk_tsc_INTERNAL_update_uc_core_config_word(&struct_val)); 2010 switch (blackhawk_tsc_get_pll_idx(sa__)) { 2011 case 0: 2012 EFUN(reg_wrc_CORE_PLL_COM_PLL_UC_CORE_CONFIG(struct_val.word)); 2013 break; 2014 case 1: 2015 EFUN(reg_wrc_CORE_PLL_COM_PLL_UC_CORE_CONFIG(struct_val.word)); 2016 break; 2017 default: 2018 EFUN(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 2019 break; 2020 } 2021 return (ERR_CODE_NONE); 2022 } 2023 2024 /*---------------------*/ 2025 /* PLL Configuration */ 2026 /*---------------------*/ 2027 /** Extract the refclk frequency in Hz, based on a blackhawk_tsc_pll_refclk_enum value. */ 2028 err_code_t _blackhawk_tsc_get_refclk_in_hz(srds_access_t *sa__, enum blackhawk_tsc_pll_refclk_enum refclk, uint32_t *refclk_in_hz) { 2029 switch (refclk) { 2030 case BLACKHAWK_TSC_PLL_REFCLK_100MHZ: *refclk_in_hz = 100000000; break; 2031 case BLACKHAWK_TSC_PLL_REFCLK_106P25MHZ: *refclk_in_hz = 106250000; break; 2032 case BLACKHAWK_TSC_PLL_REFCLK_122P88MHZ: *refclk_in_hz = 122880000; break; 2033 case BLACKHAWK_TSC_PLL_REFCLK_125MHZ: *refclk_in_hz = 125000000; break; 2034 case BLACKHAWK_TSC_PLL_REFCLK_145P947802MHZ: *refclk_in_hz = 145947802; break; 2035 case BLACKHAWK_TSC_PLL_REFCLK_155P52MHZ: *refclk_in_hz = 155520000; break; 2036 case BLACKHAWK_TSC_PLL_REFCLK_156P25MHZ: *refclk_in_hz = 156250000; break; 2037 case BLACKHAWK_TSC_PLL_REFCLK_159P375MHZ: *refclk_in_hz = 159375000; break; 2038 case BLACKHAWK_TSC_PLL_REFCLK_161P1328125MHZ: *refclk_in_hz = 161132813; break; 2039 case BLACKHAWK_TSC_PLL_REFCLK_166P67MHZ: *refclk_in_hz = 166670000; break; 2040 case BLACKHAWK_TSC_PLL_REFCLK_166P7974882MHZ: *refclk_in_hz = 166797488; break; 2041 case BLACKHAWK_TSC_PLL_REFCLK_167P38MHZ: *refclk_in_hz = 167380000; break; 2042 case BLACKHAWK_TSC_PLL_REFCLK_167P4107143MHZ: *refclk_in_hz = 167410714; break; 2043 case BLACKHAWK_TSC_PLL_REFCLK_174P703125MHZ: *refclk_in_hz = 174703125; break; 2044 case BLACKHAWK_TSC_PLL_REFCLK_212P5MHZ: *refclk_in_hz = 212500000; break; 2045 case BLACKHAWK_TSC_PLL_REFCLK_311p04: *refclk_in_hz = 311040000; break; 2046 case BLACKHAWK_TSC_PLL_REFCLK_312P5MHZ: *refclk_in_hz = 312500000; break; 2047 case BLACKHAWK_TSC_PLL_REFCLK_425MHZ: *refclk_in_hz = 425000000; break; 2048 case BLACKHAWK_TSC_PLL_REFCLK_534MHZ: *refclk_in_hz = 534000000; break; 2049 case BLACKHAWK_TSC_PLL_REFCLK_705MHZ: *refclk_in_hz = 705000000; break; 2050 case BLACKHAWK_TSC_PLL_REFCLK_175MHZ: *refclk_in_hz = 175000000; break; 2051 case BLACKHAWK_TSC_PLL_REFCLK_400MHZ: *refclk_in_hz = 400000000; break; 2052 case BLACKHAWK_TSC_PLL_REFCLK_266P67MHZ: *refclk_in_hz = 266670000; break; 2053 case BLACKHAWK_TSC_PLL_REFCLK_156P637MHZ: *refclk_in_hz = 156637000; break; 2054 case BLACKHAWK_TSC_PLL_REFCLK_157P844MHZ: *refclk_in_hz = 157844000; break; 2055 case BLACKHAWK_TSC_PLL_REFCLK_158P51MHZ: *refclk_in_hz = 158510000; break; 2056 case BLACKHAWK_TSC_PLL_REFCLK_162P9485MHZ: *refclk_in_hz = 162948500; break; 2057 case BLACKHAWK_TSC_PLL_REFCLK_167P331MHZ: *refclk_in_hz = 167331000; break; 2058 case BLACKHAWK_TSC_PLL_REFCLK_168P04MHZ: *refclk_in_hz = 168040000; break; 2059 case BLACKHAWK_TSC_PLL_REFCLK_169P40905086MHZ: *refclk_in_hz = 169409051; break; 2060 case BLACKHAWK_TSC_PLL_REFCLK_173P37MHZ: *refclk_in_hz = 173370000; break; 2061 default: 2062 EFUN_PRINTF(("ERROR: Unknown refclk frequency: 0x%08X\n", (uint32_t)refclk)); 2063 *refclk_in_hz = 0xFFFFFFFF; 2064 return (blackhawk_tsc_error(sa__, ERR_CODE_REFCLK_FREQUENCY_INVALID)); 2065 } 2066 return (ERR_CODE_NONE); 2067 } 2068 2069 /** Identify the ratio: 2070 * 2071 * (numerator / denominator) = (1000 / divisor) 2072 * 2073 * such that this has as little rounding error as possible: 2074 * 2075 * refclk_freq_hz = numerator * round(vco_freq_khz / denominator) 2076 * 2077 * This will yield the most accurate refclk_freq_hz. 2078 * Common values of vco_freq_khz are considered in this. 2079 */ 2080 static err_code_t _blackhawk_tsc_get_divisor_ratio(srds_access_t *sa__, enum blackhawk_tsc_pll_div_enum srds_div, uint16_t *numerator, uint16_t *denominator) 2081 { 2082 switch (srds_div) { 2083 case BLACKHAWK_TSC_PLL_DIV_66: *denominator = 33; *numerator = 500; break; 2084 case BLACKHAWK_TSC_PLL_DIV_67: *denominator = 67; *numerator = 1000; break; 2085 case BLACKHAWK_TSC_PLL_DIV_70: *denominator = 7; *numerator = 100; break; 2086 case BLACKHAWK_TSC_PLL_DIV_72: *denominator = 9; *numerator = 125; break; 2087 case BLACKHAWK_TSC_PLL_DIV_76: *denominator = 19; *numerator = 250; break; 2088 case BLACKHAWK_TSC_PLL_DIV_73P6: *denominator = 46; *numerator = 625; break; 2089 case BLACKHAWK_TSC_PLL_DIV_79P2: *denominator = 99; *numerator = 1250; break; 2090 case BLACKHAWK_TSC_PLL_DIV_80: *denominator = 2; *numerator = 25; break; 2091 case BLACKHAWK_TSC_PLL_DIV_82P5: *denominator = 33; *numerator = 400; break; 2092 case BLACKHAWK_TSC_PLL_DIV_84: *denominator = 21; *numerator = 250; break; 2093 case BLACKHAWK_TSC_PLL_DIV_85: *denominator = 17; *numerator = 200; break; 2094 case BLACKHAWK_TSC_PLL_DIV_87P5: *denominator = 7; *numerator = 80; break; 2095 case BLACKHAWK_TSC_PLL_DIV_89P6: *denominator = 56; *numerator = 625; break; 2096 case BLACKHAWK_TSC_PLL_DIV_90: *denominator = 9; *numerator = 100; break; 2097 case BLACKHAWK_TSC_PLL_DIV_96: *denominator = 12; *numerator = 125; break; 2098 case BLACKHAWK_TSC_PLL_DIV_100: *denominator = 1; *numerator = 10; break; 2099 case BLACKHAWK_TSC_PLL_DIV_120: *denominator = 3; *numerator = 25; break; 2100 case BLACKHAWK_TSC_PLL_DIV_127P401984: *denominator = 179; *numerator = 1405; break; 2101 case BLACKHAWK_TSC_PLL_DIV_128: *denominator = 16; *numerator = 125; break; 2102 case BLACKHAWK_TSC_PLL_DIV_132: *denominator = 33; *numerator = 250; break; 2103 case BLACKHAWK_TSC_PLL_DIV_134: *denominator = 67; *numerator = 500; break; 2104 case BLACKHAWK_TSC_PLL_DIV_140: *denominator = 7; *numerator = 50; break; 2105 case BLACKHAWK_TSC_PLL_DIV_144: *denominator = 18; *numerator = 125; break; 2106 case BLACKHAWK_TSC_PLL_DIV_147P2: *denominator = 92; *numerator = 625; break; 2107 case BLACKHAWK_TSC_PLL_DIV_148: *denominator = 37; *numerator = 250; break; 2108 case BLACKHAWK_TSC_PLL_DIV_152: *denominator = 19; *numerator = 125; break; 2109 case BLACKHAWK_TSC_PLL_DIV_158P4: *denominator = 99; *numerator = 625; break; 2110 case BLACKHAWK_TSC_PLL_DIV_160: *denominator = 4; *numerator = 25; break; 2111 case BLACKHAWK_TSC_PLL_DIV_165: *denominator = 33; *numerator = 200; break; 2112 case BLACKHAWK_TSC_PLL_DIV_168: *denominator = 21; *numerator = 125; break; 2113 case BLACKHAWK_TSC_PLL_DIV_170: *denominator = 17; *numerator = 100; break; 2114 case BLACKHAWK_TSC_PLL_DIV_175: *denominator = 7; *numerator = 40; break; 2115 case BLACKHAWK_TSC_PLL_DIV_180: *denominator = 9; *numerator = 50; break; 2116 case BLACKHAWK_TSC_PLL_DIV_184: *denominator = 23; *numerator = 125; break; 2117 case BLACKHAWK_TSC_PLL_DIV_192: *denominator = 24; *numerator = 125; break; 2118 case BLACKHAWK_TSC_PLL_DIV_198: *denominator = 99; *numerator = 500; break; 2119 case BLACKHAWK_TSC_PLL_DIV_200: *denominator = 1; *numerator = 5; break; 2120 case BLACKHAWK_TSC_PLL_DIV_224: *denominator = 28; *numerator = 125; break; 2121 case BLACKHAWK_TSC_PLL_DIV_240: *denominator = 6; *numerator = 25; break; 2122 case BLACKHAWK_TSC_PLL_DIV_264: *denominator = 33; *numerator = 125; break; 2123 case BLACKHAWK_TSC_PLL_DIV_280: *denominator = 7; *numerator = 25; break; 2124 case BLACKHAWK_TSC_PLL_DIV_330: *denominator = 33; *numerator = 100; break; 2125 case BLACKHAWK_TSC_PLL_DIV_350: *denominator = 7; *numerator = 20; break; 2126 default: 2127 EFUN_PRINTF(("ERROR: Unknown divider value: 0x%08X\n", (uint32_t)srds_div)); 2128 *numerator = 0; 2129 *denominator = 0; 2130 return (blackhawk_tsc_error(sa__, ERR_CODE_PLL_DIV_INVALID)); 2131 } 2132 return (ERR_CODE_NONE); 2133 } 2134 2135 /** Get the Refclk frequency in Hz, based on the blackhawk_tsc_pll_div_enum value and VCO frequency. */ 2136 static err_code_t _blackhawk_tsc_get_refclk_from_div_vco(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) { 2137 uint16_t numerator, denominator; 2138 EFUN(_blackhawk_tsc_get_divisor_ratio(sa__, srds_div, &numerator, &denominator)); 2139 *refclk_freq_hz = ((vco_freq_khz+(denominator>>1)) / denominator) * numerator; 2140 if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DOUBLER_EN) *refclk_freq_hz /= 2; 2141 if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV2_EN) *refclk_freq_hz *= 2; 2142 if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV4_EN) *refclk_freq_hz *= 4; 2143 return (ERR_CODE_NONE); 2144 } 2145 2146 /** Get the VCO frequency in kHz, based on the reference clock frequency and blackhawk_tsc_pll_div_enum value. */ 2147 err_code_t blackhawk_tsc_INTERNAL_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) { 2148 uint16_t numerator, denominator; 2149 EFUN(_blackhawk_tsc_get_divisor_ratio(sa__, srds_div, &numerator, &denominator)); 2150 if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DOUBLER_EN) refclk_freq_hz *= 2; 2151 if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV2_EN) refclk_freq_hz /= 2; 2152 if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV4_EN) refclk_freq_hz /= 4; 2153 *vco_freq_khz = ((refclk_freq_hz + (numerator>>1)) / numerator) * denominator; 2154 return (ERR_CODE_NONE); 2155 } 2156 2157 /* Boundaries for allowed VCO frequency */ 2158 # define SERDES_VCO_FREQ_KHZ_MIN (15000000) 2159 # define SERDES_VCO_FREQ_KHZ_MAX (30000000) 2160 2161 /* Allowed tolerance in resultant VCO frequency when auto-determining divider value */ 2162 # define SERDES_VCO_FREQ_KHZ_TOLERANCE (2000) 2163 2164 /* The allowed PLL divider values */ 2165 static const enum blackhawk_tsc_pll_div_enum _blackhawk_tsc_div_candidates[] = { 2166 BLACKHAWK_TSC_PLL_DIV_66, 2167 BLACKHAWK_TSC_PLL_DIV_67, 2168 BLACKHAWK_TSC_PLL_DIV_70, 2169 BLACKHAWK_TSC_PLL_DIV_72, 2170 BLACKHAWK_TSC_PLL_DIV_76, 2171 BLACKHAWK_TSC_PLL_DIV_73P6, 2172 BLACKHAWK_TSC_PLL_DIV_79P2, 2173 BLACKHAWK_TSC_PLL_DIV_80, 2174 BLACKHAWK_TSC_PLL_DIV_82P5, 2175 BLACKHAWK_TSC_PLL_DIV_84, 2176 BLACKHAWK_TSC_PLL_DIV_85, 2177 BLACKHAWK_TSC_PLL_DIV_87P5, 2178 BLACKHAWK_TSC_PLL_DIV_89P6, 2179 BLACKHAWK_TSC_PLL_DIV_90, 2180 BLACKHAWK_TSC_PLL_DIV_96, 2181 BLACKHAWK_TSC_PLL_DIV_100, 2182 BLACKHAWK_TSC_PLL_DIV_120, 2183 BLACKHAWK_TSC_PLL_DIV_127P401984, 2184 BLACKHAWK_TSC_PLL_DIV_128, 2185 BLACKHAWK_TSC_PLL_DIV_132, 2186 BLACKHAWK_TSC_PLL_DIV_134, 2187 BLACKHAWK_TSC_PLL_DIV_140, 2188 BLACKHAWK_TSC_PLL_DIV_144, 2189 BLACKHAWK_TSC_PLL_DIV_147P2, 2190 BLACKHAWK_TSC_PLL_DIV_148, 2191 BLACKHAWK_TSC_PLL_DIV_152, 2192 BLACKHAWK_TSC_PLL_DIV_158P4, 2193 BLACKHAWK_TSC_PLL_DIV_160, 2194 BLACKHAWK_TSC_PLL_DIV_165, 2195 BLACKHAWK_TSC_PLL_DIV_168, 2196 BLACKHAWK_TSC_PLL_DIV_170, 2197 BLACKHAWK_TSC_PLL_DIV_175, 2198 BLACKHAWK_TSC_PLL_DIV_180, 2199 BLACKHAWK_TSC_PLL_DIV_184, 2200 BLACKHAWK_TSC_PLL_DIV_192, 2201 BLACKHAWK_TSC_PLL_DIV_198, 2202 BLACKHAWK_TSC_PLL_DIV_200, 2203 BLACKHAWK_TSC_PLL_DIV_224, 2204 BLACKHAWK_TSC_PLL_DIV_240, 2205 BLACKHAWK_TSC_PLL_DIV_264, 2206 BLACKHAWK_TSC_PLL_DIV_280, 2207 BLACKHAWK_TSC_PLL_DIV_330, 2208 BLACKHAWK_TSC_PLL_DIV_350 2209 }; 2210 2211 static const uint8_t _blackhawk_tsc_div_candidates_count = sizeof(_blackhawk_tsc_div_candidates) / sizeof(_blackhawk_tsc_div_candidates[0]); 2212 2213 static err_code_t _blackhawk_tsc_check_div(srds_access_t *sa__, enum blackhawk_tsc_pll_div_enum srds_div) { 2214 uint8_t i, found = 0; 2215 for (i=0; i<_blackhawk_tsc_div_candidates_count; i++) { 2216 found |= srds_div == _blackhawk_tsc_div_candidates[i]; 2217 } 2218 if (!found) { 2219 EFUN_PRINTF(("ERROR: Invalid divider value: 0x%08X\n", (uint32_t)srds_div)); 2220 return (blackhawk_tsc_error(sa__, ERR_CODE_PLL_DIV_INVALID)); 2221 } 2222 return (ERR_CODE_NONE); 2223 } 2224 2225 static err_code_t _blackhawk_tsc_check_vco_freq_khz(srds_access_t *sa__, uint32_t vco_freq_khz) { 2226 if (vco_freq_khz < SERDES_VCO_FREQ_KHZ_MIN - SERDES_VCO_FREQ_KHZ_TOLERANCE) { 2227 EFUN_PRINTF(("ERROR: VCO frequency too low: %d kHz is lower than minimum (%d kHz)\n", vco_freq_khz, SERDES_VCO_FREQ_KHZ_MIN)); 2228 return (blackhawk_tsc_error(sa__, ERR_CODE_VCO_FREQUENCY_INVALID)); 2229 } 2230 if (vco_freq_khz > SERDES_VCO_FREQ_KHZ_MAX + SERDES_VCO_FREQ_KHZ_TOLERANCE) { 2231 EFUN_PRINTF(("ERROR: VCO frequency too high: %d kHz is higher than maximum (%d kHz)\n", vco_freq_khz, SERDES_VCO_FREQ_KHZ_MAX)); 2232 return (blackhawk_tsc_error(sa__, ERR_CODE_VCO_FREQUENCY_INVALID)); 2233 } 2234 return (ERR_CODE_NONE); 2235 } 2236 2237 /** Find the entry out of _blackhawk_tsc_div_candidates that is closest to matching refclk_freq_hz and vco_freq_khz. */ 2238 static err_code_t _blackhawk_tsc_get_div(srds_access_t *sa__, uint32_t refclk_freq_hz, uint32_t vco_freq_khz, enum blackhawk_tsc_pll_div_enum *srds_div, enum blackhawk_tsc_pll_option_enum pll_option) { 2239 int32_t vco_freq_khz_min_error = 0x7FFFFFFF; 2240 uint8_t i; 2241 for (i=0; i<_blackhawk_tsc_div_candidates_count; i++) { 2242 uint32_t actual_vco_freq_khz = 0; 2243 int32_t vco_freq_khz_error; 2244 EFUN(blackhawk_tsc_INTERNAL_get_vco_from_refclk_div(sa__, refclk_freq_hz, _blackhawk_tsc_div_candidates[i], &actual_vco_freq_khz, pll_option)); 2245 vco_freq_khz_error = vco_freq_khz - actual_vco_freq_khz; 2246 vco_freq_khz_error = SRDS_ABS(vco_freq_khz_error); 2247 if (vco_freq_khz_min_error > vco_freq_khz_error) { 2248 vco_freq_khz_min_error = vco_freq_khz_error; 2249 *srds_div = _blackhawk_tsc_div_candidates[i]; 2250 } 2251 } 2252 if (vco_freq_khz_min_error == 0xFFFFFFFF) { 2253 return (blackhawk_tsc_error(sa__, ERR_CODE_CONFLICTING_PARAMETERS)); 2254 } 2255 return (ERR_CODE_NONE); 2256 } 2257 2258 err_code_t blackhawk_tsc_INTERNAL_resolve_pll_parameters(srds_access_t *sa__, 2259 enum blackhawk_tsc_pll_refclk_enum refclk, 2260 uint32_t *refclk_freq_hz, 2261 enum blackhawk_tsc_pll_div_enum *srds_div, 2262 uint32_t *vco_freq_khz, 2263 enum blackhawk_tsc_pll_option_enum pll_option) { 2264 2265 /* Parameter value and consistency checks */ 2266 const uint8_t given_param_count = (((refclk == BLACKHAWK_TSC_PLL_REFCLK_UNKNOWN) ? 0 : 1) 2267 + ((*srds_div == BLACKHAWK_TSC_PLL_DIV_UNKNOWN) ? 0 : 1) 2268 + ((*vco_freq_khz == 0) ? 0 : 1)); 2269 const uint32_t original_vco_freq_khz = *vco_freq_khz; 2270 enum blackhawk_tsc_pll_div_enum auto_div = BLACKHAWK_TSC_PLL_DIV_UNKNOWN; 2271 char*pll_option_e2s[] = {"no", "refclk_x2", "refclk_div2", "refclk_div4"}; 2272 COMPILER_REFERENCE(pll_option_e2s); 2273 2274 /* Verify that at least two of the three parameters is given. */ 2275 if (given_param_count < 2) { 2276 return (blackhawk_tsc_error(sa__, ERR_CODE_INSUFFICIENT_PARAMETERS)); 2277 } 2278 2279 /* Skip verification if option is selected. Error if all parameters not given. */ 2280 if ((pll_option & BLACKHAWK_TSC_PLL_OPTION_DISABLE_VERIFY) == BLACKHAWK_TSC_PLL_OPTION_DISABLE_VERIFY) { 2281 if (given_param_count < 3) { 2282 return (blackhawk_tsc_error(sa__, ERR_CODE_INSUFFICIENT_PARAMETERS)); 2283 } else { 2284 EFUN(_blackhawk_tsc_get_refclk_in_hz(sa__, refclk, refclk_freq_hz)); 2285 return(ERR_CODE_NONE); 2286 } 2287 } 2288 pll_option = (enum blackhawk_tsc_pll_option_enum)(pll_option & BLACKHAWK_TSC_PLL_OPTION_REFCLK_MASK); 2289 2290 /* The refclk value is checked in various functions below. */ 2291 2292 /* Verify that the requested div value is allowed. */ 2293 if (*srds_div != BLACKHAWK_TSC_PLL_DIV_UNKNOWN) { 2294 EFUN(_blackhawk_tsc_check_div(sa__, *srds_div)); 2295 } 2296 2297 /* Verify that the requested VCO frequency is allowed. */ 2298 if (*vco_freq_khz != 0) { 2299 EFUN(_blackhawk_tsc_check_vco_freq_khz(sa__, *vco_freq_khz)); 2300 } 2301 2302 if (refclk == BLACKHAWK_TSC_PLL_REFCLK_UNKNOWN) { 2303 /* Determine refclk from vco frequency and div */ 2304 EFUN(_blackhawk_tsc_get_refclk_from_div_vco(sa__, refclk_freq_hz, *srds_div, *vco_freq_khz, pll_option)); 2305 } else { 2306 EFUN(_blackhawk_tsc_get_refclk_in_hz(sa__, refclk, refclk_freq_hz)); 2307 } 2308 2309 if (*vco_freq_khz == 0) { 2310 /* Determine VCO frequency from refclk and divider */ 2311 EFUN(blackhawk_tsc_INTERNAL_get_vco_from_refclk_div(sa__, *refclk_freq_hz, *srds_div, vco_freq_khz, pll_option)); 2312 } 2313 2314 /* Determine divider from vco frequency and refclk. 2315 * This is done even if the div was provided, because if it is, 2316 * we still want to check whether the parameters are conflicting. 2317 */ 2318 EFUN(_blackhawk_tsc_get_div(sa__, *refclk_freq_hz, *vco_freq_khz, &auto_div, pll_option)); 2319 if (*srds_div == BLACKHAWK_TSC_PLL_DIV_UNKNOWN) { 2320 /* Use the auto-determined divider value, since the divider was not supplied. */ 2321 *srds_div = auto_div; 2322 2323 /* Determine resultant VCO frequency from refclk and divider */ 2324 EFUN(blackhawk_tsc_INTERNAL_get_vco_from_refclk_div(sa__, *refclk_freq_hz, *srds_div, vco_freq_khz, pll_option)); 2325 } 2326 2327 /* Verify the resultant VCO frequency */ 2328 EFUN(_blackhawk_tsc_check_vco_freq_khz(sa__, *vco_freq_khz)); 2329 2330 /* Verify that the requested VCO frequency is delivered. */ 2331 if ((original_vco_freq_khz != 0) 2332 && ((*vco_freq_khz < original_vco_freq_khz - SERDES_VCO_FREQ_KHZ_TOLERANCE) 2333 || (*vco_freq_khz > original_vco_freq_khz + SERDES_VCO_FREQ_KHZ_TOLERANCE))) { 2334 EFUN_PRINTF(("ERROR: Could not achieve requested VCO frequency of %d kHz.\n Refclk is %d Hz, %s option enabled, and auto-determined divider is 0x%08X, yielding a VCO frequency of %d kHz.\n", 2335 original_vco_freq_khz, *refclk_freq_hz, pll_option_e2s[pll_option], *srds_div, *vco_freq_khz)); 2336 return (blackhawk_tsc_error(sa__, ERR_CODE_VCO_FREQUENCY_INVALID)); 2337 } 2338 2339 /* Verify the auto-determined divider value. */ 2340 if (auto_div != *srds_div) { 2341 EFUN_PRINTF(("ERROR: Conflicting PLL parameters: refclk is %d Hz, %s option enabled, divider is 0x%08X, and VCO frequency is %d kHz.\n Expected divider is 0x%08X\n", 2342 *refclk_freq_hz, pll_option_e2s[pll_option], *srds_div, *vco_freq_khz, auto_div)); 2343 return (blackhawk_tsc_error(sa__, ERR_CODE_CONFLICTING_PARAMETERS)); 2344 } 2345 2346 return (ERR_CODE_NONE); 2347 } 2348 2349 err_code_t blackhawk_tsc_INTERNAL_display_pll_to_divider(srds_access_t *sa__, uint32_t srds_div) { 2350 /* Adjust these to increase or decrease the number of digits to the right 2351 * of the decimal point. 2352 */ 2353 const uint8_t decimal_digits = 4; 2354 const uint32_t ten_to_the_decimal_digits = 10000; /* 10**decimal_digits */ 2355 2356 /* Not a const, because of carry logic below. */ 2357 uint16_t div_integer = SRDS_INTERNAL_GET_PLL_DIV_INTEGER(srds_div); 2358 2359 if (SRDS_INTERNAL_IS_PLL_DIV_FRACTIONAL(srds_div)) { 2360 /* fraction_num will have this many bits (ending at bit 0). */ 2361 const uint8_t fraction_num_width = 28; 2362 const uint32_t fraction_num = SRDS_INTERNAL_GET_PLL_DIV_FRACTION_NUM(srds_div, fraction_num_width); 2363 2364 /* Identify the number that, when printed with left-padded zeros, 2365 * becomes the digits to the right of the decimal point. 2366 * 2367 * This value can be obtained by dividing fraction_num by: 2368 * 2369 * (2^fraction_num_width)/(10^decimal_digits) 2370 */ 2371 const uint32_t divisor = (((1 << fraction_num_width) + (ten_to_the_decimal_digits>>1)) 2372 / ten_to_the_decimal_digits); 2373 uint32_t fraction_as_int = (fraction_num + (divisor>>1)) / divisor; 2374 2375 /* In case the rounding above caused the fractional portion to overflow 2376 * (e.g. 4.9999999999 becomes 5.0000), implement the carry into the 2377 * integer portion. 2378 */ 2379 if (fraction_as_int >= ten_to_the_decimal_digits) { 2380 fraction_as_int -= ten_to_the_decimal_digits; 2381 ++div_integer; 2382 } 2383 2384 EFUN_PRINTF(("%3d.%0*d", div_integer, decimal_digits, fraction_as_int)); 2385 } else { 2386 const uint8_t left_spaces = (decimal_digits + 1) >> 1; 2387 COMPILER_REFERENCE(left_spaces); 2388 EFUN_PRINTF(("%*s%3d%*s", left_spaces, "", div_integer, decimal_digits - left_spaces + 1, "")); 2389 } 2390 return(ERR_CODE_NONE); 2391 } 2392 2393 2394 err_code_t blackhawk_tsc_INTERNAL_print_uc_dsc_error(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd) { 2395 uint32_t supp_info; 2396 2397 ESTM(supp_info = (rd_uc_dsc_supp_info()) & 0xFF); 2398 switch (SUPP_INFO_TO_ERROR_CODE(supp_info)) { 2399 case UC_CMD_ERROR_INVALID_COMMAND: 2400 ESTM_PRINTF(("ERROR : UC reported invalid command %d. (other_info = 0x%X)\n", 2401 cmd, SUPP_INFO_TO_OTHER_INFO(supp_info))); 2402 break; 2403 case UC_CMD_ERROR_BUSY: 2404 ESTM_PRINTF(("ERROR : UC reported busy for command %d. (other_info = 0x%X)\n", 2405 cmd, SUPP_INFO_TO_OTHER_INFO(supp_info))); 2406 break; 2407 case UC_CMD_ERROR_GET_EYE_SAMPLE_ERROR: 2408 ESTM_PRINTF(("ERROR : UC reported error in getting eye sample. (command %d, other_info = 0x%X)\n", 2409 cmd, SUPP_INFO_TO_OTHER_INFO(supp_info))); 2410 break; 2411 case UC_CMD_ERROR_PRBS_NOT_LOCKED: 2412 ESTM_PRINTF(("ERROR : UC reported PRBS not locked. (command %d, other_info = 0x%X)\n", 2413 cmd, SUPP_INFO_TO_OTHER_INFO(supp_info))); 2414 break; 2415 case UC_CMD_ERROR_COMMAND_IN_PROGRESS: 2416 ESTM_PRINTF(("ERROR : UC reported command already in progress. (command %d, other_info = 0x%X)\n", 2417 cmd, SUPP_INFO_TO_OTHER_INFO(supp_info))); 2418 break; 2419 case UC_CMD_ERROR_INVALID_MODE: 2420 ESTM_PRINTF(("ERROR : UC reported invalid mode for command %d. (other_info = 0x%X)\n", 2421 cmd, SUPP_INFO_TO_OTHER_INFO(supp_info))); 2422 break; 2423 default: 2424 ESTM_PRINTF(("ERROR : UC reported unknown error 0x%X for command %d. (other_info = 0x%X)\n", 2425 SUPP_INFO_TO_ERROR_CODE(supp_info), cmd, SUPP_INFO_TO_OTHER_INFO(supp_info))); 2426 } 2427 /* Cleanup cmd register */ 2428 EFUN(reg_wr_DSC_A_DSC_UC_CTRL(0x80)); 2429 EFUN(wr_uc_dsc_data(0)); 2430 2431 return(ERR_CODE_NONE); 2432 } 2433 2434 /******************************************/ 2435 /* Serdes Register field Poll functions */ 2436 /******************************************/ 2437 2438 #ifndef CUSTOM_REG_POLLING 2439 /* poll for microcontroller to populate the dsc_data register */ 2440 err_code_t blackhawk_tsc_INTERNAL_poll_diag_done(srds_access_t *sa__, uint16_t *status, uint32_t timeout_ms) { 2441 uint8_t loop; 2442 2443 if(!status) { 2444 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 2445 } 2446 2447 for(loop=0;loop < 100; loop++) { 2448 ESTM(*status=rdv_usr_diag_status()); 2449 2450 if((*status & 0x8000) > 0) { 2451 return(ERR_CODE_NONE); 2452 } 2453 if(loop>10) { 2454 EFUN(USR_DELAY_US(10*timeout_ms)); 2455 } 2456 } 2457 return(blackhawk_tsc_error(sa__, ERR_CODE_DIAG_TIMEOUT)); 2458 } 2459 /** Poll for field "uc_dsc_ready_for_cmd" = 1 [Return Val => Error_code (0 = Polling Pass)] */ 2460 err_code_t blackhawk_tsc_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(srds_access_t *sa__, uint32_t timeout_ms, enum srds_pmd_uc_cmd_enum cmd) { 2461 /* read quickly for 10 tries */ 2462 uint16_t loop; 2463 uint16_t reset_state; 2464 2465 for (loop = 0; loop < 100; loop++) { 2466 uint16_t rddata; 2467 ESTM(rddata = reg_rd_DSC_A_DSC_UC_CTRL()); 2468 if (rddata & 0x0080) { /* bit 7 is uc_dsc_ready_for_cmd */ 2469 if (rddata & 0x0040) { /* bit 6 is uc_dsc_error_found */ 2470 EFUN(blackhawk_tsc_INTERNAL_print_uc_dsc_error(sa__, cmd)); 2471 return(blackhawk_tsc_error(sa__, ERR_CODE_UC_CMD_RETURN_ERROR)); 2472 } 2473 return (ERR_CODE_NONE); 2474 } 2475 if(loop>10) { 2476 EFUN(USR_DELAY_US(10*timeout_ms)); 2477 } 2478 } 2479 /* Check if ln_s_rstb is asserted by looking at the reset state, the give a warning and display the commands*/ 2480 ESTM(reset_state = rd_lane_dp_reset_state()); 2481 if (reset_state & 0x0007) { 2482 EFUN_PRINTF(("DSC ready for command is not working; SerDes is probably reset!\n")); 2483 return (ERR_CODE_NONE); 2484 } 2485 { 2486 EFUN_PRINTF(("%s ERROR : DSC ready for command is not working, applying workaround and getting debug info !\n", API_FUNCTION_NAME)); 2487 /* print the triage info and reset the cmd interface */ 2488 blackhawk_tsc_INTERNAL_print_triage_info(sa__, ERR_CODE_UC_CMD_POLLING_TIMEOUT, 1, 1, __LINE__); 2489 /* artifically terminate the command to re-enable the command interface */ 2490 EFUN(wr_uc_dsc_ready_for_cmd(0x1)); 2491 } 2492 return (ERR_CODE_UC_CMD_POLLING_TIMEOUT); 2493 } 2494 2495 /* Poll for field "dsc_state" = DSC_STATE_UC_TUNE [Return Val => Error_code (0 = Polling Pass)] */ 2496 err_code_t blackhawk_tsc_INTERNAL_poll_dsc_state_equals_uc_tune(srds_access_t *sa__, uint32_t timeout_ms) { 2497 uint16_t loop; 2498 uint16_t dsc_state; 2499 /* poll 10 times to avoid longer delays later */ 2500 for (loop = 0; loop < 100; loop++) { 2501 ESTM(dsc_state = rd_dsc_state()); 2502 if (dsc_state == DSC_STATE_UC_TUNE) { 2503 return (ERR_CODE_NONE); 2504 } 2505 if(loop>10) { 2506 EFUN(USR_DELAY_US(10*timeout_ms)); 2507 } 2508 } 2509 ESTM_PRINTF(("DSC_STATE = %d\n", rd_dsc_state())); 2510 return (blackhawk_tsc_error(sa__, ERR_CODE_POLLING_TIMEOUT)); /* Error Code for polling timeout */ 2511 } 2512 2513 2514 /* Poll for field "micro_ra_initdone" = 1 [Return Val => Error_code (0 = Polling Pass)] */ 2515 err_code_t blackhawk_tsc_INTERNAL_poll_micro_ra_initdone(srds_access_t *sa__, uint32_t timeout_ms) { 2516 uint16_t loop; 2517 2518 uint8_t result; 2519 for (loop = 0; loop <= 100; loop++) { 2520 ESTM(result = rdc_micro_ra_initdone()); 2521 if (result) { 2522 return (ERR_CODE_NONE); 2523 } 2524 EFUN(USR_DELAY_US(10*timeout_ms)); 2525 } 2526 return (blackhawk_tsc_error(sa__, ERR_CODE_POLLING_TIMEOUT)); /* Error Code for polling timeout */ 2527 } 2528 2529 #endif /* CUSTOM_REG_POLLING */ 2530 2531 int8_t blackhawk_tsc_INTERNAL_afe_slicer_offset_mapping(int8_t x) { 2532 if (x>=0) 2533 return(x^((x&2)>>1)); /* XOR bit 0 with bit 1 */ 2534 else 2535 return(-blackhawk_tsc_INTERNAL_afe_slicer_offset_mapping(-x)); 2536 } 2537 2538 uint8_t blackhawk_tsc_INTERNAL_is_big_endian(void) 2539 { 2540 uint32_t one_u32 = 0x01000000; 2541 char * ptr = (char *)(&one_u32); 2542 const uint8_t big_endian = (ptr[0] == 1); 2543 return big_endian; 2544 } 2545 2546 2547 int blackhawk_tsc_INTERNAL_get_endian_offset(uint8_t *addr) { 2548 const int endian_const = 1; 2549 return ((*(char*)&endian_const) == 0) ? 2550 ( 2551 (((USR_UINTPTR)(addr))%4 == 0) ? 3 : 2552 (((USR_UINTPTR)(addr))%4 == 1) ? 1 : 2553 (((USR_UINTPTR)(addr))%4 == 2) ? -1 : 2554 (((USR_UINTPTR)(addr))%4 == 3) ? -3 : 2555 0) 2556 : 0; 2557 } 2558 2559 err_code_t blackhawk_tsc_INTERNAL_rdblk_callback(void *arg, uint8_t byte_count, uint16_t data) { 2560 srds_access_t *sa__; 2561 blackhawk_tsc_INTERNAL_rdblk_callback_arg_t * const cast_arg = (blackhawk_tsc_INTERNAL_rdblk_callback_arg_t *)arg; 2562 int endian_offset = 0; 2563 sa__ = cast_arg->sa; 2564 2565 ESTM(endian_offset = blackhawk_tsc_INTERNAL_get_endian_offset(cast_arg->mem_ptr)); 2566 *(cast_arg->mem_ptr + endian_offset) = data & 0xFF; 2567 cast_arg->mem_ptr++; 2568 if (byte_count == 2) { 2569 ESTM(endian_offset = blackhawk_tsc_INTERNAL_get_endian_offset(cast_arg->mem_ptr)); 2570 *(cast_arg->mem_ptr + endian_offset) = data >> 8; 2571 cast_arg->mem_ptr++; 2572 } 2573 return (ERR_CODE_NONE); 2574 } 2575 2576 err_code_t blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(srds_access_t *sa__, 2577 uint32_t block_addr, 2578 uint16_t block_size, 2579 uint16_t start_offset, 2580 uint16_t cnt, 2581 void *arg, 2582 err_code_t (*callback)(void *, uint8_t, uint16_t)) { 2583 uint32_t read_val = 0; 2584 uint8_t defecit = 0; 2585 uint32_t addr = block_addr + start_offset; 2586 2587 if (cnt == 0) { 2588 return (ERR_CODE_NONE); 2589 } 2590 2591 /* Check for bad start offset and block size. */ 2592 if (start_offset >= block_size) { 2593 return (ERR_CODE_BAD_PTR_OR_INVALID_INPUT); 2594 } 2595 2596 while (cnt > 0) { 2597 /* Determine how many bytes to read before wrapping back to start of block. */ 2598 uint16_t block_cnt = SRDS_MIN(cnt, block_addr + block_size - addr); 2599 cnt -= block_cnt; 2600 2601 /* Set up the word reads. */ 2602 EFUN(wrc_micro_autoinc_rdaddr_en(1)); 2603 EFUN(wrc_micro_ra_rddatasize(0x1)); /* Select 16bit read datasize */ 2604 EFUN(wrc_micro_ra_rdaddr_msw(addr >> 16)); /* Upper 16bits of RAM address to be read */ 2605 EFUN(wrc_micro_ra_rdaddr_lsw(addr & 0xFFFE)); /* Lower 16bits of RAM address to be read */ 2606 2607 /* Read the leading byte, if starting at an odd address. */ 2608 if ((addr & 1) == 1) { 2609 ESTM(read_val |= ((rdc_micro_ra_rddata_lsw() >> 8) << defecit)); 2610 if (defecit == 8) { 2611 EFUN(callback(arg, 2, (uint16_t)read_val)); 2612 read_val = 0; 2613 } 2614 /* We just read a byte. This toggles the defecit from 0 to 8 or from 8 to 0. */ 2615 defecit ^= 8; 2616 --block_cnt; 2617 } 2618 2619 /* Read the whole words, and call the callback with two bytes at a time. */ 2620 while (block_cnt >= 2) { 2621 ESTM(read_val |= (rdc_micro_ra_rddata_lsw() << defecit)); 2622 EFUN(callback(arg, 2, (uint16_t)read_val)); 2623 read_val >>= 16; 2624 /* We just read two bytes. This preserves whatever defecit (8 or 0) is there. */ 2625 block_cnt -= 2; 2626 } 2627 2628 /* Read the trailing byte, if leftover after reading whole words. */ 2629 if (block_cnt > 0) { 2630 ESTM(read_val |= ((rdc_micro_ra_rddata_lsw() & 0xFF) << defecit)); 2631 if (defecit == 8) { 2632 EFUN(callback(arg, 2, (uint16_t)read_val)); 2633 read_val = 0; 2634 } 2635 /* We just read a byte. This toggles the defecit from 0 to 8 or from 8 to 0. */ 2636 defecit ^= 8; 2637 } 2638 addr = block_addr; 2639 } 2640 2641 /* If a final byte is left behind, then call the callback with it. */ 2642 if (defecit > 0) { 2643 EFUN(callback(arg, 1, (uint16_t)read_val)); 2644 } 2645 2646 return(ERR_CODE_NONE); 2647 } 2648 err_code_t blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram_descending(srds_access_t *sa__, 2649 uint32_t block_addr, 2650 uint16_t block_size, 2651 uint16_t start_offset, 2652 uint16_t cnt, 2653 void *arg, 2654 err_code_t (*callback)(void *, uint8_t, uint16_t)) { 2655 uint32_t read_val = 0; 2656 uint8_t defecit = 0; 2657 uint32_t addr = block_addr + start_offset; 2658 uint16_t configured_addr_msw = (addr >> 16) + 1; 2659 2660 if (cnt == 0) { 2661 return (ERR_CODE_NONE); 2662 } 2663 2664 /* Check for bad start offset and block size. */ 2665 if (start_offset >= block_size) { 2666 return (ERR_CODE_BAD_PTR_OR_INVALID_INPUT); 2667 } 2668 2669 EFUN(wrc_micro_autoinc_rdaddr_en(0)); 2670 EFUN(wrc_micro_ra_rddatasize(0x1)); /* Select 16bit read datasize */ 2671 2672 while (cnt > 0) { 2673 /* Determine how many bytes to read before wrapping back to end of block. */ 2674 uint16_t block_cnt = SRDS_MIN(cnt, start_offset+1); 2675 cnt -= block_cnt; 2676 2677 while (block_cnt > 0) { 2678 const uint16_t addr_msw = addr >> 16; 2679 uint16_t read_val2; 2680 if (addr_msw != configured_addr_msw) { 2681 EFUN(wrc_micro_ra_rdaddr_msw(addr_msw)); /* Upper 16bits of RAM address to be read */ 2682 configured_addr_msw = addr_msw; 2683 } 2684 2685 EFUN(wrc_micro_ra_rdaddr_lsw(addr & 0xFFFE)); /* Lower 16bits of RAM address to be read */ 2686 ESTM(read_val2 = rdc_micro_ra_rddata_lsw()); 2687 2688 if (((addr & 1) == 1) && (block_cnt >= 2)) { 2689 /* Reading two bytes. Since we're reading in descending address order, they 2690 * will be reversed before they are sent out. */ 2691 read_val |= ((((read_val2 & 0xFF) << 8) | (read_val2 >> 8)) << defecit); 2692 EFUN(callback(arg, 2, (uint16_t)read_val)); 2693 read_val >>= 16; 2694 /* We just read two bytes. This preserves whatever defecit (8 or 0) is there. */ 2695 block_cnt -= 2; 2696 addr -= 2; 2697 } else { 2698 if ((addr & 1) == 1) { 2699 /* Reading upper byte of word. */ 2700 read_val |= ((read_val2 >> 8) << defecit); 2701 } else { 2702 /* Reading lower byte of word. */ 2703 read_val |= ((read_val2 & 0xFF) << defecit); 2704 } 2705 if (defecit == 8) { 2706 EFUN(callback(arg, 2, (uint16_t)read_val)); 2707 read_val = 0; 2708 } 2709 /* We just read a byte. This toggles the defecit from 0 to 8 or from 8 to 0. */ 2710 defecit ^= 8; 2711 --block_cnt; 2712 --addr; 2713 } 2714 } 2715 2716 addr = block_addr + block_size - 1; 2717 start_offset = block_size - 1; 2718 } 2719 2720 /* If a final byte is left behind, then call the callback with it. */ 2721 if (defecit > 0) { 2722 EFUN(callback(arg, 1, (uint16_t)read_val)); 2723 } 2724 2725 return(ERR_CODE_NONE); 2726 } 2727 2728 uint8_t blackhawk_tsc_INTERNAL_grp_idx_from_lane(uint8_t lane) { 2729 return(lane>>1); 2730 } 2731 2732 err_code_t blackhawk_tsc_INTERNAL_get_lms_thresh_bin(srds_access_t *sa__, int8_t *lms_thresh_bin) { 2733 ESTM(*lms_thresh_bin = (int8_t)rd_afe_lms_thresh_bin()); 2734 return(ERR_CODE_NONE); 2735 } 2736 2737 err_code_t blackhawk_tsc_INTERNAL_poll_dbgfb_idx_lock(srds_access_t *sa__, uint8_t timeout_ms) { 2738 uint32_t loop, max_loop = 10; 2739 uint8_t idx_lock = 0; 2740 2741 /* poll for first 10 times and then wait for timeout_ms before polling */ 2742 for (loop = 0; loop < max_loop; loop++) { 2743 ESTM(idx_lock = rd_dbg_fdbk_idx_lock()); 2744 if (idx_lock) { 2745 return (ERR_CODE_NONE); 2746 } 2747 } 2748 /* polled for 10 times, wait for timeout_ms right here before polling the register */ 2749 EFUN(blackhawk_tsc_delay_us(timeout_ms * 1000)); 2750 ESTM(idx_lock = rd_dbg_fdbk_idx_lock()); 2751 if (idx_lock) { 2752 return (ERR_CODE_NONE); 2753 } else { 2754 ESTM_PRINTF(("!!!!ERROR!!!! polling for dbgfb idx lock timedout after %d ms \n", timeout_ms)); 2755 /* Error Code for polling timeout */ 2756 return (blackhawk_tsc_error(sa__, ERR_CODE_POLLING_TIMEOUT)); 2757 } 2758 } 2759 2760 err_code_t blackhawk_tsc_get_dbgfb_summary(srds_access_t *sa__, dbgfb_cfg_st *dbgfb_cfg) { 2761 uint32_t d_0_n1, d_0_0, d_0_p1, d_1_n1, d_1_0, d_1_p1; 2762 uint32_t pdet, ndet; 2763 int32_t tdet; 2764 enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ; 2765 2766 EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode)); 2767 if (pam_mode == NRZ) { 2768 EFUN_PRINTF(("!!!!ERROR!!!! rx_pam_mode is set to NRZ , blackhawk_tsc_get_dbgfb_summary cannot continue\n")); 2769 return(ERR_CODE_INVALID_RX_PAM_MODE); 2770 } 2771 2772 EFUN(wr_dbg_fdbk_en(1)); 2773 EFUN(wr_fdbk_counting_mode(0)); 2774 EFUN(wr_dbg_fdbk_data_threshold(dbgfb_cfg->y)); 2775 EFUN(wr_dbg_fdbk_data_sel(1)); 2776 if (dbgfb_cfg->x) { 2777 EFUN(wr_inlv_idx(78)); 2778 EFUN(wr_dbg_fdbk_idx(dbgfb_cfg->x -1)); 2779 EFUN(wr_frc_index_diffprec(1)); 2780 EFUN(blackhawk_tsc_INTERNAL_poll_dbgfb_idx_lock(sa__, 100)); 2781 EFUN(wr_frc_index_diffprec(0)); 2782 EFUN(wr_dbg_fdbk_idx_monitor_en(0)); 2783 EFUN(wr_dbg_fdbk_idx_monitor_en(1)); 2784 } else { 2785 EFUN(wr_dbg_fdbk_idx(1)); 2786 EFUN(wr_dbg_fdbk_idx(0)); 2787 EFUN(wr_dbg_fdbk_idx_monitor_en(0)); 2788 } 2789 2790 EFUN(USR_DELAY_US(dbgfb_cfg->time_in_us)); 2791 2792 EFUN(wr_dbg_fdbk_en(0)); 2793 ESTM(d_1_n1 = rd_dbg_fdbk_counter_0()); 2794 2795 ESTM(d_1_0 = rd_dbg_fdbk_counter_1()); 2796 ESTM(d_1_p1 = rd_dbg_fdbk_counter_2()); 2797 ESTM(d_0_n1 = rd_dbg_fdbk_counter_3()); 2798 ESTM(d_0_0 = rd_dbg_fdbk_counter_4()); 2799 ESTM(d_0_p1 = rd_dbg_fdbk_counter_5()); 2800 2801 tdet = d_1_n1 + d_0_p1-d_0_n1 - d_1_p1; 2802 pdet = d_1_n1 + d_1_0 + d_1_p1; 2803 ndet = d_0_n1 + d_0_0 + d_0_p1; 2804 dbgfb_cfg->data2 = pdet; 2805 dbgfb_cfg->data3 = ndet; 2806 dbgfb_cfg->data1 = tdet; 2807 return ERR_CODE_NONE; 2808 } 2809 2810 err_code_t blackhawk_tsc_collect_dbgfb_stats(srds_access_t *sa__, uint32_t time_in_us, dbgfb_stats_st *dbgfb_stats) { 2811 uint8_t y, x; 2812 uint8_t max_y; 2813 enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ; 2814 uint8_t pam4es_en = 0; 2815 dbgfb_cfg_st dbgfb_cfg = {0}; 2816 2817 EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode)); 2818 if (pam_mode == NRZ) { 2819 EFUN_PRINTF(("!!!!ERROR!!!! rx_pam_mode is set to NRZ , blackhawk_tsc_collect_dbgfb_stats cannot continue\n")); 2820 return(ERR_CODE_INVALID_RX_PAM_MODE); 2821 } 2822 pam4es_en = (pam_mode==PAM4_ES); 2823 max_y = pam4es_en ? 6 : 3; 2824 /* backup the measure time and pam4es_en info */ 2825 dbgfb_stats->time_in_us = time_in_us; 2826 dbgfb_stats->pam4es_en = pam4es_en; 2827 2828 2829 for (y=0; y < max_y; y++){ 2830 for (x = 0; x < _X_; x++){ 2831 dbgfb_cfg.y = y; 2832 dbgfb_cfg.x = x; 2833 dbgfb_cfg.time_in_us = time_in_us; 2834 dbgfb_cfg.data1 = 0; 2835 dbgfb_cfg.data2 = 0; 2836 dbgfb_cfg.data3 = 0; 2837 EFUN(blackhawk_tsc_get_dbgfb_summary(sa__, &dbgfb_cfg)); 2838 dbgfb_stats->time_in_us = time_in_us; 2839 dbgfb_stats->data.data1[x][y] = dbgfb_cfg.data1; 2840 dbgfb_stats->data.data2[x][y] = dbgfb_cfg.data2; 2841 dbgfb_stats->data.data3[x][y] = dbgfb_cfg.data3; 2842 dbgfb_stats->data.data4[x][y] = dbgfb_stats->data.data2[x][y] - dbgfb_stats->data.data3[x][y]; 2843 2844 } 2845 } 2846 return ERR_CODE_NONE; 2847 } 2848