openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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