merlin16_debug_functions.c (15867B)
1 /*********************************************************************************** 2 *********************************************************************************** 3 * File Name : merlin16_debug_functions.c * 4 * Created On : 03 Nov 2015 * 5 * Created By : Brent Roberts * 6 * Description : APIs for Serdes IPs * 7 * Revision : * 8 * * 9 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 10 * 11 * Copyright 2007-2019 Broadcom Inc. All rights reserved. * 12 * No portions of this material may be reproduced in any form without * 13 * the written permission of: * 14 * Broadcom Corporation * 15 * 5300 California Avenue * 16 * Irvine, CA 92617 * 17 * * 18 * All information contained in this document is Broadcom Corporation * 19 * company private proprietary, and trade secret. * 20 */ 21 22 /** @file merlin16_debug_functions.c 23 * Implementation of API debug functions 24 */ 25 26 #include <phymod/phymod_system.h> 27 #include "merlin16_debug_functions.h" 28 #include "merlin16_access.h" 29 #include "merlin16_common.h" 30 #include "merlin16_config.h" 31 #include "merlin16_functions.h" 32 #include "merlin16_internal.h" 33 #include "merlin16_internal_error.h" 34 #include "merlin16_prbs.h" 35 #include "merlin16_select_defns.h" 36 37 38 39 /*************************/ 40 /* Stop/Resume uC Lane */ 41 /*************************/ 42 43 err_code_t merlin16_stop_uc_lane(srds_access_t *sa__, uint8_t enable) { 44 45 return(merlin16_stop_rx_adaptation(sa__,enable)); 46 } 47 48 49 err_code_t merlin16_stop_uc_lane_status(srds_access_t *sa__, uint8_t *uc_lane_stopped) { 50 51 if(!uc_lane_stopped) { 52 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 53 } 54 55 ESTM(*uc_lane_stopped = rdv_usr_sts_micro_stopped()); 56 57 return (ERR_CODE_NONE); 58 } 59 60 /*******************************************************************/ 61 /* APIs to Write Core/Lane Config and User variables into uC RAM */ 62 /*******************************************************************/ 63 64 err_code_t merlin16_set_usr_ctrl_core_event_log_level(srds_access_t *sa__, uint8_t core_event_log_level) { 65 return(wrcv_usr_ctrl_core_event_log_level(core_event_log_level)); 66 } 67 68 err_code_t merlin16_set_usr_ctrl_lane_event_log_level(srds_access_t *sa__, uint8_t lane_event_log_level) { 69 return(wrv_usr_ctrl_lane_event_log_level(lane_event_log_level)); 70 } 71 72 err_code_t merlin16_set_usr_ctrl_disable_startup(srds_access_t *sa__, struct merlin16_usr_ctrl_disable_functions_st set_val) { 73 EFUN(merlin16_INTERNAL_update_usr_ctrl_disable_functions_byte(&set_val)); 74 return(wrv_usr_ctrl_disable_startup_functions_byte(set_val.byte)); 75 } 76 77 err_code_t merlin16_set_usr_ctrl_disable_startup_dfe(srds_access_t *sa__, struct merlin16_usr_ctrl_disable_dfe_functions_st set_val) { 78 EFUN(merlin16_INTERNAL_update_usr_ctrl_disable_dfe_functions_byte(&set_val)); 79 return(wrv_usr_ctrl_disable_startup_dfe_functions_byte(set_val.byte)); 80 } 81 82 err_code_t merlin16_set_usr_ctrl_disable_steady_state(srds_access_t *sa__, struct merlin16_usr_ctrl_disable_functions_st set_val) { 83 EFUN(merlin16_INTERNAL_check_uc_lane_stopped(sa__)); /* make sure uC is stopped to avoid race conditions */ 84 EFUN(merlin16_INTERNAL_update_usr_ctrl_disable_functions_byte(&set_val)); 85 return(wrv_usr_ctrl_disable_steady_state_functions_byte(set_val.byte)); 86 } 87 88 err_code_t merlin16_set_usr_ctrl_disable_steady_state_dfe(srds_access_t *sa__, struct merlin16_usr_ctrl_disable_dfe_functions_st set_val) { 89 EFUN(merlin16_INTERNAL_update_usr_ctrl_disable_dfe_functions_byte(&set_val)); 90 return(wrv_usr_ctrl_disable_steady_state_dfe_functions_byte(set_val.byte)); 91 } 92 93 /******************************************************************/ 94 /* APIs to Read Core/Lane Config and User variables from uC RAM */ 95 /******************************************************************/ 96 97 err_code_t merlin16_get_usr_ctrl_core_event_log_level(srds_access_t *sa__, uint8_t *core_event_log_level) { 98 99 if(!core_event_log_level) { 100 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 101 } 102 103 ESTM(*core_event_log_level = rdcv_usr_ctrl_core_event_log_level()); 104 105 return (ERR_CODE_NONE); 106 } 107 108 err_code_t merlin16_get_usr_ctrl_lane_event_log_level(srds_access_t *sa__, uint8_t *lane_event_log_level) { 109 110 if(!lane_event_log_level) { 111 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 112 } 113 114 ESTM(*lane_event_log_level = rdv_usr_ctrl_lane_event_log_level()); 115 return (ERR_CODE_NONE); 116 } 117 118 err_code_t merlin16_get_usr_ctrl_disable_startup(srds_access_t *sa__, struct merlin16_usr_ctrl_disable_functions_st *get_val) { 119 120 if(!get_val) { 121 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 122 } 123 124 ESTM(get_val->byte = rdv_usr_ctrl_disable_startup_functions_byte()); 125 EFUN(merlin16_INTERNAL_update_usr_ctrl_disable_functions_st(get_val)); 126 return (ERR_CODE_NONE); 127 } 128 129 err_code_t merlin16_get_usr_ctrl_disable_startup_dfe(srds_access_t *sa__, struct merlin16_usr_ctrl_disable_dfe_functions_st *get_val) { 130 131 if(!get_val) { 132 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 133 } 134 135 ESTM(get_val->byte = rdv_usr_ctrl_disable_startup_dfe_functions_byte()); 136 EFUN(merlin16_INTERNAL_update_usr_ctrl_disable_dfe_functions_st(get_val)); 137 return (ERR_CODE_NONE); 138 } 139 140 err_code_t merlin16_get_usr_ctrl_disable_steady_state(srds_access_t *sa__, struct merlin16_usr_ctrl_disable_functions_st *get_val) { 141 142 if(!get_val) { 143 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 144 } 145 146 ESTM(get_val->byte = rdv_usr_ctrl_disable_steady_state_functions_byte()); 147 EFUN(merlin16_INTERNAL_update_usr_ctrl_disable_functions_st(get_val)); 148 return (ERR_CODE_NONE); 149 } 150 151 err_code_t merlin16_get_usr_ctrl_disable_steady_state_dfe(srds_access_t *sa__, struct merlin16_usr_ctrl_disable_dfe_functions_st *get_val) { 152 153 if(!get_val) { 154 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 155 } 156 157 ESTM(get_val->byte = rdv_usr_ctrl_disable_steady_state_dfe_functions_byte()); 158 EFUN(merlin16_INTERNAL_update_usr_ctrl_disable_dfe_functions_st(get_val)); 159 return (ERR_CODE_NONE); 160 } 161 162 /****************************************/ 163 /* Serdes Register/Variable Dump APIs */ 164 /****************************************/ 165 166 err_code_t merlin16_reg_dump(srds_access_t *sa__) { 167 uint16_t addr, rddata = 0; 168 169 EFUN_PRINTF(("\n**** SERDES REGISTER DUMP ****")); 170 171 for (addr = 0x0; addr < 0x10; addr++) { 172 if (!(addr % 16)) { 173 EFUN_PRINTF(("\n%04x ",addr)); 174 } 175 EFUN(merlin16_pmd_rdt_reg(sa__, addr,&rddata)); 176 EFUN_PRINTF(("%04x ",rddata)); 177 } 178 179 for (addr = 0x90; addr < 0xA0; addr++) { 180 if (!(addr % 16)) { 181 EFUN_PRINTF(("\n%04x ",addr)); 182 } 183 EFUN(merlin16_pmd_rdt_reg(sa__, addr,&rddata)); 184 EFUN_PRINTF(("%04x ",rddata)); 185 } 186 187 for (addr = 0xD000; addr < 0xD1A0; addr++) { 188 if (!(addr % 16)) { 189 EFUN_PRINTF(("\n%04x ",addr)); 190 } 191 EFUN(merlin16_pmd_rdt_reg(sa__, addr,&rddata)); 192 EFUN_PRINTF(("%04x ",rddata)); 193 } 194 195 for (addr = 0xD200; addr < 0xD230; addr++) { 196 if (!(addr % 16)) { 197 EFUN_PRINTF(("\n%04x ",addr)); 198 } 199 EFUN(merlin16_pmd_rdt_reg(sa__, addr,&rddata)); 200 EFUN_PRINTF(("%04x ",rddata)); 201 } 202 for (addr = 0xFFD0; addr < 0xFFE0; addr++) { 203 if (!(addr % 16)) { 204 EFUN_PRINTF(("\n%04x ",addr)); 205 } 206 EFUN(merlin16_pmd_rdt_reg(sa__, addr,&rddata)); 207 EFUN_PRINTF(("%04x ",rddata)); 208 } 209 return (ERR_CODE_NONE); 210 } 211 212 213 err_code_t merlin16_uc_core_var_dump(srds_access_t *sa__) { 214 uint8_t addr; 215 216 EFUN_PRINTF(("\n**** SERDES UC CORE RAM VARIABLE DUMP ****")); 217 218 for (addr = 0x0; addr < 0xFF; addr++) { 219 if (!(addr % 26)) { 220 EFUN_PRINTF(("\n%04x ",addr)); 221 } 222 ESTM_PRINTF(("%02x ", merlin16_rdbc_uc_var(sa__, __ERR, addr))); 223 } 224 return (ERR_CODE_NONE); 225 } 226 227 228 err_code_t merlin16_uc_lane_var_dump(srds_access_t *sa__) { 229 uint8_t rx_lock, uc_stopped = 0; 230 uint16_t addr; 231 EFUN_PRINTF(("\n**** SERDES UC LANE %d RAM VARIABLE DUMP ****",merlin16_get_lane(sa__))); 232 233 ESTM(rx_lock = rd_pmd_rx_lock()); 234 235 { 236 err_code_t err_code=ERR_CODE_NONE; 237 uc_stopped = merlin16_INTERNAL_stop_micro(sa__,rx_lock,&err_code); 238 if(err_code) USR_PRINTF(("Unable to stop microcontroller, following data is suspect\n")); 239 } 240 241 for (addr = 0x0; addr < LANE_VAR_RAM_SIZE; addr++) { 242 if (!(addr % 26)) { 243 EFUN_PRINTF(("\n%04x ",addr)); 244 } 245 ESTM_PRINTF(("%02x ", merlin16_rdbl_uc_var(sa__, __ERR, addr))); 246 } 247 248 if (rx_lock == 1) { 249 if (!uc_stopped) { 250 EFUN(merlin16_stop_rx_adaptation(sa__, 0)); 251 } 252 } else { 253 EFUN(merlin16_stop_rx_adaptation(sa__, 0)); 254 } 255 256 return (ERR_CODE_NONE); 257 } 258 259 /***************************************/ 260 /* API Function to Read Event Logger */ 261 /***************************************/ 262 263 err_code_t merlin16_read_event_log(srds_access_t *sa__) { 264 merlin16_INTERNAL_event_log_dump_state_t state; 265 uint8_t micro_num = 0; 266 { 267 state.index = 0; 268 state.line_start_index = 0; 269 EFUN(merlin16_INTERNAL_read_event_log_with_callback(sa__, micro_num, 0, &state, merlin16_INTERNAL_event_log_dump_callback)); 270 EFUN(merlin16_INTERNAL_event_log_dump_callback(&state, 0, 0)); 271 } 272 return(ERR_CODE_NONE); 273 } 274 275 /**********************************************/ 276 /* Loopback and Ultra-Low Latency Functions */ 277 /**********************************************/ 278 279 /* Enable/Disable Digital Loopback */ 280 err_code_t merlin16_dig_lpbk(srds_access_t *sa__, uint8_t enable) { 281 /* setting/clearing prbs_chk_en_auto_mode while coming out of/going in to dig lpbk */ 282 EFUN(wr_prbs_chk_en_auto_mode(!enable)); 283 EFUN(wr_dig_lpbk_en(enable)); /* 0 = disabled, 1 = enabled */ 284 285 /* Disabling Link Training as it's an invalid mode in digital loopback */ 286 if(enable) { 287 uint8_t link_training_enable = 0; 288 ESTM(link_training_enable = rd_cl72_ieee_training_enable()); 289 if(link_training_enable) { 290 EFUN_PRINTF(("Warning: Core: %d, Lane %d: Link Training mode is on in digital loopback.\n", merlin16_get_core(sa__), merlin16_get_lane(sa__))); 291 } 292 } 293 return (ERR_CODE_NONE); 294 } 295 296 297 /* Enable/Diasble Digital Loopback for Repeater */ 298 err_code_t merlin16_dig_lpbk_rptr(srds_access_t *sa__, uint8_t enable, enum srds_rptr_mode_enum mode) { 299 switch(mode) { 300 case DATA_IN_SIDE: 301 /* DATA_IN_SIDE - The side where data is fed into the RX serial input */ 302 if (enable) { 303 EFUN(merlin16_loop_timing(sa__, 0)); 304 EFUN(merlin16_loop_timing(sa__, 1)); /* Program DATA_IN_SIDE side TX_PI for loop-timing mode to lock SYS TX to SYS TX clock freq. */ 305 } else { 306 EFUN(merlin16_loop_timing(sa__, 0)); 307 } 308 break; 309 310 case DIG_LPBK_SIDE: 311 /* DIG_LPBK_SIDE - The side where data is looped back using digital loopback */ 312 313 EFUN(merlin16_tx_rptr_mode_timing(sa__, 1)); /* Program DIG_LPBK_SIDE side TX_PI for repeater mode to lock LINE TX to SYS RX clock freq. */ 314 EFUN(wr_dig_lpbk_en(enable)); /* 0 = diabled, 1 = enabled */ 315 EFUN(wr_ams_tx_ll_selpath_tx(0)); /* Switch mux and enable traffic to flow through */ 316 break; 317 318 default : return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 319 } 320 321 return (ERR_CODE_NONE); 322 } 323 324 325 err_code_t merlin16_nl_from_dig_lpbk(srds_access_t *sa__, enum srds_rptr_mode_enum mode) { 326 EFUN(merlin16_dig_lpbk_rptr(sa__, 0,mode)); 327 return (ERR_CODE_NONE); 328 329 } 330 331 332 /**********************************/ 333 /* TX_PI Jitter Generation APIs */ 334 /**********************************/ 335 336 /* TX_PI Sinusoidal or Spread-Spectrum (SSC) Jitter Generation */ 337 err_code_t merlin16_tx_pi_jitt_gen(srds_access_t *sa__, uint8_t enable, int16_t freq_override_val, enum srds_tx_pi_freq_jit_gen_enum jit_type, uint8_t tx_pi_jit_freq_idx, uint8_t tx_pi_jit_amp) { 338 /* Added a limiting for the jitter amplitude index, per freq_idx */ 339 uint8_t max_amp_idx_r20_os1[] = {37, 42, 48, 56, 33, 39, 47, 58, 37, 42, 48, 56, 33, 39, 47, 58, 37, 42, 48, 56, 33, 39, 47, 58, 37, 42, 48, 56, 33, 39, 47, 58, 37, 42, 48, 56, 33, 39, 47, 58, 37, 42, 48, 56, 33, 39, 47, 58, 37, 42, 48, 56, 33, 39, 47, 58, 37, 48, 33, 47, 37, 33, 37, 37}; 340 341 /* Irrespective of the osr_mode, txpi runs @ os1. Thus the max amp idx values remain the same. */ 342 if (jit_type == TX_PI_SJ) { 343 if (tx_pi_jit_amp > max_amp_idx_r20_os1[tx_pi_jit_freq_idx]) { 344 tx_pi_jit_amp = max_amp_idx_r20_os1[tx_pi_jit_freq_idx]; 345 } 346 } 347 348 EFUN(merlin16_tx_pi_freq_override(sa__, enable, freq_override_val)); 349 350 if (enable) { 351 EFUN(wr_tx_pi_jit_freq_idx(tx_pi_jit_freq_idx)); 352 EFUN(wr_tx_pi_jit_amp(tx_pi_jit_amp)); 353 354 if (jit_type == TX_PI_SSC_HIGH_FREQ) { 355 EFUN(wr_tx_pi_jit_ssc_freq_mode(0x1)); /* SSC_FREQ_MODE: 0 = 6G SSC mode, 1 = 10G SSC mode */ 356 EFUN(wr_tx_pi_ssc_gen_en(0x1)); /* SSC jitter enable: 0 = disabled, 1 = enabled */ 357 } 358 else if (jit_type == TX_PI_SSC_LOW_FREQ) { 359 EFUN(wr_tx_pi_jit_ssc_freq_mode(0x0)); /* SSC_FREQ_MODE: 0 = 6G SSC mode, 1 = 10G SSC mode */ 360 EFUN(wr_tx_pi_ssc_gen_en(0x1)); /* SSC jitter enable: 0 = disabled, 1 = enabled */ 361 } 362 else if (jit_type == TX_PI_SJ) { 363 EFUN(wr_tx_pi_sj_gen_en(0x1)); /* Sinusoidal jitter enable: 0 = disabled, 1 = enabled */ 364 } 365 } 366 else { 367 EFUN(wr_tx_pi_ssc_gen_en(0x0)); /* SSC jitter enable: 0 = disabled, 1 = enabled */ 368 EFUN(wr_tx_pi_sj_gen_en(0x0)); /* Sinusoidal jitter enable: 0 = disabled, 1 = enabled */ 369 } 370 return (ERR_CODE_NONE); 371 } 372 373 374 /*******************************/ 375 /* Isolate Serdes Input Pins */ 376 /*******************************/ 377 378 err_code_t merlin16_isolate_ctrl_pins(srds_access_t *sa__, uint8_t enable) { 379 uint8_t lane, lane_orig, num_lanes; 380 merlin16_info_t const * const merlin16_info_ptr = merlin16_INTERNAL_get_merlin16_info_ptr(); 381 EFUN(merlin16_isolate_core_ctrl_pins(sa__, enable)); 382 383 ESTM(lane_orig = merlin16_get_lane(sa__)); 384 num_lanes = merlin16_info_ptr->lane_count * merlin16_info_ptr->micro_count; 385 for(lane = 0; lane < num_lanes; lane++) { 386 EFUN(merlin16_set_lane(sa__, lane)); 387 EFUN(merlin16_isolate_lane_ctrl_pins(sa__, enable)); 388 } 389 EFUN(merlin16_set_lane(sa__, lane_orig)); 390 391 return (ERR_CODE_NONE); 392 } 393 394 err_code_t merlin16_isolate_lane_ctrl_pins(srds_access_t *sa__, uint8_t enable) { 395 396 if (enable) { 397 EFUN(wr_pmd_ln_tx_h_pwrdn_pkill(0x1)); 398 EFUN(wr_pmd_ln_rx_h_pwrdn_pkill(0x1)); 399 EFUN(wr_pmd_ln_dp_h_rstb_pkill(0x1)); 400 EFUN(wr_pmd_ln_h_rstb_pkill(0x1)); 401 EFUN(wr_pmd_tx_disable_pkill(0x1)); 402 } 403 else { 404 EFUN(wr_pmd_ln_tx_h_pwrdn_pkill(0x0)); 405 EFUN(wr_pmd_ln_rx_h_pwrdn_pkill(0x0)); 406 EFUN(wr_pmd_ln_dp_h_rstb_pkill(0x0)); 407 EFUN(wr_pmd_ln_h_rstb_pkill(0x0)); 408 EFUN(wr_pmd_tx_disable_pkill(0x0)); 409 } 410 return (ERR_CODE_NONE); 411 } 412 413 err_code_t merlin16_isolate_core_ctrl_pins(srds_access_t *sa__, uint8_t enable) { 414 415 if (enable) { 416 EFUN(wrc_pmd_core_dp_h_rstb_pkill(0x1)); 417 } 418 else { 419 EFUN(wrc_pmd_core_dp_h_rstb_pkill(0x0)); 420 } 421 return (ERR_CODE_NONE); 422 } 423 424