merlin16_pcieg3_debug_functions.c (11970B)
1 /*********************************************************************************** 2 *********************************************************************************** 3 * File Name : merlin16_pcieg3_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_pcieg3_debug_functions.c 23 * Implementation of API debug functions 24 */ 25 26 #include "merlin16_pcieg3_debug_functions.h" 27 #include "merlin16_pcieg3_access.h" 28 #include "merlin16_pcieg3_common.h" 29 #include "merlin16_pcieg3_config.h" 30 #include "merlin16_pcieg3_functions.h" 31 #include "merlin16_pcieg3_internal.h" 32 #include "merlin16_pcieg3_internal_error.h" 33 #include "merlin16_pcieg3_prbs.h" 34 #include "merlin16_pcieg3_select_defns.h" 35 36 /*************************/ 37 /* Stop/Resume uC Lane */ 38 /*************************/ 39 40 err_code_t merlin16_pcieg3_stop_uc_lane(srds_access_t *sa__, uint8_t enable) { 41 42 return(merlin16_pcieg3_stop_rx_adaptation(sa__,enable)); 43 } 44 45 46 err_code_t merlin16_pcieg3_stop_uc_lane_status(srds_access_t *sa__, uint8_t *uc_lane_stopped) { 47 48 if(!uc_lane_stopped) { 49 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 50 } 51 52 ESTM(*uc_lane_stopped = rdv_usr_sts_micro_stopped()); 53 54 return (ERR_CODE_NONE); 55 } 56 57 /*******************************************************************/ 58 /* APIs to Write Core/Lane Config and User variables into uC RAM */ 59 /*******************************************************************/ 60 61 err_code_t merlin16_pcieg3_set_usr_ctrl_core_event_log_level(srds_access_t *sa__, uint8_t core_event_log_level) { 62 return(wrcv_usr_ctrl_core_event_log_level(core_event_log_level)); 63 } 64 65 err_code_t merlin16_pcieg3_set_usr_ctrl_lane_event_log_level(srds_access_t *sa__, uint8_t lane_event_log_level) { 66 return(wrv_usr_ctrl_lane_event_log_level(lane_event_log_level)); 67 } 68 69 70 /******************************************************************/ 71 /* APIs to Read Core/Lane Config and User variables from uC RAM */ 72 /******************************************************************/ 73 74 err_code_t merlin16_pcieg3_get_usr_ctrl_core_event_log_level(srds_access_t *sa__, uint8_t *core_event_log_level) { 75 76 if(!core_event_log_level) { 77 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 78 } 79 80 ESTM(*core_event_log_level = rdcv_usr_ctrl_core_event_log_level()); 81 82 return (ERR_CODE_NONE); 83 } 84 85 err_code_t merlin16_pcieg3_get_usr_ctrl_lane_event_log_level(srds_access_t *sa__, uint8_t *lane_event_log_level) { 86 87 if(!lane_event_log_level) { 88 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 89 } 90 91 ESTM(*lane_event_log_level = rdv_usr_ctrl_lane_event_log_level()); 92 return (ERR_CODE_NONE); 93 } 94 95 96 /****************************************/ 97 /* Serdes Register/Variable Dump APIs */ 98 /****************************************/ 99 100 err_code_t merlin16_pcieg3_reg_dump(srds_access_t *sa__) { 101 uint16_t addr, rddata; 102 103 EFUN_PRINTF(("\n**** SERDES REGISTER DUMP ****")); 104 105 for (addr = 0x0; addr < 0x10; addr++) { 106 if (!(addr % 16)) { 107 EFUN_PRINTF(("\n%04x ",addr)); 108 } 109 EFUN(merlin16_pcieg3_pmd_rdt_reg(sa__, addr,&rddata)); 110 EFUN_PRINTF(("%04x ",rddata)); 111 } 112 113 for (addr = 0x90; addr < 0xA0; addr++) { 114 if (!(addr % 16)) { 115 EFUN_PRINTF(("\n%04x ",addr)); 116 } 117 EFUN(merlin16_pcieg3_pmd_rdt_reg(sa__, addr,&rddata)); 118 EFUN_PRINTF(("%04x ",rddata)); 119 } 120 121 for (addr = 0xD000; addr < 0xD1A0; addr++) { 122 if (!(addr % 16)) { 123 EFUN_PRINTF(("\n%04x ",addr)); 124 } 125 EFUN(merlin16_pcieg3_pmd_rdt_reg(sa__, addr,&rddata)); 126 EFUN_PRINTF(("%04x ",rddata)); 127 } 128 129 for (addr = 0xD300; addr < 0xD340; addr++) { 130 if (!(addr % 16)) { 131 EFUN_PRINTF(("\n%04x ", addr)); 132 } 133 EFUN(merlin16_pcieg3_pmd_rdt_reg(sa__, addr, &rddata)); 134 EFUN_PRINTF(("%04x ", rddata)); 135 } 136 for (addr = 0xD200; addr < 0xD230; addr++) { 137 if (!(addr % 16)) { 138 EFUN_PRINTF(("\n%04x ",addr)); 139 } 140 EFUN(merlin16_pcieg3_pmd_rdt_reg(sa__, addr,&rddata)); 141 EFUN_PRINTF(("%04x ",rddata)); 142 } 143 for (addr = 0xFFD0; addr < 0xFFE0; addr++) { 144 if (!(addr % 16)) { 145 EFUN_PRINTF(("\n%04x ",addr)); 146 } 147 EFUN(merlin16_pcieg3_pmd_rdt_reg(sa__, addr,&rddata)); 148 EFUN_PRINTF(("%04x ",rddata)); 149 } 150 return (ERR_CODE_NONE); 151 } 152 153 154 err_code_t merlin16_pcieg3_uc_core_var_dump(srds_access_t *sa__) { 155 uint8_t addr; 156 157 EFUN_PRINTF(("\n**** SERDES UC CORE RAM VARIABLE DUMP ****")); 158 159 for (addr = 0x0; addr < 0xFF; addr++) { 160 if (!(addr % 26)) { 161 EFUN_PRINTF(("\n%04x ",addr)); 162 } 163 ESTM_PRINTF(("%02x ", merlin16_pcieg3_rdbc_uc_var(sa__, __ERR, addr))); 164 } 165 return (ERR_CODE_NONE); 166 } 167 168 169 err_code_t merlin16_pcieg3_uc_lane_var_dump(srds_access_t *sa__) { 170 uint8_t rx_lock, uc_stopped = 0; 171 uint16_t addr; 172 EFUN_PRINTF(("\n**** SERDES UC LANE %d RAM VARIABLE DUMP ****",merlin16_pcieg3_get_lane(sa__))); 173 174 ESTM(rx_lock = rd_pmd_rx_lock()); 175 176 { 177 err_code_t err_code=ERR_CODE_NONE; 178 uc_stopped = merlin16_pcieg3_INTERNAL_stop_micro(sa__,rx_lock,&err_code); 179 if(err_code) USR_PRINTF(("Unable to stop microcontroller, following data is suspect\n")); 180 } 181 182 for (addr = 0x0; addr < LANE_VAR_RAM_SIZE; addr++) { 183 if (!(addr % 26)) { 184 EFUN_PRINTF(("\n%04x ",addr)); 185 } 186 ESTM_PRINTF(("%02x ", merlin16_pcieg3_rdbl_uc_var(sa__, __ERR, addr))); 187 } 188 189 if (rx_lock == 1) { 190 if (!uc_stopped) { 191 EFUN(merlin16_pcieg3_stop_rx_adaptation(sa__, 0)); 192 } 193 } else { 194 EFUN(merlin16_pcieg3_stop_rx_adaptation(sa__, 0)); 195 } 196 197 return (ERR_CODE_NONE); 198 } 199 200 /***************************************/ 201 /* API Function to Read Event Logger */ 202 /***************************************/ 203 204 err_code_t merlin16_pcieg3_read_event_log(srds_access_t *sa__) { 205 merlin16_pcieg3_INTERNAL_event_log_dump_state_t state; 206 uint8_t micro_num = 0; 207 { 208 state.index = 0; 209 state.line_start_index = 0; 210 EFUN(merlin16_pcieg3_INTERNAL_read_event_log_with_callback(sa__, micro_num, 0, &state, merlin16_pcieg3_INTERNAL_event_log_dump_callback)); 211 EFUN(merlin16_pcieg3_INTERNAL_event_log_dump_callback(&state, 0, 0)); 212 } 213 return(ERR_CODE_NONE); 214 } 215 216 /**********************************************/ 217 /* Loopback and Ultra-Low Latency Functions */ 218 /**********************************************/ 219 220 /* Enable/Diasble Digital Loopback */ 221 err_code_t merlin16_pcieg3_dig_lpbk(srds_access_t *sa__, uint8_t enable) { 222 /* setting/clearing prbs_chk_en_auto_mode while coming out of/going in to dig lpbk */ 223 EFUN(wr_prbs_chk_en_auto_mode(!enable)); 224 EFUN(wr_dig_lpbk_en(enable)); /* 0 = diabled, 1 = enabled */ 225 226 /* Making PRBS from generator have higher priority than linktrn PRBS to drive TX */ 227 EFUN(wr_tx_mux_sel_order(enable)); 228 229 return (ERR_CODE_NONE); 230 } 231 232 233 /**********************************/ 234 /* TX_PI Jitter Generation APIs */ 235 /**********************************/ 236 237 /* TX_PI Sinusoidal or Spread-Spectrum (SSC) Jitter Generation */ 238 err_code_t merlin16_pcieg3_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) { 239 /* Added a limiting for the jitter amplitude index, per freq_idx */ 240 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}; 241 242 /* Irrespective of the osr_mode, txpi runs @ os1. Thus the max amp idx values remain the same. */ 243 if (jit_type == TX_PI_SJ) { 244 if (tx_pi_jit_amp > max_amp_idx_r20_os1[tx_pi_jit_freq_idx]) { 245 tx_pi_jit_amp = max_amp_idx_r20_os1[tx_pi_jit_freq_idx]; 246 } 247 } 248 249 EFUN(merlin16_pcieg3_tx_pi_freq_override(sa__, enable, freq_override_val)); 250 251 if (enable) { 252 EFUN(wr_tx_pi_jit_freq_idx(tx_pi_jit_freq_idx)); 253 EFUN(wr_tx_pi_jit_amp(tx_pi_jit_amp)); 254 255 if (jit_type == TX_PI_SSC_HIGH_FREQ) { 256 EFUN(wr_tx_pi_jit_ssc_freq_mode(0x1)); /* SSC_FREQ_MODE: 0 = 6G SSC mode, 1 = 10G SSC mode */ 257 EFUN(wr_tx_pi_ssc_gen_en(0x1)); /* SSC jitter enable: 0 = disabled, 1 = enabled */ 258 } 259 else if (jit_type == TX_PI_SSC_LOW_FREQ) { 260 EFUN(wr_tx_pi_jit_ssc_freq_mode(0x0)); /* SSC_FREQ_MODE: 0 = 6G SSC mode, 1 = 10G SSC mode */ 261 EFUN(wr_tx_pi_ssc_gen_en(0x1)); /* SSC jitter enable: 0 = disabled, 1 = enabled */ 262 } 263 else if (jit_type == TX_PI_SJ) { 264 EFUN(wr_tx_pi_sj_gen_en(0x1)); /* Sinusoidal jitter enable: 0 = disabled, 1 = enabled */ 265 } 266 } 267 else { 268 EFUN(wr_tx_pi_ssc_gen_en(0x0)); /* SSC jitter enable: 0 = disabled, 1 = enabled */ 269 EFUN(wr_tx_pi_sj_gen_en(0x0)); /* Sinusoidal jitter enable: 0 = disabled, 1 = enabled */ 270 } 271 return (ERR_CODE_NONE); 272 } 273 274 275 /*******************************/ 276 /* Isolate Serdes Input Pins */ 277 /*******************************/ 278 279 err_code_t merlin16_pcieg3_isolate_ctrl_pins(srds_access_t *sa__, uint8_t enable) { 280 uint8_t lane, lane_orig, num_lanes; 281 merlin16_pcieg3_info_t const * const merlin16_pcieg3_info_ptr = merlin16_pcieg3_INTERNAL_get_merlin16_pcieg3_info_ptr(); 282 EFUN(merlin16_pcieg3_isolate_core_ctrl_pins(sa__, enable)); 283 284 ESTM(lane_orig = merlin16_pcieg3_get_lane(sa__)); 285 num_lanes = merlin16_pcieg3_info_ptr->lane_count * merlin16_pcieg3_info_ptr->micro_count; 286 for(lane = 0; lane < num_lanes; lane++) { 287 EFUN(merlin16_pcieg3_set_lane(sa__, lane)); 288 EFUN(merlin16_pcieg3_isolate_lane_ctrl_pins(sa__, enable)); 289 } 290 EFUN(merlin16_pcieg3_set_lane(sa__, lane_orig)); 291 292 return (ERR_CODE_NONE); 293 } 294 295 err_code_t merlin16_pcieg3_isolate_lane_ctrl_pins(srds_access_t *sa__, uint8_t enable) { 296 297 if (enable) { 298 EFUN(wr_pmd_ln_tx_h_pwrdn_pkill(0x1)); 299 EFUN(wr_pmd_ln_rx_h_pwrdn_pkill(0x1)); 300 EFUN(wr_pmd_ln_dp_h_rstb_pkill(0x1)); 301 EFUN(wr_pmd_ln_h_rstb_pkill(0x1)); 302 EFUN(wr_pmd_tx_disable_pkill(0x1)); 303 } 304 else { 305 EFUN(wr_pmd_ln_tx_h_pwrdn_pkill(0x0)); 306 EFUN(wr_pmd_ln_rx_h_pwrdn_pkill(0x0)); 307 EFUN(wr_pmd_ln_dp_h_rstb_pkill(0x0)); 308 EFUN(wr_pmd_ln_h_rstb_pkill(0x0)); 309 EFUN(wr_pmd_tx_disable_pkill(0x0)); 310 } 311 return (ERR_CODE_NONE); 312 } 313 314 err_code_t merlin16_pcieg3_isolate_core_ctrl_pins(srds_access_t *sa__, uint8_t enable) { 315 316 if (enable) { 317 EFUN(wrc_pmd_core_dp_h_rstb_pkill(0x1)); 318 } 319 else { 320 EFUN(wrc_pmd_core_dp_h_rstb_pkill(0x0)); 321 } 322 return (ERR_CODE_NONE); 323 } 324