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

blackhawk_tsc_config.c (61447B)


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