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

time.c (503021B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:       time.c
      8  *
      9  * Remarks:    Broadcom StrataSwitch Time BroadSync API
     10  *
     11  * Functions:
     12  *      Private Interface functions
     13  *
     14  *      _bcm_esw_time_hw_clear
     15  *      _bcm_esw_time_deinit
     16  *      _bcm_esw_time_reinit
     17  *      _bcm_esw_time_interface_id_validate
     18  *      _bcm_esw_time_interface_input_validate
     19  *      _bcm_esw_time_interface_allocate_id
     20  *      _bcm_esw_time_interface_heartbeat_install
     21  *      _bcm_esw_time_interface_accuracy_time2hw
     22  *      _bcm_esw_time_interface_drift_install
     23  *      _bcm_esw_time_interface_offset_install
     24  *      _bcm_esw_time_interface_ref_clock_install
     25  *      _bcm_esw_time_interface_install
     26  *      _bcm_esw_time_interface_dual_bs_install
     27  *      _bcm_time_interface_free
     28  *      _bcm_esw_time_accuracy_parse
     29  *      _bcm_esw_time_input_parse
     30  *      _bcm_esw_time_capture_counter_read
     31  *      _bcm_esw_time_capture_get
     32  *      _bcm_esw_time_interface_offset_get
     33  *      _bcm_esw_time_interface_drift_get
     34  *      _bcm_esw_time_interface_ref_clock_get
     35  *      _bcm_esw_time_interface_accuracy_get
     36  *      _bcm_esw_time_interface_get
     37  *      _bcm_esw_time_interface_dual_bs_get
     38  *      _bcm_esw_time_hw_interrupt_dflt
     39  *      _bcm_esw_time_hw_interrupt
     40  *      _bcm_esw_time_trigger_to_timestamp_mode
     41  *      _bcm_esw_time_trigger_from_timestamp_mode
     42  *      _bcm_esw_time_bs_init
     43  *      _bcm_time_sw_dump
     44  *
     45  *      Public Interface functions
     46  *
     47  *      bcm_esw_time_init
     48  *      bcm_esw_time_deinit
     49  *      bcm_esw_time_interface_add
     50  *      bcm_esw_time_interface_delete
     51  *      bcm_esw_time_interface_get
     52  *      bcm_esw_time_interface_delete_all
     53  *      bcm_esw_time_interface_traverse
     54  *      bcm_esw_time_capture_get
     55  *      bcm_esw_time_heartbeat_enable_set
     56  *      bcm_esw_time_heartbeat_enable_get
     57  *      bcm_esw_time_trigger_enable_set
     58  *      bcm_esw_time_trigger_enable_get
     59  *      bcm_esw_time_heartbeat_register
     60  *      bcm_esw_time_heartbeat_unregister
     61  */
     62 
     63 #include <shared/util.h>
     64 #include <shared/bsl.h>
     65 #include <bcm/time.h>
     66 #include <bcm/error.h>
     67 
     68 #include <soc/defs.h>
     69 #include <soc/mem.h>
     70 #include <soc/iproc.h>
     71 #include <soc/drv.h>
     72 #include <soc/cmicm.h>
     73 
     74 #include <bcm/port.h>
     75 
     76 #include <bcm_int/common/time.h>
     77 #include <bcm_int/common/time-mbox.h>
     78 #include <bcm_int/common/mbox.h>
     79 
     80 #include <bcm_int/esw/mbcm.h>
     81 #include <bcm_int/esw_dispatch.h>
     82 #include <bcm_int/common/ptp.h>
     83 #ifdef BCM_CMICX_SUPPORT
     84 #include <soc/intr_cmicx.h>
     85 #endif
     86 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     87 #include <soc/trident2.h>
     88 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
     89 #if defined(BCM_GREYHOUND2_SUPPORT)
     90 #include <soc/phy/phyctrl.h>
     91 #endif /* BCM_GREYHOUND2_SUPPORT */
     92 #ifdef PORTMOD_SUPPORT
     93 #include <soc/esw/portctrl.h>
     94 #include <soc/portmod/portmod.h>
     95 #include <soc/portmod/portmod_internal.h>
     96 #endif
     97 #ifdef BCM_WARM_BOOT_SUPPORT
     98 #include <soc/scache.h>
     99 #endif
    100 #include <bcm_int/esw/switch.h>
    101 
    102 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
    103 #include <bcm_int/common/esmc.h>
    104 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
    105 
    106 #define BROAD_SYNC_TIME_CAPTURE_TIMEOUT      (10) /* useconds */
    107 #define BROAD_SYNC_OUTPUT_TOGGLE_TIME_DELAY  (3)  /* seconds */ 
    108 
    109 #define SYNT_TIME_SECONDS(unit, id) \
    110         TIME_INTERFACE_CONFIG(unit, id).time_capture.syntonous.seconds
    111 #define SYNT_TIME_NANOSECONDS(unit, id) \
    112         TIME_INTERFACE_CONFIG(unit, id).time_capture.syntonous.nanoseconds
    113 
    114 #define HX5_PORT_BLOCK_FIRST_PORT(port)                              \
    115         SOC_INFO(unit).port_l2p_mapping[port] <= 48 ?               \
    116         (1 + ((SOC_INFO(unit).port_l2p_mapping[port] - 1) & ~0xF)) :\
    117         (1 + ((SOC_INFO(unit).port_l2p_mapping[port] - 1) & ~0x3));
    118 
    119 #if defined(BCM_HITLESS_RESET_SUPPORT)
    120 #define HITLESS_REG(cmicd_reg_write)           \
    121     do {                                       \
    122         /* Double-writes per CMICD-110 WAR. */ \
    123         cmicd_reg_write;                       \
    124         cmicd_reg_write;                       \
    125     } while (0)
    126 
    127 #else
    128 #define HITLESS_REG(cmicd_reg_write)           \
    129     do {                                       \
    130         cmicd_reg_write;                       \
    131     } while (0)
    132 
    133 #endif /* defined(BCM_HITLESS_RESET_SUPPORT) */
    134 
    135 #if (defined(BCM_TIME_V3_SUPPORT) ||                                    \
    136      defined(BCM_KATANA2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) ||      \
    137      defined(BCM_HURRICANE2_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) || \
    138      defined(BCM_SABER2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||      \
    139      defined(BCM_HURRICANE3_SUPPORT) || defined(BCM_MONTEREY_SUPPORT))
    140     #define BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC (1)
    141 #endif
    142 
    143 #define SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)      \
    144     ((soc_feature(unit, soc_feature_time_v3)) ||              \
    145      (SOC_IS_KATANA2(unit)) || (SOC_IS_HELIX4(unit)) ||       \
    146      (SOC_IS_HURRICANE2(unit)) || (SOC_IS_GREYHOUND(unit)) || \
    147      (SOC_IS_SABER2(unit)) || (SOC_IS_TOMAHAWKX(unit)) ||      \
    148      (SOC_IS_HURRICANE3(unit)) || (SOC_IS_GREYHOUND2(unit)) || (SOC_IS_MONTEREY(unit)))
    149 
    150 #if (defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC) || \
    151      defined(BCM_KATANA_SUPPORT) ||             \
    152      defined(BCM_TRIUMPH3_SUPPORT) ||           \
    153      defined(BCM_TRIDENT2_SUPPORT))
    154 #define BCM_TIME_MANAGED_BROADSYNC (1)
    155 #endif
    156 
    157 #define SOC_HAS_MANAGED_BROADSYNC(unit)                  \
    158     (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit) || \
    159      SOC_IS_KATANA(unit) ||                              \
    160      SOC_IS_TRIUMPH3(unit) ||                            \
    161      SOC_IS_TD2_TT2(unit))
    162 
    163 #ifdef BCM_WARM_BOOT_SUPPORT
    164 #define BCM_WB_VERSION_1_0      SOC_SCACHE_VERSION(1,0)
    165 #define BCM_WB_DEFAULT_VERSION  BCM_WB_VERSION_1_0
    166 #endif  /* BCM_WARM_BOOT_SUPPORT */
    167 
    168 /****************************************************************************/
    169 /*                      LOCAL VARIABLES DECLARATION                         */
    170 /****************************************************************************/
    171 /* 8 TSC (TSC0~6, TSCF0) */
    172 static const int gh2_tsc_phy_port[] = {58, 62, 66, 70, 74, 78, 82, 86};
    173 
    174 static _bcm_time_config_p _bcm_time_config[BCM_MAX_NUM_UNITS] = {NULL};
    175 
    176 static bcm_time_spec_t _bcm_time_accuracy_arr[TIME_ACCURACY_CLK_MAX] = {
    177       {0, COMPILER_64_INIT(0,0),  25},        /* HW value = 32, accuracy up tp 25 nanosec */
    178       {0, COMPILER_64_INIT(0,0),  100},       /* HW value = 33, accuracy up to 100 nanosec */
    179       {0, COMPILER_64_INIT(0,0),  250},       /* HW value = 34, accuracy up to 250 nanosec */
    180       {0, COMPILER_64_INIT(0,0),  1000},      /* HW value = 35, accuracy up to 1 microsec */
    181       {0, COMPILER_64_INIT(0,0),  2500},      /* HW value = 36, accuracy up to 2.5 microsec */
    182       {0, COMPILER_64_INIT(0,0),  10000},     /* HW value = 37, accuracy up to 10 microsec */
    183       {0, COMPILER_64_INIT(0,0),  25000},     /* HW value = 38, accuracy up to 25 microsec */
    184       {0, COMPILER_64_INIT(0,0),  100000},    /* HW value = 39, accuracy up to 100 microsec */
    185       {0, COMPILER_64_INIT(0,0),  250000},    /* HW value = 40, accuracy up to 250 microsec */
    186       {0, COMPILER_64_INIT(0,0),  1000000},   /* HW value = 41, accuracy up to 1 milisec */
    187       {0, COMPILER_64_INIT(0,0),  2500000},   /* HW value = 42, accuracy up to 2.5 milisec */
    188       {0, COMPILER_64_INIT(0,0),  10000000},  /* HW value = 43, accuracy up to 10 milisec */
    189       {0, COMPILER_64_INIT(0,0),  25000000},  /* HW value = 44, accuracy up to 25 milisec */
    190       {0, COMPILER_64_INIT(0,0),  100000000}, /* HW value = 45, accuracy up to 100 milisec */
    191       {0, COMPILER_64_INIT(0,0),  250000000}, /* HW value = 46, accuracy up to 250 milisec */
    192       {0, COMPILER_64_INIT(0,1),  0},         /* HW value = 47, accuracy up to 1 sec */
    193       {0, COMPILER_64_INIT(0,10), 0},        /* HW value = 48, accuracy up to 10 sec */
    194       /* HW value = 49, accuracy greater than 10 sec */
    195       {0, COMPILER_64_INIT(0,TIME_ACCURACY_INFINITE), TIME_ACCURACY_INFINITE},
    196       /* HW value = 254 accuracy unknown */
    197       {0, COMPILER_64_INIT(0,TIME_ACCURACY_UNKNOWN), TIME_ACCURACY_UNKNOWN}
    198 };
    199 
    200 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
    201 STATIC
    202 soc_reg_t  _bcm_time_gpio_regs[TS_GPIO_COUNT] = { NS_TIMESYNC_GPIO_0_CTRLr,
    203                             NS_TIMESYNC_GPIO_1_CTRLr,
    204                             NS_TIMESYNC_GPIO_2_CTRLr,
    205                             NS_TIMESYNC_GPIO_3_CTRLr,
    206                             NS_TIMESYNC_GPIO_4_CTRLr,
    207                             NS_TIMESYNC_GPIO_5_CTRLr };
    208 
    209 STATIC
    210 soc_reg_t  _bcm_time_bs_pll_regs[2] = { NS_BROADSYNC0_CLK_EVENT_CTRLr,
    211                             NS_BROADSYNC1_CLK_EVENT_CTRLr };
    212 STATIC
    213 soc_reg_t __bcm_time_mapper_port_enable_regs[4] = { NS_TIMESYNC_MAPPER_PORT_ENABLE_0r,
    214                                          NS_TIMESYNC_MAPPER_PORT_ENABLE_1r,
    215                                          NS_TIMESYNC_MAPPER_PORT_ENABLE_2r,
    216                                          NS_TIMESYNC_MAPPER_PORT_ENABLE_3r
    217                                        };
    218 
    219 STATIC
    220 soc_reg_t _bcm_time_mapper_port_enable[32] = { PORT0_TS_ENABLEf, PORT1_TS_ENABLEf,
    221                                      PORT2_TS_ENABLEf, PORT3_TS_ENABLEf,
    222                                      PORT4_TS_ENABLEf, PORT5_TS_ENABLEf,
    223                                      PORT6_TS_ENABLEf, PORT7_TS_ENABLEf,
    224 
    225                                      PORT8_TS_ENABLEf, PORT9_TS_ENABLEf,
    226                                      PORT10_TS_ENABLEf, PORT11_TS_ENABLEf,
    227                                      PORT12_TS_ENABLEf, PORT13_TS_ENABLEf,
    228                                      PORT14_TS_ENABLEf, PORT15_TS_ENABLEf,
    229 
    230                                      PORT16_TS_ENABLEf, PORT17_TS_ENABLEf,
    231                                      PORT18_TS_ENABLEf, PORT19_TS_ENABLEf,
    232                                      PORT20_TS_ENABLEf, PORT21_TS_ENABLEf,
    233                                      PORT22_TS_ENABLEf, PORT23_TS_ENABLEf,
    234 
    235                                      PORT24_TS_ENABLEf, PORT25_TS_ENABLEf,
    236                                      PORT26_TS_ENABLEf, PORT27_TS_ENABLEf,
    237                                      PORT28_TS_ENABLEf, PORT29_TS_ENABLEf,
    238                                      PORT30_TS_ENABLEf, PORT31_TS_ENABLEf
    239                                   };
    240 
    241 
    242 STATIC
    243 uint8 _bcm_time_capture_event_state[BCM_TIME_CAPTURE_MAX_EVENT_ID];
    244 STATIC uint8    tsfifo_flag = 0;
    245 #endif
    246 
    247 /****************************************************************************/
    248 /*                     Internal functions implementation                    */
    249 /****************************************************************************/
    250 STATIC int 
    251 _bcm_esw_time_capture_get (int unit, bcm_time_if_t id, bcm_time_capture_t *time, uint32 flags);
    252 STATIC int 
    253 _bcm_esw_time_interface_offset_get(int unit, bcm_time_if_t id, bcm_time_spec_t *offset);
    254 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
    255     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \
    256     defined(BCM_HURRICANE2_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) || \
    257     defined(BCM_SABER2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
    258 STATIC int
    259 _bcm_esw_time_bs_init(int unit, bcm_time_interface_t *intf);
    260 STATIC int
    261 _bcm_esw_time_hw_clear(int unit, bcm_time_if_t intf_id);
    262 STATIC int
    263 _bcm_esw_time_hitless_reset(int unit, bcm_time_if_t intf_id);
    264 #endif
    265 
    266 #if defined(INCLUDE_GDPLL)
    267 extern void gdpll_intr(int unit, uint32 int_status, uint32 int_enable);
    268 #endif
    269 
    270 STATIC int
    271 _bcm_esw_time_synce_clock_source_squelch_set(int unit, bcm_time_synce_clock_src_type_t clk_src,
    272                             int squelch);
    273 STATIC int
    274 _bcm_esw_time_synce_clock_source_squelch_get(int unit, bcm_time_synce_clock_src_type_t clk_src,
    275                             int *squelch);
    276 
    277 STATIC int
    278 _bcm_esw_time_synce_clock_source_frequency_set(int unit, bcm_time_synce_clock_source_config_t *clk_src_config,
    279                             int frequency);
    280 STATIC int
    281 _bcm_esw_time_synce_clock_source_frequency_get(int unit, bcm_time_synce_clock_source_config_t *clk_src_config,
    282                             int *frequency);
    283 
    284 /*
    285  * Function:
    286  *    _bcm_esw_time_hw_clear
    287  * Purpose:
    288  *    Internal routine used to clear all HW registers and table to default values
    289  * Parameters:
    290  *    unit           - (IN) BCM device number.
    291  *    intf_id        - (IN) Time interface identifier
    292  * Returns:
    293  *    BCM_E_XXX
    294  */
    295 STATIC int
    296 _bcm_esw_time_hw_clear(int unit, bcm_time_if_t intf_id)
    297 {
    298     uint32 regval;
    299 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
    300     /*****************************************************************************/
    301     /*   Perform KATANA2, HELIX4, HURRICANE2, GREYHOUND, SABER2 IPROC HW configuration   */
    302     /*****************************************************************************/
    303 
    304     /* Reset Config register */
    305     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
    306         if (!soc_feature(unit, soc_feature_time_v3_no_bs)) {
    307             if(SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
    308                 READ_NS_BS0_BS_CONFIGr(unit, &regval);
    309                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, MODEf, TIME_MODE_OUTPUT);
    310                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
    311                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
    312                 HITLESS_REG(WRITE_NS_BS0_BS_CONFIGr(unit, regval));
    313 
    314                 READ_NS_BS1_BS_CONFIGr(unit, &regval);
    315                 soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, MODEf, TIME_MODE_OUTPUT);
    316                 soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
    317                 soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
    318                 HITLESS_REG(WRITE_NS_BS1_BS_CONFIGr(unit, regval));
    319 
    320                 READ_NS_BS0_BS_OUTPUT_TIME_0r(unit, &regval);
    321                 soc_reg_field_set(unit, NS_BS0_BS_OUTPUT_TIME_0r, &regval, ACCURACYf, 0);
    322                 soc_reg_field_set(unit, NS_BS0_BS_OUTPUT_TIME_0r, &regval, LOCKf, 0);
    323                 soc_reg_field_set(unit, NS_BS0_BS_OUTPUT_TIME_0r, &regval, EPOCHf, 0);
    324                 WRITE_NS_BS0_BS_OUTPUT_TIME_0r(unit, regval);
    325 
    326                 READ_NS_BS1_BS_OUTPUT_TIME_0r(unit, &regval);
    327                 soc_reg_field_set(unit, NS_BS1_BS_OUTPUT_TIME_0r, &regval, ACCURACYf, 0);
    328                 soc_reg_field_set(unit, NS_BS1_BS_OUTPUT_TIME_0r, &regval, LOCKf, 0);
    329                 soc_reg_field_set(unit, NS_BS1_BS_OUTPUT_TIME_0r, &regval, EPOCHf, 0);
    330                 WRITE_NS_BS1_BS_OUTPUT_TIME_0r(unit, regval);
    331 
    332                 /* Reset Clock Control */
    333                 READ_NS_BS0_BS_CLK_CTRLr(unit, &regval);
    334                 soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, ENABLEf, 0);
    335                 HITLESS_REG(WRITE_NS_BS0_BS_CLK_CTRLr(unit, regval));
    336 
    337                 READ_NS_BS1_BS_CLK_CTRLr(unit, &regval);
    338                 soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, ENABLEf, 0);
    339                 HITLESS_REG(WRITE_NS_BS1_BS_CLK_CTRLr(unit, regval));
    340 
    341                 /* Reset HeartBeat */
    342                 READ_NS_BS0_BS_HEARTBEAT_CTRLr(unit, &regval);
    343                 soc_reg_field_set(unit, NS_BS0_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 0);
    344                 HITLESS_REG(WRITE_NS_BS0_BS_HEARTBEAT_CTRLr(unit, regval));
    345 
    346                 READ_NS_BS1_BS_HEARTBEAT_CTRLr(unit, &regval);
    347                 soc_reg_field_set(unit, NS_BS1_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 0);
    348                 HITLESS_REG(WRITE_NS_BS1_BS_HEARTBEAT_CTRLr(unit, regval));
    349             } else {
    350 
    351                 READ_CMIC_BS0_CONFIGr(unit, &regval);
    352                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, MODEf, TIME_MODE_OUTPUT);
    353                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
    354                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
    355                 HITLESS_REG(WRITE_CMIC_BS0_CONFIGr(unit, regval));
    356 
    357                 READ_CMIC_BS1_CONFIGr(unit, &regval);
    358                 soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, MODEf, TIME_MODE_OUTPUT);
    359                 soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
    360                 soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
    361                 HITLESS_REG(WRITE_CMIC_BS1_CONFIGr(unit, regval));
    362 
    363                 READ_CMIC_BS0_OUTPUT_TIME_0r(unit, &regval);
    364                 soc_reg_field_set(unit, CMIC_BS0_OUTPUT_TIME_0r, &regval, ACCURACYf, 0);
    365                 soc_reg_field_set(unit, CMIC_BS0_OUTPUT_TIME_0r, &regval, LOCKf, 0);
    366                 soc_reg_field_set(unit, CMIC_BS0_OUTPUT_TIME_0r, &regval, EPOCHf, 0);
    367                 WRITE_CMIC_BS0_OUTPUT_TIME_0r(unit, regval);
    368 
    369                 READ_CMIC_BS1_OUTPUT_TIME_0r(unit, &regval);
    370                 soc_reg_field_set(unit, CMIC_BS1_OUTPUT_TIME_0r, &regval, ACCURACYf, 0);
    371                 soc_reg_field_set(unit, CMIC_BS1_OUTPUT_TIME_0r, &regval, LOCKf, 0);
    372                 soc_reg_field_set(unit, CMIC_BS1_OUTPUT_TIME_0r, &regval, EPOCHf, 0);
    373                 WRITE_CMIC_BS1_OUTPUT_TIME_0r(unit, regval);
    374 
    375                 /* Reset Clock Control */
    376                 READ_CMIC_BS0_CLK_CTRLr(unit, &regval);
    377                 soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, ENABLEf, 0);
    378                 HITLESS_REG(WRITE_CMIC_BS0_CLK_CTRLr(unit, regval));
    379 
    380                 READ_CMIC_BS1_CLK_CTRLr(unit, &regval);
    381                 soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, ENABLEf, 0);
    382                 HITLESS_REG(WRITE_CMIC_BS1_CLK_CTRLr(unit, regval));
    383 
    384                 /* Reset HeartBeat */
    385                 READ_CMIC_BS0_HEARTBEAT_CTRLr(unit, &regval);
    386                 soc_reg_field_set(unit, CMIC_BS0_HEARTBEAT_CTRLr, &regval, ENABLEf, 0);
    387                 HITLESS_REG(WRITE_CMIC_BS0_HEARTBEAT_CTRLr(unit, regval));
    388 
    389                 READ_CMIC_BS1_HEARTBEAT_CTRLr(unit, &regval);
    390                 soc_reg_field_set(unit, CMIC_BS1_HEARTBEAT_CTRLr, &regval, ENABLEf, 0);
    391                 HITLESS_REG(WRITE_CMIC_BS1_HEARTBEAT_CTRLr(unit, regval));
    392             }
    393         }
    394 
    395         /* Reset Capture */
    396         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)){
    397             READ_NS_ROE_TS_INT_ENABLEr(unit, &regval);
    398             soc_reg_field_set(unit, NS_ROE_TS_INT_ENABLEr, &regval, INTENf, 0);
    399             WRITE_NS_ROE_TS_INT_ENABLEr(unit, regval);
    400 
    401             READ_NS_MISC_CLK_EVENT_CTRLr(unit, &regval);
    402             soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, TIME_CAPTURE_ENABLEf, 0);
    403             soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, BS0_TX_HB_STATUS_ENABLEf, 0);
    404             soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, BS0_RX_HB_STATUS_ENABLEf, 0);
    405             soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, BS1_TX_HB_STATUS_ENABLEf, 0);
    406             soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, BS1_RX_HB_STATUS_ENABLEf, 0);
    407             WRITE_NS_MISC_CLK_EVENT_CTRLr(unit, regval);
    408 
    409             READ_NS_MISC_CLK_EVENT_CTRLr(unit, &regval);
    410             soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, ENABLEf, TIME_CAPTURE_MODE_DISABLE);
    411             WRITE_NS_MISC_CLK_EVENT_CTRLr(unit, regval);
    412         } else
    413 #ifdef BCM_TRIDENT3_SUPPORT
    414          if (soc_feature(unit, soc_feature_timesync_block_iproc)) {
    415             soc_iproc_getreg(unit, soc_reg_addr(unit,
    416                 CMIC_TIMESYNC_INTERRUPT_ENABLEr, REG_PORT_ANY, 0), &regval);
    417             soc_reg_field_set(unit, CMIC_TIMESYNC_INTERRUPT_ENABLEr, &regval,
    418                               INT_ENABLEf, 0);
    419             soc_iproc_setreg(unit, soc_reg_addr(unit,
    420                 CMIC_TIMESYNC_INTERRUPT_ENABLEr, REG_PORT_ANY, 0), regval);
    421 
    422             soc_iproc_getreg(unit, soc_reg_addr(unit,
    423                 CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, REG_PORT_ANY, 0), &regval);
    424             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr,
    425                               &regval, TIME_CAPTURE_ENABLEf, 0);
    426             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr,
    427                               &regval, BSYNC0_TX_HB_STATUS_ENABLEf, 0);
    428             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr,
    429                               &regval, BSYNC0_RX_HB_STATUS_ENABLEf, 0);
    430             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr,
    431                               &regval, BSYNC1_TX_HB_STATUS_ENABLEf, 0);
    432             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr,
    433                               &regval, BSYNC1_RX_HB_STATUS_ENABLEf, 0);
    434             soc_iproc_setreg(unit, soc_reg_addr(unit,
    435                 CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, REG_PORT_ANY, 0), regval);
    436 
    437             soc_iproc_getreg(unit, soc_reg_addr(unit,
    438                 CMIC_TIMESYNC_TIME_CAPTURE_MODEr, REG_PORT_ANY, 0), &regval);
    439             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &regval,
    440                               TIME_CAPTURE_MODEf, TIME_CAPTURE_MODE_DISABLE);
    441             soc_iproc_setreg(unit, soc_reg_addr(unit,
    442                 CMIC_TIMESYNC_TIME_CAPTURE_MODEr, REG_PORT_ANY, 0), regval);
    443 
    444         } else
    445 #endif
    446         {
    447             READ_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, &regval);
    448             soc_reg_field_set(unit, CMIC_TIMESYNC_INTERRUPT_ENABLEr, &regval, INT_ENABLEf, 0);
    449             WRITE_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, regval);
    450 
    451             READ_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, &regval);
    452             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, TIME_CAPTURE_ENABLEf, 0);
    453             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, BSYNC0_TX_HB_STATUS_ENABLEf, 0);
    454             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, BSYNC0_RX_HB_STATUS_ENABLEf, 0);
    455             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, BSYNC1_TX_HB_STATUS_ENABLEf, 0);
    456             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, BSYNC1_RX_HB_STATUS_ENABLEf, 0);
    457             WRITE_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, regval);
    458 
    459             READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &regval);
    460             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &regval, TIME_CAPTURE_MODEf, TIME_CAPTURE_MODE_DISABLE);
    461             WRITE_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, regval);
    462         }
    463 
    464     } else
    465 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
    466 
    467     /*****************************************************************************/
    468     /*        Non-KATANA2, HELIX4, HURRICANE2, GREYHOUND HW configuration        */
    469     /*****************************************************************************/
    470     {
    471         if (SOC_REG_IS_VALID(unit, CMIC_BS_DRIFT_RATEr)) {
    472             /* Reset Drift Rate  */
    473             READ_CMIC_BS_DRIFT_RATEr(unit, &regval);
    474             soc_reg_field_set(unit, CMIC_BS_DRIFT_RATEr, &regval, SIGNf, 0);
    475             soc_reg_field_set(unit, CMIC_BS_DRIFT_RATEr, &regval, FRAC_NSf, 0);
    476             WRITE_CMIC_BS_DRIFT_RATEr(unit, regval);
    477         }
    478 
    479         if (SOC_REG_IS_VALID(unit, CMIC_BS_OFFSET_ADJUST_0r)) {
    480             /* Reset Offset Adjust */
    481             READ_CMIC_BS_OFFSET_ADJUST_0r(unit, &regval);
    482             soc_reg_field_set(unit, CMIC_BS_OFFSET_ADJUST_0r, &regval, SECONDf, 0);
    483             WRITE_CMIC_BS_OFFSET_ADJUST_0r(unit, regval);
    484             READ_CMIC_BS_OFFSET_ADJUST_1r(unit, &regval);
    485             soc_reg_field_set(unit, CMIC_BS_OFFSET_ADJUST_1r, &regval, SIGN_BITf, 0);
    486             soc_reg_field_set(unit, CMIC_BS_OFFSET_ADJUST_1r, &regval, NSf, 0);
    487             WRITE_CMIC_BS_OFFSET_ADJUST_1r(unit, regval);
    488         }
    489 
    490 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
    491         if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) {
    492             READ_CMIC_BS_CONFIGr(unit, &regval);
    493             /* Configure Broadsync in output mode */
    494             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, MODEf, TIME_MODE_OUTPUT);
    495             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
    496             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
    497             WRITE_CMIC_BS_CONFIGr(unit, regval);
    498 
    499             READ_CMIC_BS_OUTPUT_TIME_0r(unit, &regval);
    500             soc_reg_field_set(unit, CMIC_BS_OUTPUT_TIME_0r, &regval, ACCURACYf, 0);
    501             soc_reg_field_set(unit, CMIC_BS_OUTPUT_TIME_0r, &regval, LOCKf, 0);
    502             soc_reg_field_set(unit, CMIC_BS_OUTPUT_TIME_0r, &regval, EPOCHf, 0);
    503             WRITE_CMIC_BS_OUTPUT_TIME_0r(unit, regval);
    504         } else
    505 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
    506         {
    507             READ_CMIC_BS_CONFIGr(unit, &regval);
    508             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, ENABLEf, 0);
    509             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, MODEf, TIME_MODE_OUTPUT);
    510             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, TIME_CODE_ENABLEf, 0);
    511             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, LOCKf, 0);
    512             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, ACCURACYf, TIME_ACCURACY_UNKNOWN_HW_VAL);
    513             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, EPOCHf, 0);
    514             WRITE_CMIC_BS_CONFIGr(unit, regval);
    515         }
    516 
    517 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
    518         if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) {
    519             READ_CMIC_BS_CLK_CTRLr(unit, &regval);
    520             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, ENABLEf, 0);
    521             WRITE_CMIC_BS_CLK_CTRLr(unit, regval);
    522         } else
    523 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
    524         {
    525             READ_CMIC_BS_CLK_CTRL_0r(unit, &regval);
    526             soc_reg_field_set(unit, CMIC_BS_CLK_CTRL_0r, &regval, ENABLEf, 0);
    527             soc_reg_field_set(unit, CMIC_BS_CLK_CTRL_0r, &regval, NSf, 0);
    528             WRITE_CMIC_BS_CLK_CTRL_0r(unit, regval);
    529         }
    530 
    531         if (SOC_REG_IS_VALID(unit, CMIC_BS_CLK_CTRL_1r)) {
    532             READ_CMIC_BS_CLK_CTRL_1r(unit, &regval);
    533             soc_reg_field_set(unit, CMIC_BS_CLK_CTRL_1r, &regval, FRAC_NSf, 0);
    534             WRITE_CMIC_BS_CLK_CTRL_1r(unit, regval);
    535         }
    536 
    537         /* Reset Clock Toggle  */
    538         if (SOC_REG_IS_VALID(unit, CMIC_BS_CLK_TOGGLE_TIME_0r)) {
    539             READ_CMIC_BS_CLK_TOGGLE_TIME_0r(unit, &regval);
    540             soc_reg_field_set(unit, CMIC_BS_CLK_TOGGLE_TIME_0r, &regval, SECf, 0);
    541             WRITE_CMIC_BS_CLK_TOGGLE_TIME_0r(unit, regval);
    542         }
    543 
    544         if (SOC_REG_IS_VALID(unit, CMIC_BS_CLK_TOGGLE_TIME_1r)) {
    545             READ_CMIC_BS_CLK_TOGGLE_TIME_1r(unit, &regval);
    546             soc_reg_field_set(unit, CMIC_BS_CLK_TOGGLE_TIME_1r, &regval, NSf, 0);
    547             WRITE_CMIC_BS_CLK_TOGGLE_TIME_1r(unit, regval);
    548         }
    549 
    550         if (SOC_REG_IS_VALID(unit, CMIC_BS_CLK_TOGGLE_TIME_2r)) {
    551             READ_CMIC_BS_CLK_TOGGLE_TIME_2r(unit, &regval);
    552             soc_reg_field_set(unit, CMIC_BS_CLK_TOGGLE_TIME_2r, &regval, FRAC_NSf, 0);
    553             WRITE_CMIC_BS_CLK_TOGGLE_TIME_2r(unit, regval);
    554         }
    555 
    556         READ_CMIC_BS_HEARTBEAT_CTRLr(unit, &regval);
    557         soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 0);
    558         if (!(SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
    559               SOC_IS_TD2_TT2(unit))) {
    560             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_CTRLr, &regval, THRESHOLDf, 0);
    561         }
    562         WRITE_CMIC_BS_HEARTBEAT_CTRLr(unit, regval);
    563 
    564 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
    565         if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) {
    566             READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
    567             soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval,
    568                               INT_ENABLEf, 0);
    569             if(SOC_IS_TD2P_TT2P(unit)) {
    570                 soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval,
    571                                 TIME_CAPTURE_MODEf, TIME_CAPTURE_MODE_DISABLE);
    572             } else {
    573                 /* Configure the HW to capture time on every heartbeat */
    574                 soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval,
    575                                 TIME_CAPTURE_MODEf, TIME_CAPTURE_MODE_HEARTBEAT);
    576             }
    577             WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, regval);
    578         } else
    579 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
    580         {
    581             READ_CMIC_BS_CAPTURE_CTRLr(unit, &regval);
    582             soc_reg_field_set(unit, CMIC_BS_CAPTURE_CTRLr, &regval, INT_ENf, 0);
    583             soc_reg_field_set(unit, CMIC_BS_CAPTURE_CTRLr, &regval, TIME_CAPTURE_MODEf,
    584                               TIME_CAPTURE_MODE_DISABLE);
    585             WRITE_CMIC_BS_CAPTURE_CTRLr(unit, regval);
    586         }
    587     }
    588 
    589     return BCM_E_NONE;
    590 }
    591 
    592 /*
    593  * Function:
    594  *    _bcm_esw_time_hitless_reset
    595  * Purpose:
    596  *    Internal routine used to check if hitless reset is present in
    597  *    the hardware, and is active.
    598  *    If present, hitless reset preserves the BroadSync operation
    599  *    and registers through a chip reset.
    600  * Parameters:
    601  *    unit           - (IN) BCM device number.
    602  *    intf_id        - (IN) Time interface identifier
    603  * Returns:
    604  *    BCM_E_NONE if hitless reset is active
    605  *    BCM_E_UNAVAIL if it is not.
    606  */
    607 int _bcm_esw_time_hitless_reset(int unit, bcm_time_if_t intf_id)
    608 {
    609 #if defined(BCM_HITLESS_RESET_SUPPORT)
    610     if (SOC_IS_KATANA2(unit) || SOC_IS_SABER2(unit)) {
    611         /* if BS0 has its output enabled, this indicates that
    612          * drv.c determined that hitless reset was in effect
    613          * and so did not clear the output.
    614          */
    615         uint32 regval;
    616         READ_CMIC_BS0_CONFIGr(unit, &regval);
    617         if (soc_reg_field_get(unit, CMIC_BS0_CONFIGr,
    618                               regval, BS_CLK_OUTPUT_ENABLEf) != 0) {
    619             return BCM_E_NONE;
    620         }
    621     }
    622 #endif
    623 
    624     return BCM_E_UNAVAIL;
    625 }
    626 
    627 /*
    628  * Function:
    629  *    _bcm_esw_time_deinit
    630  * Purpose:
    631  *    Internal routine used to free time software module
    632  *    control structures.
    633  * Parameters:
    634  *    unit           - (IN) BCM device number.
    635  *    time_cfg_pptr  - (IN) Pointer to pointer to time config structure.
    636  * Returns:
    637  *    BCM_E_XXX
    638  */
    639 STATIC int
    640 _bcm_esw_time_deinit(int unit, _bcm_time_config_p *time_cfg_pptr)
    641 {
    642     int                 idx;
    643     _bcm_time_config_p  time_cfg_ptr;
    644     soc_control_t       *soc = SOC_CONTROL(unit);
    645 
    646     /* Sanity checks. */
    647     if (NULL == time_cfg_pptr) {
    648         return (BCM_E_PARAM);
    649     }
    650 
    651     time_cfg_ptr = *time_cfg_pptr;
    652     /* If time config was not allocated we are done. */
    653     if (NULL == time_cfg_ptr) {
    654         return (BCM_E_NONE);
    655     }
    656 
    657     /* Free time interface */
    658     if (NULL != time_cfg_ptr->intf_arr) {
    659         for (idx = 0; idx < NUM_TIME_INTERFACE(unit); idx++) {
    660             if (NULL !=  time_cfg_ptr->intf_arr[idx].user_cb) {
    661                 sal_free(time_cfg_ptr->intf_arr[idx].user_cb);
    662             }
    663         }
    664         sal_free(time_cfg_ptr->intf_arr);
    665     }
    666 
    667     /* Destroy protection mutex. */
    668     if (NULL != time_cfg_ptr->mutex) {
    669         sal_mutex_destroy(time_cfg_ptr->mutex);
    670     }
    671 
    672     /* If any registered function - deregister */
    673     soc->time_call_ref_count = 0;
    674     soc->soc_time_callout = NULL;
    675 
    676     /* Free module configuration structue. */
    677     sal_free(time_cfg_ptr);
    678     *time_cfg_pptr = NULL;
    679     return (BCM_E_NONE);
    680 }
    681 
    682 #ifdef BCM_WARM_BOOT_SUPPORT
    683 
    684 /*
    685  * Function:
    686  *    _bcm_time_scache_alloc
    687  * Purpose:
    688  *    Internal routine used to allocate scache memory for TIME module
    689  * Parameters:
    690  *    unit           - (IN) BCM device number.
    691  * Returns:
    692  *    BCM_E_XXX
    693  */
    694 STATIC int
    695 _bcm_time_scache_alloc(int unit)
    696 {
    697     soc_scache_handle_t scache_handle;
    698     uint8 *time_scache;
    699     int alloc_size = 0;
    700 
    701     alloc_size = ( sizeof(bcm_time_interface_t) + sizeof(int)) * NUM_TIME_INTERFACE(unit);
    702 
    703     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TIME, 0);
    704     BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, scache_handle, 1,
    705                alloc_size, &time_scache, BCM_WB_DEFAULT_VERSION, NULL));
    706     return BCM_E_NONE;
    707 }
    708 
    709 /*
    710  * Function:
    711  *    _bcm_time_scache_sync
    712  * Purpose:
    713  *    Routine to sync the time module to scache
    714  * Parameters:
    715  *    unit           - (IN) BCM device number.
    716  * Returns:
    717  *    BCM_E_XXX
    718  */
    719 int
    720 _bcm_time_scache_sync(int unit)
    721 {
    722     int         rv = BCM_E_NONE;
    723     soc_scache_handle_t scache_handle;
    724     uint8 *time_scache;
    725     int alloc_size = 0;
    726     int idx;
    727 
    728     alloc_size = ( sizeof(bcm_time_interface_t) + sizeof(int)) * NUM_TIME_INTERFACE(unit);
    729 
    730     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TIME, 0);
    731     rv = _bcm_esw_scache_ptr_get(unit,
    732                     scache_handle,
    733                     0,
    734                     alloc_size,
    735                     &time_scache,
    736                     BCM_WB_DEFAULT_VERSION,
    737                     NULL
    738                     );
    739 
    740     if (!BCM_FAILURE(rv)) {
    741         for (idx = 0; idx < NUM_TIME_INTERFACE(unit); idx++) {
    742             sal_memcpy(time_scache, (TIME_INTERFACE(unit, idx)),
    743                     sizeof(bcm_time_interface_t));
    744             time_scache += sizeof(bcm_time_interface_t);
    745             sal_memcpy(time_scache, &TIME_INTERFACE_CONFIG_REF_COUNT(unit, idx),
    746                     sizeof(int));
    747             time_scache += sizeof(int);
    748         }
    749     }
    750 
    751     return rv;
    752 }
    753 
    754 /*
    755  * Function:
    756  *    _bcm_esw_time_reinit
    757  * Purpose:
    758  *    Internal routine used to reinitialize time module based on HW settings
    759  *    during Warm boot
    760  * Parameters:
    761  *    unit           - (IN) BCM device number.
    762  *    intf_id        - (IN) Time interface identifier
    763  * Returns:
    764  *    BCM_E_XXX
    765  */
    766 STATIC int
    767 _bcm_esw_time_reinit(int unit, bcm_time_if_t intf_id)
    768 {
    769     soc_scache_handle_t scache_handle;
    770     uint16      recovered_ver = 0;
    771     uint8       *time_scache;
    772     int         rv = BCM_E_NONE;
    773 
    774     if(SOC_WARM_BOOT(unit)) {
    775         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TIME, 0);
    776         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 0, 0,
    777                                     &time_scache, BCM_WB_DEFAULT_VERSION,
    778                                     &recovered_ver);
    779         if (!BCM_FAILURE(rv)) {
    780             time_scache += sizeof(bcm_time_interface_t) * intf_id;
    781             sal_memcpy((TIME_INTERFACE(unit, intf_id)), time_scache,
    782                     sizeof(bcm_time_interface_t));
    783             time_scache += sizeof(bcm_time_interface_t);
    784             time_scache += sizeof(int) * intf_id;
    785             sal_memcpy(&(TIME_INTERFACE_CONFIG_REF_COUNT(unit, intf_id)), time_scache,
    786                     sizeof(int));
    787             time_scache += sizeof(int);
    788 
    789 #if defined(BCM_TIME_MANAGED_BROADSYNC)
    790             if ((TIME_INTERFACE(unit, intf_id))->flags & BCM_TIME_SYNC_STAMPER) {
    791                 /* Broadsync was initialised. Hence reattach */
    792                 (void)_bcm_mbox_comm_init(unit, MOS_MSG_MBOX_APPL_BS);
    793             }
    794 #endif
    795         }
    796     }
    797 
    798     if (!soc_feature(unit, soc_feature_time_v3_no_bs)) {
    799         int hb_enable;
    800 
    801         /* Read the status of heartbeat interrupt */
    802         BCM_IF_ERROR_RETURN(
    803             bcm_esw_time_heartbeat_enable_get(unit, intf_id, &hb_enable));
    804 
    805         /* If heartbeat was enabled, restore handling functionality */
    806         if (hb_enable) {
    807             BCM_IF_ERROR_RETURN(
    808                 bcm_esw_time_heartbeat_enable_set(unit, intf_id, hb_enable));
    809         }
    810     }
    811 
    812     return (BCM_E_NONE);
    813 }
    814 #endif /* BCM_WARM_BOOT_SUPPORT */
    815 
    816 /*
    817  * Function:
    818  *    _bcm_esw_time_interface_id_validate
    819  * Purpose:
    820  *    Internal routine used to validate interface identifier
    821  * Parameters:
    822  *    unit           - (IN) BCM device number.
    823  *    id             - (IN) Interface id to validate
    824  * Returns:
    825  *    BCM_E_XXX
    826  */
    827 STATIC int
    828 _bcm_esw_time_interface_id_validate(int unit, bcm_time_if_t id)
    829 {
    830     if (0 == TIME_INIT(unit)) {
    831         return (BCM_E_INIT);
    832     }
    833     if (id < 0 || id > TIME_INTERFACE_ID_MAX(unit)) {
    834         return (BCM_E_PARAM);
    835     }
    836     if (NULL == TIME_INTERFACE(unit, id)) {
    837         return (BCM_E_NOT_FOUND);
    838     }
    839 
    840     return (BCM_E_NONE);
    841 }
    842 
    843 
    844 /*
    845  * Function:
    846  *    _bcm_esw_time_interface_input_validate
    847  * Purpose:
    848  *    Internal routine used to validate interface input
    849  * Parameters:
    850  *    unit           - (IN) BCM device number.
    851  *    intf           - (IN) Interface to validate
    852  * Returns:
    853  *    BCM_E_XXX
    854  */
    855 STATIC int
    856 _bcm_esw_time_interface_input_validate(int unit, bcm_time_interface_t *intf)
    857 {
    858     /* Sanity checks. */
    859     if (NULL == intf) {
    860         return (BCM_E_PARAM);
    861     }
    862     if (intf->flags & BCM_TIME_WITH_ID) {
    863         if (intf->id < 0 || intf->id > TIME_INTERFACE_ID_MAX(unit) ) {
    864             return (BCM_E_PARAM);
    865         }
    866     }
    867 
    868 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
    869     if (soc_feature(unit, soc_feature_time_v3_no_bs) && 
    870         (intf->flags & BCM_TIME_SYNC_STAMPER)) {
    871         return BCM_E_UNAVAIL;
    872     }
    873 #endif
    874  
    875 #if defined(BCM_TIME_MANAGED_BROADSYNC)
    876     if (intf->flags & BCM_TIME_SYNC_STAMPER) {
    877         if (intf->heartbeat_hz <= 0 || intf->bitclock_hz <= 0) {
    878             return (BCM_E_PARAM);
    879         }
    880     }
    881 #endif
    882 
    883 #if defined(BCM_TIME_V3_SUPPORT)
    884     if (soc_feature(unit, soc_feature_time_v3) &&
    885         !SOC_IS_HURRICANE2(unit) && !SOC_IS_GREYHOUND(unit) &&
    886         !SOC_IS_TOMAHAWKX(unit) && !SOC_IS_HURRICANE3(unit) &&
    887         !SOC_IS_GREYHOUND2(unit) && !SOC_IS_TRIDENT3(unit) &&
    888         !(intf->flags & BCM_TIME_SYNC_STAMPER)) {
    889         /*
    890          * Drift/Offset is not supported by 3rd generation time architecture
    891          * NB: Hurricane2 (56150) enables v3 time feature. BroadSync FW APIs
    892          *     support time offset functionality. !SOC_IS_HURRICANE2() logic
    893          *     added to conditional to enable phase offset on HR2 similar to
    894          *     other platforms.
    895          */
    896         if (intf->flags & BCM_TIME_DRIFT || intf->flags & BCM_TIME_OFFSET) {
    897             return BCM_E_UNAVAIL;
    898         }
    899     }
    900 #endif /* defined(BCM_TIME_V3_SUPPORT) */
    901 
    902     if (intf->flags & BCM_TIME_DRIFT) {
    903         if (intf->drift.nanoseconds > TIME_DRIFT_MAX) {
    904             return BCM_E_PARAM;
    905         }
    906     }
    907 
    908     if (intf->flags & BCM_TIME_OFFSET) {
    909         if (intf->offset.nanoseconds > TIME_NANOSEC_MAX) {
    910             return BCM_E_PARAM;
    911 }
    912     }
    913 
    914     return (BCM_E_NONE);
    915 }
    916 
    917 
    918 /*
    919  * Function:
    920  *    _bcm_esw_time_interface_allocate_id
    921  * Purpose:
    922  *    Internal routine used to allocate time interface id
    923  * Parameters:
    924  *    unit           - (IN) BCM device number.
    925  *    id             - (OUT) Interface id to be allocated
    926  * Returns:
    927  *    BCM_E_XXX
    928  */
    929 STATIC int
    930 _bcm_esw_time_interface_allocate_id(int unit, bcm_time_if_t *id)
    931 {
    932     int                              idx;  /* Time interfaces iteration index.*/
    933     _bcm_time_interface_config_p     intf; /* Time interface description.     */
    934 
    935     /* Input parameters check. */
    936     if (NULL == id) {
    937         return (BCM_E_PARAM);
    938     }
    939 
    940     /* Find & allocate time interface. */
    941     for (idx = 0; idx < TIME_CONFIG(unit)->intf_count; idx++) {
    942         intf = TIME_CONFIG(unit)->intf_arr + idx;
    943         if (intf->ref_count) {  /* In use interface */
    944             continue;
    945         }
    946         intf->ref_count++;  /* If founf mark interface as in use */
    947         *id = intf->time_interface.id; /* Assign ID */
    948         return (BCM_E_NONE);
    949     }
    950 
    951     /* No available interfaces */
    952     return (BCM_E_FULL);
    953 }
    954 
    955 
    956 
    957 /*
    958  * Function:
    959  *    _bcm_esw_time_interface_heartbeat_install
    960  * Purpose:
    961  *    Internal routine used to install interface heartbeat rate into a HW
    962  * Parameters:
    963  *    unit           - (IN) BCM device number.
    964  *    id             - (IN) Interface id to be installed into a HW
    965  * Returns:
    966  *    BCM_E_XXX
    967  */
    968 STATIC int
    969 _bcm_esw_time_interface_heartbeat_install(int unit, bcm_time_if_t id)
    970 {
    971     uint32  regval;
    972     uint32  hb_hz;  /* Number of heartbeats in HZ */
    973     uint32  ns_hp;  /* Number of nanosec per half clock cycle*/
    974     uint32  threshold; /* Heartbeat threshold */
    975 
    976     bcm_time_interface_t    *intf;
    977 
    978     intf = TIME_INTERFACE(unit, id);
    979 
    980     hb_hz = (intf->heartbeat_hz > TIME_HEARTBEAT_HZ_MAX) ?
    981         TIME_HEARTBEAT_HZ_MAX : intf->heartbeat_hz;
    982     hb_hz = (intf->heartbeat_hz < TIME_HEARTBEAT_HZ_MIN) ?
    983         TIME_HEARTBEAT_HZ_MIN : hb_hz;
    984 
    985     threshold = intf->bitclock_hz / hb_hz;
    986 
    987     if (threshold < 100) {
    988         /* BitClock must have a frequency at least 100 times that of heartbeat. */
    989         return BCM_E_PARAM;
    990     }
    991 
    992     /* Calculate nanoseconds per half period of cycle */
    993     ns_hp = TIME_HEARTBEAT_NS_HZ / intf->bitclock_hz / 2;
    994 
    995     /* program the half period of broadsync clock */
    996 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
    997     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
    998         uint32  interval = 0;
    999         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   1000             READ_NS_BS0_BS_CLK_CTRLr(unit, &regval);
   1001             soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   1002             WRITE_NS_BS0_BS_CLK_CTRLr(unit, regval);
   1003 
   1004             READ_NS_BS1_BS_CLK_CTRLr(unit, &regval);
   1005             soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   1006             WRITE_NS_BS1_BS_CLK_CTRLr(unit, regval);
   1007 
   1008             /* enable Heartbeat generation */
   1009             READ_NS_BS0_BS_HEARTBEAT_CTRLr(unit, &regval);
   1010             soc_reg_field_set(unit, NS_BS0_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   1011             WRITE_NS_BS0_BS_HEARTBEAT_CTRLr(unit, regval);
   1012 
   1013             /* Install heartbeat up and down interval */
   1014             READ_NS_BS0_BS_HEARTBEAT_UP_DURATIONr(unit, &regval);
   1015             soc_reg_field_set(unit, NS_BS0_BS_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, threshold);
   1016             WRITE_NS_BS0_BS_HEARTBEAT_UP_DURATIONr(unit, regval);
   1017 
   1018             READ_NS_BS0_BS_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   1019             soc_reg_field_set(unit, NS_BS0_BS_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, threshold);
   1020             WRITE_NS_BS0_BS_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   1021 
   1022             READ_NS_BS1_BS_HEARTBEAT_UP_DURATIONr(unit, &regval);
   1023             soc_reg_field_set(unit, NS_BS1_BS_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, threshold);
   1024             WRITE_NS_BS1_BS_HEARTBEAT_UP_DURATIONr(unit, regval);
   1025 
   1026             READ_NS_BS1_BS_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   1027             soc_reg_field_set(unit, NS_BS1_BS_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, threshold);
   1028             WRITE_NS_BS1_BS_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   1029 
   1030             /* Enable heartbeat output */
   1031             READ_NS_BS0_BS_HEARTBEAT_CTRLr(unit, &regval);
   1032             soc_reg_field_set(unit, NS_BS0_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   1033             WRITE_NS_BS0_BS_HEARTBEAT_CTRLr(unit, regval);
   1034 
   1035             READ_NS_BS1_BS_HEARTBEAT_CTRLr(unit, &regval);
   1036             soc_reg_field_set(unit, NS_BS1_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   1037             WRITE_NS_BS1_BS_HEARTBEAT_CTRLr(unit, regval);
   1038 
   1039             /*
   1040              * KT-1381 :
   1041              *  TS_GPIO_LOW = (UP_EVENT_INTERVAL x 4) + 1 TS_REF_CLK_time_period
   1042              *  TS_GPIO_HIGH = (DOWN_EVENT_INTERVAL x 4) + 1 TS_REF_CLK_time_period
   1043              */
   1044             threshold = (threshold * 4) + SOC_TIMESYNC_PLL_CLOCK_NS(unit);
   1045 
   1046             /* Install GPIO timesync trigger interval */
   1047             /* GPIO_EVENT_1 */
   1048             READ_NS_TIMESYNC_GPIO_0_DOWN_EVENT_CTRLr(unit, &interval);
   1049             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_0_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1050             WRITE_NS_TIMESYNC_GPIO_0_DOWN_EVENT_CTRLr(unit, interval);
   1051 
   1052             READ_NS_TIMESYNC_GPIO_0_UP_EVENT_CTRLr(unit, &interval);
   1053             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_0_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1054             WRITE_NS_TIMESYNC_GPIO_0_UP_EVENT_CTRLr(unit, interval);
   1055 
   1056             /* GPIO_EVENT_2 */
   1057             READ_NS_TIMESYNC_GPIO_1_DOWN_EVENT_CTRLr(unit, &interval);
   1058             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_1_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1059             WRITE_NS_TIMESYNC_GPIO_1_DOWN_EVENT_CTRLr(unit, interval);
   1060 
   1061             READ_NS_TIMESYNC_GPIO_1_UP_EVENT_CTRLr(unit, &interval);
   1062             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_1_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1063             WRITE_NS_TIMESYNC_GPIO_1_UP_EVENT_CTRLr(unit, interval);
   1064 
   1065             /* GPIO_EVENT_3 */
   1066             READ_NS_TIMESYNC_GPIO_2_DOWN_EVENT_CTRLr(unit, &interval);
   1067             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_2_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1068             WRITE_NS_TIMESYNC_GPIO_2_DOWN_EVENT_CTRLr(unit, interval);
   1069 
   1070             READ_NS_TIMESYNC_GPIO_2_UP_EVENT_CTRLr(unit, &interval);
   1071             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_2_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1072             WRITE_NS_TIMESYNC_GPIO_2_UP_EVENT_CTRLr(unit, interval);
   1073 
   1074             /* GPIO_EVENT_4 */
   1075             READ_NS_TIMESYNC_GPIO_3_DOWN_EVENT_CTRLr(unit, &interval);
   1076             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_3_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1077             WRITE_NS_TIMESYNC_GPIO_3_DOWN_EVENT_CTRLr(unit, interval);
   1078 
   1079             READ_NS_TIMESYNC_GPIO_3_UP_EVENT_CTRLr(unit, &interval);
   1080             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_3_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1081             WRITE_NS_TIMESYNC_GPIO_3_UP_EVENT_CTRLr(unit, interval);
   1082 
   1083             /* GPIO_EVENT_5 */
   1084             READ_NS_TIMESYNC_GPIO_4_DOWN_EVENT_CTRLr(unit, &interval);
   1085             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_4_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1086             WRITE_NS_TIMESYNC_GPIO_4_DOWN_EVENT_CTRLr(unit, interval);
   1087 
   1088             READ_NS_TIMESYNC_GPIO_4_UP_EVENT_CTRLr(unit, &interval);
   1089             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_4_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1090             WRITE_NS_TIMESYNC_GPIO_4_UP_EVENT_CTRLr(unit, interval);
   1091 
   1092             /* GPIO_EVENT_6 */
   1093             READ_NS_TIMESYNC_GPIO_5_DOWN_EVENT_CTRLr(unit, &interval);
   1094             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_5_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1095             WRITE_NS_TIMESYNC_GPIO_5_DOWN_EVENT_CTRLr(unit, interval);
   1096 
   1097             READ_NS_TIMESYNC_GPIO_5_UP_EVENT_CTRLr(unit, &interval);
   1098             soc_reg_field_set(unit, NS_TIMESYNC_GPIO_5_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1099             WRITE_NS_TIMESYNC_GPIO_5_UP_EVENT_CTRLr(unit, interval);
   1100 
   1101         } else {
   1102             READ_CMIC_BS0_CLK_CTRLr(unit, &regval);
   1103             soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, ENABLEf, 1);
   1104             WRITE_CMIC_BS0_CLK_CTRLr(unit, regval);
   1105 
   1106             READ_CMIC_BS1_CLK_CTRLr(unit, &regval);
   1107             soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, ENABLEf, 1);
   1108             WRITE_CMIC_BS1_CLK_CTRLr(unit, regval);
   1109 
   1110             /* enable Heartbeat generation */
   1111             READ_CMIC_BS0_HEARTBEAT_CTRLr(unit, &regval);
   1112             soc_reg_field_set(unit, CMIC_BS0_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   1113             WRITE_CMIC_BS0_HEARTBEAT_CTRLr(unit, regval);
   1114 
   1115             /* Install heartbeat up and down interval */
   1116             READ_CMIC_BS0_HEARTBEAT_UP_DURATIONr(unit, &regval);
   1117             soc_reg_field_set(unit, CMIC_BS0_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, threshold);
   1118             WRITE_CMIC_BS0_HEARTBEAT_UP_DURATIONr(unit, regval);
   1119 
   1120             READ_CMIC_BS0_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   1121             soc_reg_field_set(unit, CMIC_BS0_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, threshold);
   1122             WRITE_CMIC_BS0_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   1123 
   1124             READ_CMIC_BS1_HEARTBEAT_UP_DURATIONr(unit, &regval);
   1125             soc_reg_field_set(unit, CMIC_BS1_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, threshold);
   1126             WRITE_CMIC_BS1_HEARTBEAT_UP_DURATIONr(unit, regval);
   1127 
   1128             READ_CMIC_BS1_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   1129             soc_reg_field_set(unit, CMIC_BS1_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, threshold);
   1130             WRITE_CMIC_BS1_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   1131 
   1132             /* Enable heartbeat output */
   1133             READ_CMIC_BS0_HEARTBEAT_CTRLr(unit, &regval);
   1134             soc_reg_field_set(unit, CMIC_BS0_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   1135             WRITE_CMIC_BS0_HEARTBEAT_CTRLr(unit, regval);
   1136 
   1137             READ_CMIC_BS1_HEARTBEAT_CTRLr(unit, &regval);
   1138             soc_reg_field_set(unit, CMIC_BS1_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   1139             WRITE_CMIC_BS1_HEARTBEAT_CTRLr(unit, regval);
   1140 
   1141             /*
   1142              * KT-1381 :
   1143              *  TS_GPIO_LOW = (UP_EVENT_INTERVAL x 4) + 1 TS_REF_CLK_time_period
   1144              *  TS_GPIO_HIGH = (DOWN_EVENT_INTERVAL x 4) + 1 TS_REF_CLK_time_period
   1145              */
   1146             threshold = (threshold * 4) + SOC_TIMESYNC_PLL_CLOCK_NS(unit);
   1147 
   1148             /* Install GPIO timesync trigger interval */
   1149             /* GPIO_EVENT_1 */
   1150             READ_CMIC_TIMESYNC_GPIO_0_DOWN_EVENT_CTRLr(unit, &interval);
   1151             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_0_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1152             WRITE_CMIC_TIMESYNC_GPIO_0_DOWN_EVENT_CTRLr(unit, interval);
   1153 
   1154             READ_CMIC_TIMESYNC_GPIO_0_UP_EVENT_CTRLr(unit, &interval);
   1155             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_0_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1156             WRITE_CMIC_TIMESYNC_GPIO_0_UP_EVENT_CTRLr(unit, interval);
   1157 
   1158             /* GPIO_EVENT_2 */
   1159             READ_CMIC_TIMESYNC_GPIO_1_DOWN_EVENT_CTRLr(unit, &interval);
   1160             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_1_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1161             WRITE_CMIC_TIMESYNC_GPIO_1_DOWN_EVENT_CTRLr(unit, interval);
   1162 
   1163             READ_CMIC_TIMESYNC_GPIO_1_UP_EVENT_CTRLr(unit, &interval);
   1164             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_1_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1165             WRITE_CMIC_TIMESYNC_GPIO_1_UP_EVENT_CTRLr(unit, interval);
   1166 
   1167             /* GPIO_EVENT_3 */
   1168             READ_CMIC_TIMESYNC_GPIO_2_DOWN_EVENT_CTRLr(unit, &interval);
   1169             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_2_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1170             WRITE_CMIC_TIMESYNC_GPIO_2_DOWN_EVENT_CTRLr(unit, interval);
   1171 
   1172             READ_CMIC_TIMESYNC_GPIO_2_UP_EVENT_CTRLr(unit, &interval);
   1173             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_2_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1174             WRITE_CMIC_TIMESYNC_GPIO_2_UP_EVENT_CTRLr(unit, interval);
   1175 
   1176             /* GPIO_EVENT_4 */
   1177             READ_CMIC_TIMESYNC_GPIO_3_DOWN_EVENT_CTRLr(unit, &interval);
   1178             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_3_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1179             WRITE_CMIC_TIMESYNC_GPIO_3_DOWN_EVENT_CTRLr(unit, interval);
   1180 
   1181             READ_CMIC_TIMESYNC_GPIO_3_UP_EVENT_CTRLr(unit, &interval);
   1182             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_3_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1183             WRITE_CMIC_TIMESYNC_GPIO_3_UP_EVENT_CTRLr(unit, interval);
   1184 
   1185             /* GPIO_EVENT_5 */
   1186             READ_CMIC_TIMESYNC_GPIO_4_DOWN_EVENT_CTRLr(unit, &interval);
   1187             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_4_DOWN_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1188             WRITE_CMIC_TIMESYNC_GPIO_4_DOWN_EVENT_CTRLr(unit, interval);
   1189 
   1190             READ_CMIC_TIMESYNC_GPIO_4_UP_EVENT_CTRLr(unit, &interval);
   1191             soc_reg_field_set(unit, CMIC_TIMESYNC_GPIO_4_UP_EVENT_CTRLr, &interval, INTERVAL_LENGTHf, threshold);
   1192             WRITE_CMIC_TIMESYNC_GPIO_4_UP_EVENT_CTRLr(unit, interval);
   1193         }
   1194 
   1195     } else
   1196 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   1197     {
   1198 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   1199         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   1200             SOC_IS_TD2_TT2(unit)) {
   1201 
   1202             READ_CMIC_BS_CLK_CTRLr(unit, &regval);
   1203             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   1204             WRITE_CMIC_BS_CLK_CTRLr(unit, regval);
   1205 
   1206             READ_CMIC_BS_HEARTBEAT_CTRLr(unit, &regval);
   1207             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   1208             WRITE_CMIC_BS_HEARTBEAT_CTRLr(unit, regval);
   1209         } else
   1210 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   1211         {
   1212             READ_CMIC_BS_CLK_CTRL_0r(unit, &regval);
   1213             soc_reg_field_set(unit, CMIC_BS_CLK_CTRL_0r, &regval, ENABLEf, 1);
   1214             soc_reg_field_set(unit, CMIC_BS_CLK_CTRL_0r, &regval, NSf, ns_hp);
   1215             WRITE_CMIC_BS_CLK_CTRL_0r(unit, regval);
   1216 
   1217             READ_CMIC_BS_HEARTBEAT_CTRLr(unit, &regval);
   1218             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   1219             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_CTRLr, &regval,
   1220                               THRESHOLDf, threshold);
   1221             WRITE_CMIC_BS_HEARTBEAT_CTRLr(unit, regval);
   1222         }
   1223 
   1224 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   1225         /* Install heartbeat and external trigger clock interval */
   1226         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   1227             SOC_IS_TD2_TT2(unit)) {
   1228             uint32  interval = 0;
   1229 
   1230             /* Install heartbeat up and down interval */
   1231             READ_CMIC_BS_HEARTBEAT_UP_DURATIONr(unit, &interval);
   1232             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_UP_DURATIONr,
   1233                               &interval, UP_DURATIONf, threshold);
   1234             WRITE_CMIC_BS_HEARTBEAT_UP_DURATIONr(unit, interval);
   1235 
   1236             READ_CMIC_BS_HEARTBEAT_DOWN_DURATIONr(unit, &interval);
   1237             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_DOWN_DURATIONr,
   1238                               &interval, DOWN_DURATIONf, threshold);
   1239             WRITE_CMIC_BS_HEARTBEAT_DOWN_DURATIONr(unit, interval);
   1240 
   1241             /* Install divisor for LCPLL trigger interval */
   1242             READ_CMIC_TS_LCPLL_CLK_COUNT_CTRLr(unit, &interval);
   1243             soc_reg_field_set(unit,
   1244                               CMIC_TS_LCPLL_CLK_COUNT_CTRLr,
   1245                               &interval, DIVISORf, threshold);
   1246             WRITE_CMIC_TS_LCPLL_CLK_COUNT_CTRLr(unit, interval);
   1247 
   1248             /* Install divisor for Primary L1 trigger interval */
   1249             READ_CMIC_TS_L1_CLK_RECOVERED_CLK_COUNT_CTRLr(unit, &interval);
   1250             soc_reg_field_set(unit,
   1251                               CMIC_TS_L1_CLK_RECOVERED_CLK_COUNT_CTRLr,
   1252                               &interval, DIVISORf, threshold);
   1253             WRITE_CMIC_TS_L1_CLK_RECOVERED_CLK_COUNT_CTRLr(unit, interval);
   1254 
   1255             /* Install divisor for backup L1 trigger interval */
   1256             READ_CMIC_TS_L1_CLK_RECOVERED_CLK_BKUP_COUNT_CTRLr(unit, &interval);
   1257             soc_reg_field_set(unit,
   1258                               CMIC_TS_L1_CLK_RECOVERED_CLK_BKUP_COUNT_CTRLr,
   1259                               &interval, DIVISORf, threshold);
   1260             WRITE_CMIC_TS_L1_CLK_RECOVERED_CLK_BKUP_COUNT_CTRLr(unit, interval);
   1261 
   1262             /*
   1263              * KT-1381 :
   1264              *  TS_GPIO_LOW =
   1265                    (UP_EVENT_INTERVAL x 4) + 1 TS_REF_CLK_time_period
   1266              *  TS_GPIO_HIGH =
   1267                    (DOWN_EVENT_INTERVAL x 4) + 1 TS_REF_CLK_time_period
   1268              */
   1269             threshold = (threshold * 4) + SOC_TIMESYNC_PLL_CLOCK_NS(unit);
   1270 
   1271             /* Install GPIO timesync trigger interval */
   1272             /* GPIO_EVENT_1 */
   1273             READ_CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr(unit, &interval);
   1274             soc_reg_field_set(unit, CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr, &interval,
   1275                               INTERVAL_LENGTHf, threshold);
   1276             WRITE_CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr(unit, interval);
   1277             READ_CMIC_TS_GPIO_1_UP_EVENT_CTRLr(unit, &interval);
   1278             soc_reg_field_set(unit, CMIC_TS_GPIO_1_UP_EVENT_CTRLr, &interval,
   1279                               INTERVAL_LENGTHf, threshold);
   1280             WRITE_CMIC_TS_GPIO_1_UP_EVENT_CTRLr(unit, interval);
   1281 
   1282             /* GPIO_EVENT_2 */
   1283             READ_CMIC_TS_GPIO_2_DOWN_EVENT_CTRLr(unit, &interval);
   1284             soc_reg_field_set(unit, CMIC_TS_GPIO_2_DOWN_EVENT_CTRLr, &interval,
   1285                               INTERVAL_LENGTHf, threshold);
   1286             WRITE_CMIC_TS_GPIO_2_DOWN_EVENT_CTRLr(unit, interval);
   1287             READ_CMIC_TS_GPIO_2_UP_EVENT_CTRLr(unit, &interval);
   1288             soc_reg_field_set(unit, CMIC_TS_GPIO_2_UP_EVENT_CTRLr, &interval,
   1289                               INTERVAL_LENGTHf, threshold);
   1290             WRITE_CMIC_TS_GPIO_2_UP_EVENT_CTRLr(unit, interval);
   1291 
   1292             /* GPIO_EVENT_3 */
   1293             READ_CMIC_TS_GPIO_3_DOWN_EVENT_CTRLr(unit, &interval);
   1294             soc_reg_field_set(unit, CMIC_TS_GPIO_3_DOWN_EVENT_CTRLr, &interval,
   1295                               INTERVAL_LENGTHf, threshold);
   1296             WRITE_CMIC_TS_GPIO_3_DOWN_EVENT_CTRLr(unit, interval);
   1297             READ_CMIC_TS_GPIO_3_UP_EVENT_CTRLr(unit, &interval);
   1298             soc_reg_field_set(unit, CMIC_TS_GPIO_3_UP_EVENT_CTRLr, &interval,
   1299                               INTERVAL_LENGTHf, threshold);
   1300             WRITE_CMIC_TS_GPIO_3_UP_EVENT_CTRLr(unit, interval);
   1301 
   1302             /* GPIO_EVENT_4 */
   1303             READ_CMIC_TS_GPIO_4_DOWN_EVENT_CTRLr(unit, &interval);
   1304             soc_reg_field_set(unit, CMIC_TS_GPIO_4_DOWN_EVENT_CTRLr, &interval,
   1305                               INTERVAL_LENGTHf, threshold);
   1306             WRITE_CMIC_TS_GPIO_4_DOWN_EVENT_CTRLr(unit, interval);
   1307             READ_CMIC_TS_GPIO_4_UP_EVENT_CTRLr(unit, &interval);
   1308             soc_reg_field_set(unit, CMIC_TS_GPIO_4_UP_EVENT_CTRLr, &interval,
   1309                               INTERVAL_LENGTHf, threshold);
   1310             WRITE_CMIC_TS_GPIO_4_UP_EVENT_CTRLr(unit, interval);
   1311 
   1312             /* GPIO_EVENT_5 */
   1313             READ_CMIC_TS_GPIO_5_DOWN_EVENT_CTRLr(unit, &interval);
   1314             soc_reg_field_set(unit,
   1315                               CMIC_TS_GPIO_5_DOWN_EVENT_CTRLr,
   1316                               &interval, INTERVAL_LENGTHf, threshold);
   1317             WRITE_CMIC_TS_GPIO_5_DOWN_EVENT_CTRLr(unit, interval);
   1318             READ_CMIC_TS_GPIO_5_UP_EVENT_CTRLr(unit, &interval);
   1319             soc_reg_field_set(unit,
   1320                               CMIC_TS_GPIO_5_UP_EVENT_CTRLr,
   1321                               &interval, INTERVAL_LENGTHf, threshold);
   1322             WRITE_CMIC_TS_GPIO_5_UP_EVENT_CTRLr(unit, interval);
   1323         }
   1324 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   1325     }
   1326 
   1327     return (BCM_E_NONE);
   1328 }
   1329 
   1330 
   1331 /*
   1332  * Function:
   1333  *    _bcm_esw_time_interface_accuracy_time2hw
   1334  * Purpose:
   1335  *    Internal routine used to compute HW accuracy value from interface
   1336  * Parameters:
   1337  *    unit           - (IN) BCM device number.
   1338  *    id             - (IN) Interface id
   1339  *    accuracy       - (OUT) HW value to be programmed
   1340  * Returns:
   1341  *    BCM_E_XXX
   1342  */
   1343 STATIC int
   1344 _bcm_esw_time_interface_accuracy_time2hw(int unit, bcm_time_if_t id,
   1345                                          uint32 *accuracy)
   1346 {
   1347     int                     idx;    /* accuracy itterator */
   1348     bcm_time_interface_t    *intf;
   1349 
   1350     if (NULL == accuracy) {
   1351         return BCM_E_PARAM;
   1352     }
   1353 
   1354     intf = TIME_INTERFACE(unit, id);
   1355 
   1356     /* Find the right accuracy */
   1357     for (idx = 0; idx < TIME_ACCURACY_CLK_MAX; idx++) {
   1358         if (intf->accuracy.nanoseconds <= _bcm_time_accuracy_arr[idx].nanoseconds &&
   1359              COMPILER_64_LO(intf->accuracy.seconds) <= COMPILER_64_LO(_bcm_time_accuracy_arr[idx].seconds) ) {
   1360             break;
   1361         }
   1362     }
   1363     /* if no match - return error */
   1364     if (idx == TIME_ACCURACY_CLK_MAX) {
   1365         return BCM_E_NOT_FOUND;
   1366     }
   1367 
   1368     /* Return the correct HW value */
   1369 
   1370     *accuracy = TIME_ACCURACY_SW_IDX_2_HW(idx);
   1371 
   1372     return (BCM_E_NONE);
   1373 }
   1374 
   1375 /*
   1376  * Function:
   1377  *    _bcm_esw_time_interface_drift_install
   1378  * Purpose:
   1379  *    Internal routine used to install interface drift into a HW
   1380  * Parameters:
   1381  *    unit           - (IN) BCM device number.
   1382  *    id             - (IN) Interface id to be installed into a HW
   1383  * Returns:
   1384  *    BCM_E_XXX
   1385  */
   1386 STATIC int
   1387 _bcm_esw_time_interface_drift_install(int unit, bcm_time_if_t id)
   1388 {
   1389     uint32 regval, hw_val, sign;
   1390     bcm_time_interface_t    *intf;
   1391 
   1392 #if defined(BCM_TIME_V3_SUPPORT)
   1393     /* Not supported in 3rd generation time arch */
   1394     if (soc_feature(unit, soc_feature_time_v3)) {
   1395         return BCM_E_UNAVAIL;
   1396     }
   1397 #endif /* defined(BCM_TIME_V3_SUPPORT) */
   1398 
   1399 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   1400     /* Katana does not support clock drift */
   1401     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   1402         SOC_IS_TD2_TT2(unit)) {
   1403         return BCM_E_UNAVAIL;
   1404     }
   1405 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   1406 
   1407     intf = TIME_INTERFACE(unit, id);
   1408     sign = intf->drift.isnegative;
   1409 
   1410     /* Requested drift value should not be more then 1/8 of drift denominator */
   1411     if (intf->drift.nanoseconds <= TIME_DRIFT_MAX) {
   1412         hw_val = 8 * intf->drift.nanoseconds;
   1413     } else {
   1414         return (BCM_E_PARAM);
   1415     }
   1416     READ_CMIC_BS_DRIFT_RATEr(unit, &regval);
   1417     soc_reg_field_set(unit, CMIC_BS_DRIFT_RATEr, &regval, SIGNf, sign);
   1418     soc_reg_field_set(unit, CMIC_BS_DRIFT_RATEr, &regval, FRAC_NSf, hw_val);
   1419     WRITE_CMIC_BS_DRIFT_RATEr(unit, regval);
   1420 
   1421     return (BCM_E_NONE);
   1422 }
   1423 
   1424 /*
   1425  * Function:
   1426  *    _bcm_esw_time_interface_offset_install
   1427  * Purpose:
   1428  *    Internal routine used to install interface offset into a HW
   1429  * Parameters:
   1430  *    unit           - (IN) BCM device number.
   1431  *    id             - (IN) Interface id to be installed into a HW
   1432  * Returns:
   1433  *    BCM_E_XXX
   1434  */
   1435 STATIC int
   1436 _bcm_esw_time_interface_offset_install(int unit, bcm_time_if_t id)
   1437 {
   1438     uint32 regval, sign, hw_val;
   1439     bcm_time_interface_t    *intf;
   1440 
   1441 #if defined(BCM_TIME_V3_SUPPORT)
   1442     /* Not supported in 3rd generation time arch */
   1443     if (soc_feature(unit, soc_feature_time_v3)) {
   1444         return BCM_E_UNAVAIL;
   1445     }
   1446 #endif /* defined(BCM_TIME_V3_SUPPORT) */
   1447 
   1448 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
   1449     /* Katana does not support clock offset */
   1450     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   1451         SOC_IS_TD2_TT2(unit) || SOC_IS_HELIX4(unit)) {
   1452         return BCM_E_UNAVAIL;
   1453     }
   1454 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) */
   1455 
   1456     intf = TIME_INTERFACE(unit, id);
   1457 
   1458     /* Negative value if local clock is faster and need negative adjustment */
   1459     sign = intf->offset.isnegative;
   1460     /* Write second's values into the HW */
   1461     READ_CMIC_BS_OFFSET_ADJUST_0r(unit, &regval);
   1462     hw_val = COMPILER_64_LO(intf->offset.seconds);
   1463     soc_reg_field_set(unit, CMIC_BS_OFFSET_ADJUST_0r, &regval, SECONDf, hw_val);
   1464     WRITE_CMIC_BS_OFFSET_ADJUST_0r(unit, regval);
   1465     /* Write sign and nansecond's values into the HW */
   1466     READ_CMIC_BS_OFFSET_ADJUST_1r(unit, &regval);
   1467     soc_reg_field_set(unit, CMIC_BS_OFFSET_ADJUST_1r, &regval,
   1468                       SIGN_BITf, sign);
   1469     soc_reg_field_set(unit, CMIC_BS_OFFSET_ADJUST_1r, &regval, NSf,
   1470                       intf->offset.nanoseconds);
   1471     WRITE_CMIC_BS_OFFSET_ADJUST_1r(unit, regval);
   1472 
   1473     /* If necessary install the epoch */
   1474     if (COMPILER_64_HI(intf->offset.seconds) > 0) {
   1475         READ_CMIC_BS_CONFIGr(unit, &regval);
   1476         hw_val = COMPILER_64_HI(intf->offset.seconds);
   1477         if (hw_val > TIME_EPOCH_MAX) {
   1478             hw_val = TIME_EPOCH_MAX;
   1479         }
   1480         soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, EPOCHf, hw_val);
   1481         WRITE_CMIC_BS_CONFIGr(unit, regval);
   1482     }
   1483 
   1484     return (BCM_E_NONE);
   1485 }
   1486 
   1487 #if defined(BCM_TIME_MANAGED_BROADSYNC)
   1488 /*
   1489  * Function:
   1490  *    _bcm_esw_time_interface_ref_clock_install
   1491  * Purpose:
   1492  *    Internal routine to install timesync clock divisor to
   1493  *    enable broadsync reference clock.
   1494  * Parameters:
   1495  *    unit           - (IN) BCM device number.
   1496  *    id             - (IN) Interface id to be installed into a HW
   1497  * Returns:
   1498  *    BCM_E_XXX
   1499  */
   1500 STATIC int
   1501 _bcm_esw_time_interface_ref_clock_install(int unit, bcm_time_if_t id)
   1502 {
   1503     uint32 regval, ndiv, hdiv, ref_clk;
   1504     bcm_time_interface_t    *intf;
   1505 
   1506     intf = TIME_INTERFACE(unit, id);
   1507 
   1508     /* Validate and calculate ts_clk divisor to generate reference clock */
   1509     if (intf->clk_resolution <= 0) {
   1510         return BCM_E_PARAM;
   1511     }
   1512 
   1513     /* Maximum ts_clk frequency is of 25Mhz(40ns) */
   1514     ref_clk = (intf->clk_resolution > TIME_TS_CLK_FREQUENCY_40NS) ?
   1515               TIME_TS_CLK_FREQUENCY_40NS : intf->clk_resolution;
   1516 
   1517     /* Divisor is half period for reference clock */
   1518     ndiv = TIME_TS_CLK_FREQUENCY_40NS / ref_clk;
   1519 
   1520     /* Divisor is ceiling of half period */
   1521     hdiv = (ndiv + 1)/2 ? ndiv : 1;
   1522 
   1523     /* Enable Broadsync reference clock */
   1524 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   1525     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   1526         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   1527             READ_NS_BROADSYNC_REF_CLK_GEN_CTRLr(unit, &regval);
   1528             soc_reg_field_set(unit, NS_BROADSYNC_REF_CLK_GEN_CTRLr, &regval,
   1529                               ENABLEf, 1);
   1530             soc_reg_field_set(unit, NS_BROADSYNC_REF_CLK_GEN_CTRLr, &regval,
   1531                               DIVISORf, hdiv);
   1532             WRITE_NS_BROADSYNC_REF_CLK_GEN_CTRLr(unit, regval);
   1533         } else {
   1534             READ_CMIC_BROADSYNC_REF_CLK_GEN_CTRLr(unit, &regval);
   1535             soc_reg_field_set(unit, CMIC_BROADSYNC_REF_CLK_GEN_CTRLr, &regval,
   1536                               ENABLEf, 1);
   1537             soc_reg_field_set(unit, CMIC_BROADSYNC_REF_CLK_GEN_CTRLr, &regval,
   1538                               DIVISORf, hdiv);
   1539             WRITE_CMIC_BROADSYNC_REF_CLK_GEN_CTRLr(unit, regval);
   1540         }
   1541     } else
   1542 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   1543     {
   1544         READ_CMIC_BS_REF_CLK_GEN_CTRLr(unit, &regval);
   1545         soc_reg_field_set(unit, CMIC_BS_REF_CLK_GEN_CTRLr, &regval,
   1546                           ENABLEf, 1);
   1547         soc_reg_field_set(unit, CMIC_BS_REF_CLK_GEN_CTRLr, &regval,
   1548                           DIVISORf, hdiv);
   1549         WRITE_CMIC_BS_REF_CLK_GEN_CTRLr(unit, regval);
   1550     }
   1551 
   1552     return (BCM_E_NONE);
   1553 }
   1554 #endif /* BCM_TIME_MANAGED_BROADSYNC */
   1555 
   1556 /*
   1557  * Function:
   1558  *    _bcm_esw_time_interface_install
   1559  * Purpose:
   1560  *    Internal routine used to install interface settings into a HW
   1561  * Parameters:
   1562  *    unit           - (IN) BCM device number.
   1563  *    intf_id        - (IN) Interface id to be installed into a HW
   1564  * Returns:
   1565  *    BCM_E_XXX
   1566  */
   1567 STATIC int
   1568 _bcm_esw_time_interface_install(int unit, bcm_time_if_t intf_id)
   1569 {
   1570     bcm_time_interface_t    *intf;  /* Time interface */
   1571     uint32                  regval; /* For register read and write operations */
   1572     uint32                  hw_val; /* Value to program into a HW */
   1573     uint32                  second, diff, delay = BROAD_SYNC_OUTPUT_TOGGLE_TIME_DELAY;
   1574     int                     enable = 0;
   1575     soc_reg_t               reg;
   1576     bcm_time_spec_t         toggle_time;
   1577 
   1578     if (NULL == TIME_INTERFACE(unit, intf_id)) {
   1579         return BCM_E_PARAM;
   1580     }
   1581 
   1582     intf = TIME_INTERFACE(unit, intf_id);
   1583 
   1584     READ_CMIC_BS_CONFIGr(unit, &regval);
   1585 
   1586 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   1587     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   1588         SOC_IS_TD2_TT2(unit)) {
   1589         if ((intf->flags & BCM_TIME_ENABLE)) {
   1590             /* Enable all three broadsync pins:
   1591              *     Bit clock, HeartBeat and Timecode
   1592              */
   1593             soc_reg_field_set(
   1594                     unit, CMIC_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 1);
   1595             soc_reg_field_set(
   1596                     unit, CMIC_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, 1);
   1597             soc_reg_field_set(
   1598                     unit, CMIC_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 1);
   1599         } else {
   1600             soc_reg_field_set(
   1601                     unit, CMIC_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
   1602             soc_reg_field_set(
   1603                     unit, CMIC_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
   1604         }
   1605 
   1606         if ((intf->flags & BCM_TIME_LOCKED)) {
   1607             soc_reg_field32_modify(
   1608                     unit, CMIC_BS_OUTPUT_TIME_0r, REG_PORT_ANY, LOCKf, 1);
   1609         } else {
   1610             soc_reg_field32_modify(
   1611                     unit, CMIC_BS_OUTPUT_TIME_0r, REG_PORT_ANY, LOCKf, 0);
   1612         }
   1613 
   1614     } else
   1615 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   1616     {
   1617         if (intf->flags & BCM_TIME_ENABLE) {
   1618             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, ENABLEf, 1);
   1619             soc_reg_field_set(
   1620                 unit, CMIC_BS_CONFIGr, &regval, TIME_CODE_ENABLEf, 1);
   1621         } else {
   1622             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, ENABLEf, 0);
   1623             soc_reg_field_set(
   1624                 unit, CMIC_BS_CONFIGr, &regval, TIME_CODE_ENABLEf, 0);
   1625         }
   1626 
   1627         if ((intf->flags & BCM_TIME_LOCKED)) {
   1628             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, LOCKf, 1);
   1629         } else {
   1630             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, LOCKf, 0);
   1631         }
   1632     }
   1633 
   1634     if (intf->flags & BCM_TIME_INPUT) {
   1635         /* Set Broadsync in Input mode */
   1636         soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, MODEf,
   1637                           TIME_MODE_INPUT);
   1638     } else {
   1639         /* Configure Accuracy, offset and drift for broadsync output mode */
   1640         soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, MODEf,
   1641                           TIME_MODE_OUTPUT);
   1642         if (intf->flags & BCM_TIME_ACCURACY) {
   1643             BCM_IF_ERROR_RETURN(
   1644                 _bcm_esw_time_interface_accuracy_time2hw(unit, intf_id, &hw_val));
   1645             if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   1646                 SOC_IS_TD2_TT2(unit)) {
   1647                 soc_reg_field32_modify(unit, CMIC_BS_OUTPUT_TIME_0r,
   1648                                        REG_PORT_ANY, ACCURACYf, hw_val);
   1649             } else {
   1650                 soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, ACCURACYf, hw_val);
   1651             }
   1652         }
   1653         if (intf->flags & BCM_TIME_HEARTBEAT) {
   1654             BCM_IF_ERROR_RETURN(
   1655                 _bcm_esw_time_interface_heartbeat_install(unit, intf_id));
   1656 
   1657             if (!(intf->flags & BCM_TIME_OFFSET)) {
   1658                 BCM_IF_ERROR_RETURN(
   1659                     _bcm_esw_time_capture_get(unit, intf_id, TIME_CAPTURE(unit, intf_id), 0));
   1660                 if (!(SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   1661                       SOC_IS_TD2_TT2(unit))) {
   1662                     second = COMPILER_64_LO(SYNT_TIME_SECONDS(unit, intf_id));
   1663                     second += delay;
   1664                     WRITE_CMIC_BS_CLK_TOGGLE_TIME_0r(unit, second);
   1665                     WRITE_CMIC_BS_CLK_TOGGLE_TIME_1r(
   1666                                 unit, SYNT_TIME_NANOSECONDS(unit, intf_id));
   1667                 }
   1668             }
   1669         }
   1670     }
   1671     WRITE_CMIC_BS_CONFIGr(unit, regval);
   1672 
   1673     if (intf->flags & BCM_TIME_OFFSET) {
   1674         if(SOC_REG_IS_VALID(unit, CMIC_BS_CLK_CTRL_0r)) {
   1675             reg   =   CMIC_BS_CLK_CTRL_0r;
   1676             READ_CMIC_BS_CLK_CTRL_0r(unit, &regval);
   1677         } else {
   1678             reg   =   CMIC_BS_CLK_CTRLr;
   1679             READ_CMIC_BS_CLK_CTRLr(unit, &regval);
   1680         }
   1681 
   1682         /* Stop broadsync output if already enabled */
   1683         enable = soc_reg_field_get(unit, reg, regval, ENABLEf);
   1684         if (1 == enable) {
   1685             soc_reg_field_set(unit, reg, &regval, ENABLEf, 0);
   1686             if (SOC_REG_IS_VALID(unit, CMIC_BS_CLK_CTRL_0r)) {
   1687                 WRITE_CMIC_BS_CLK_CTRL_0r(unit, regval);
   1688             } else {
   1689                 WRITE_CMIC_BS_CLK_CTRLr(unit, regval);
   1690             }
   1691             BCM_IF_ERROR_RETURN(
   1692                 _bcm_esw_time_capture_get(unit, intf_id, TIME_CAPTURE(unit, intf_id), 0));
   1693         }
   1694 
   1695         BCM_IF_ERROR_RETURN(
   1696             _bcm_esw_time_interface_offset_install(unit, intf_id));
   1697 
   1698         if (intf->offset.isnegative) {
   1699             second = COMPILER_64_LO(SYNT_TIME_SECONDS(unit, intf_id)) -
   1700                      COMPILER_64_LO(intf->offset.seconds);
   1701 
   1702             if (intf->offset.nanoseconds <= SYNT_TIME_NANOSECONDS(unit, intf_id)) {
   1703                 toggle_time.nanoseconds = SYNT_TIME_NANOSECONDS(unit, intf_id) -
   1704                                           intf->offset.nanoseconds;
   1705             } else {
   1706                 /* Wrapped */
   1707                 diff = intf->offset.nanoseconds - SYNT_TIME_NANOSECONDS(unit, intf_id);
   1708                 toggle_time.nanoseconds = TIME_NANOSEC_MAX - diff;
   1709                 second--;
   1710             }
   1711             COMPILER_64_SET(toggle_time.seconds, 0, second);
   1712         } else {
   1713             second = COMPILER_64_LO(SYNT_TIME_SECONDS(unit, intf_id)) +
   1714                      COMPILER_64_LO(intf->offset.seconds);
   1715             toggle_time.nanoseconds =
   1716                 SYNT_TIME_NANOSECONDS(unit, intf_id) + intf->offset.nanoseconds;
   1717             if (toggle_time.nanoseconds >= TIME_NANOSEC_MAX) {
   1718                 toggle_time.nanoseconds -= TIME_NANOSEC_MAX;
   1719                 second++;
   1720             }
   1721             COMPILER_64_SET(toggle_time.seconds, 0, second);
   1722         }
   1723 
   1724         if (1 == enable) {
   1725             /* Reenable broadsync output */
   1726             COMPILER_64_TO_32_LO(second, toggle_time.seconds);
   1727             second += delay;
   1728             if (SOC_REG_IS_VALID(unit, CMIC_BS_CLK_TOGGLE_TIME_0r)) {
   1729                 WRITE_CMIC_BS_CLK_TOGGLE_TIME_0r(unit, second);
   1730             }
   1731 
   1732             if (SOC_REG_IS_VALID(unit, CMIC_BS_CLK_TOGGLE_TIME_1r)) {
   1733                 WRITE_CMIC_BS_CLK_TOGGLE_TIME_1r(unit, toggle_time.nanoseconds);
   1734             }
   1735 
   1736             if (SOC_REG_IS_VALID(unit, CMIC_BS_CLK_TOGGLE_TIME_1r)) {
   1737                 READ_CMIC_BS_CLK_CTRL_0r(unit, &regval);
   1738                 soc_reg_field_set(unit, CMIC_BS_CLK_CTRL_0r, &regval, ENABLEf, 1);
   1739                 WRITE_CMIC_BS_CLK_CTRL_0r(unit, regval);
   1740             } else {
   1741                 READ_CMIC_BS_CLK_CTRLr(unit, &regval);
   1742                 soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   1743                 WRITE_CMIC_BS_CLK_CTRLr(unit, regval);
   1744             }
   1745         }
   1746     }
   1747 
   1748     if (intf->flags & BCM_TIME_DRIFT) {
   1749         BCM_IF_ERROR_RETURN(
   1750             _bcm_esw_time_interface_drift_install(unit, intf_id));
   1751     }
   1752 
   1753     return (BCM_E_NONE);
   1754 }
   1755 
   1756 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   1757 STATIC int
   1758 _bcm_esw_time_interface_dual_bs_install(int unit, bcm_time_if_t intf_id)
   1759 {
   1760     bcm_time_interface_t    *intf;  /* Time interface */
   1761     uint32                  regval; /* For register read and write operations */
   1762     uint32                  hw_val; /* Value to program into a HW */
   1763 
   1764     /* Feature unavailable on devices without BroadSync support. */
   1765     if (soc_feature(unit, soc_feature_time_v3_no_bs)) {
   1766         return BCM_E_UNAVAIL;
   1767     }
   1768 
   1769     if (NULL == TIME_INTERFACE(unit, intf_id)) {
   1770         return BCM_E_PARAM;
   1771     }
   1772 
   1773     intf = TIME_INTERFACE(unit, intf_id);
   1774 
   1775     if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   1776         READ_NS_BS0_BS_CONFIGr(unit, &regval);
   1777 
   1778         if ((intf->flags & BCM_TIME_LOCKED)) {
   1779             soc_reg_field32_modify(unit, NS_BS0_BS_OUTPUT_TIME_0r, REG_PORT_ANY, LOCKf, 1);
   1780         } else {
   1781             soc_reg_field32_modify(unit, NS_BS0_BS_OUTPUT_TIME_0r, REG_PORT_ANY, LOCKf, 0);
   1782         }
   1783 
   1784         if (intf->flags & BCM_TIME_INPUT) {
   1785             /* Set Broadsync in Input mode */
   1786             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, MODEf, TIME_MODE_INPUT);
   1787 
   1788             /* ensure all output controls are disabled in input mode */
   1789             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
   1790             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
   1791             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, 0);
   1792         } else {
   1793             /* Configure Accuracy, offset and drift for broadsync output mode */
   1794             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, MODEf, TIME_MODE_OUTPUT);
   1795 
   1796             if ((intf->flags & BCM_TIME_ENABLE)) {
   1797                 /* Enable all three broadsync pins: Bit clock, HeartBeat and Timecode */
   1798                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 1);
   1799                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 1);
   1800                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, 1);
   1801             } else {
   1802                 /* ensure all output controls are disabled */
   1803                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
   1804                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
   1805                 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, 0);
   1806             }
   1807 
   1808             if (intf->flags & BCM_TIME_ACCURACY) {
   1809                 BCM_IF_ERROR_RETURN(
   1810                     _bcm_esw_time_interface_accuracy_time2hw(unit, intf_id, &hw_val));
   1811                 soc_reg_field32_modify(unit, NS_BS0_BS_OUTPUT_TIME_0r, REG_PORT_ANY, ACCURACYf, hw_val);
   1812             }
   1813 
   1814             if (intf->flags & BCM_TIME_HEARTBEAT) {
   1815                 BCM_IF_ERROR_RETURN(
   1816                     _bcm_esw_time_interface_heartbeat_install(unit, intf_id));
   1817             }
   1818         }
   1819 
   1820         WRITE_NS_BS0_BS_CONFIGr(unit, regval);
   1821 
   1822     } else {
   1823 
   1824         READ_CMIC_BS0_CONFIGr(unit, &regval);
   1825 
   1826         if ((intf->flags & BCM_TIME_LOCKED)) {
   1827             soc_reg_field32_modify(unit, CMIC_BS0_OUTPUT_TIME_0r, REG_PORT_ANY, LOCKf, 1);
   1828         } else {
   1829             soc_reg_field32_modify(unit, CMIC_BS0_OUTPUT_TIME_0r, REG_PORT_ANY, LOCKf, 0);
   1830         }
   1831 
   1832         if (intf->flags & BCM_TIME_INPUT) {
   1833             /* Set Broadsync in Input mode */
   1834             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, MODEf, TIME_MODE_INPUT);
   1835 
   1836             /* ensure all output controls are disabled in input mode */
   1837             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
   1838             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
   1839             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, 0);
   1840         } else {
   1841             /* Configure Accuracy, offset and drift for broadsync output mode */
   1842             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, MODEf, TIME_MODE_OUTPUT);
   1843 
   1844             if ((intf->flags & BCM_TIME_ENABLE)) {
   1845                 /* Enable all three broadsync pins: Bit clock, HeartBeat and Timecode */
   1846                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 1);
   1847                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 1);
   1848                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, 1);
   1849             } else {
   1850                 /* ensure all output controls are disabled */
   1851                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, 0);
   1852                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, 0);
   1853                 soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, 0);
   1854             }
   1855 
   1856             if (intf->flags & BCM_TIME_ACCURACY) {
   1857                 BCM_IF_ERROR_RETURN(
   1858                     _bcm_esw_time_interface_accuracy_time2hw(unit, intf_id, &hw_val));
   1859                 soc_reg_field32_modify(unit, CMIC_BS0_OUTPUT_TIME_0r, REG_PORT_ANY, ACCURACYf, hw_val);
   1860             }
   1861 
   1862             if (intf->flags & BCM_TIME_HEARTBEAT) {
   1863                 BCM_IF_ERROR_RETURN(
   1864                     _bcm_esw_time_interface_heartbeat_install(unit, intf_id));
   1865             }
   1866         }
   1867 
   1868         WRITE_CMIC_BS0_CONFIGr(unit, regval);
   1869     }
   1870     return (BCM_E_NONE);
   1871 }
   1872 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   1873 
   1874 
   1875 /*
   1876  * Function:
   1877  *     _bcm_time_interface_free
   1878  * Purpose:
   1879  *     Free time interface.
   1880  * Parameters:
   1881  *      unit            - (IN) BCM device number.
   1882  *      intf_id         - (IN) time interface id.
   1883  * Returns:
   1884  *      BCM_X_XXX
   1885  */
   1886 
   1887 STATIC int
   1888 _bcm_time_interface_free(int unit, bcm_time_if_t intf_id)
   1889 {
   1890     _bcm_time_interface_config_p  intf_cfg; /* Time interface config.*/
   1891 
   1892     intf_cfg = &TIME_INTERFACE_CONFIG(unit, intf_id);
   1893 
   1894     if (intf_cfg->ref_count > 0) {
   1895         intf_cfg->ref_count--;
   1896     }
   1897 
   1898     if (0 == intf_cfg->ref_count) {
   1899         sal_memset(&intf_cfg->time_interface, 0, sizeof(bcm_time_interface_t));
   1900         intf_cfg->time_interface.id = intf_id;
   1901     }
   1902 
   1903     return (BCM_E_NONE);
   1904 }
   1905 
   1906 /*
   1907  * Function:
   1908  *      _bcm_esw_time_accuracy_parse
   1909  * Purpose:
   1910  *      Internal routine to parse accuracy hw value into bcm_time_spec_t format
   1911  * Parameters:
   1912  *      unit        - (IN) StrataSwitch Unit #.
   1913  *      accuracy    - (IN) Accuracy HW value
   1914  *      time        - (OUT) bcm_time_spec_t structure to contain accuracy
   1915  * Returns:
   1916  *      BCM_E_NONE
   1917  *      BCM_E_XXX
   1918  */
   1919 STATIC int
   1920 _bcm_esw_time_accuracy_parse(int unit, uint32 accuracy, bcm_time_spec_t *time)
   1921 {
   1922     if (accuracy < TIME_ACCURACY_LOW_HW_VAL ||
   1923         (accuracy > TIME_ACCURACY_HIGH_HW_VAL &&
   1924          accuracy != TIME_ACCURACY_UNKNOWN_HW_VAL)) {
   1925         return (BCM_E_PARAM);
   1926     }
   1927 
   1928     time->isnegative =
   1929         _bcm_time_accuracy_arr[TIME_ACCURACY_HW_2_SW_IDX(accuracy)].isnegative;
   1930     time->nanoseconds =
   1931         _bcm_time_accuracy_arr[TIME_ACCURACY_HW_2_SW_IDX(accuracy)].nanoseconds;
   1932     time->seconds =
   1933         _bcm_time_accuracy_arr[TIME_ACCURACY_HW_2_SW_IDX(accuracy)].seconds;
   1934     time->isnegative = 0;   /* Can't be negative */
   1935 
   1936     return (BCM_E_NONE);
   1937 }
   1938 
   1939 
   1940 /*
   1941  * Function:
   1942  *      _bcm_esw_time_input_parse
   1943  * Purpose:
   1944  *      Internal routine to parse input time information stored in 3 registeres
   1945  * Parameters:
   1946  *      unit    - (IN) StrataSwitch Unit #.
   1947  *      data0   - (IN) Data stored in register 0 conrain input time information
   1948  *      data1   - (IN) Data stored in register 1 conrain input time information
   1949  *      data2   - (IN) Data stored in register 2 conrain input time information
   1950  *      time    - (OUT) Structure to contain input time information
   1951  * Returns:
   1952  *      BCM_E_NONE
   1953  *      BCM_E_XXX
   1954  */
   1955 STATIC int
   1956 _bcm_esw_time_input_parse(int unit, uint32 data0, uint32 data1, uint32 data2,
   1957                           bcm_time_capture_t *time)
   1958 {
   1959     uint32 accuracy, sec_hi, sec_lo;
   1960 
   1961     if (data0 >> 31) {
   1962         time->flags |= BCM_TIME_CAPTURE_LOCKED;
   1963     }
   1964     time->received.isnegative = 0;
   1965     sec_hi = ((data0 << 1) >> 1);
   1966     sec_lo = (data1 >> 14);
   1967     COMPILER_64_SET(time->received.seconds, sec_hi, sec_lo);
   1968     time->received.nanoseconds = (data1 << 16);
   1969     time->received.nanoseconds |= (data2 >> 8);
   1970 
   1971     accuracy = ((data2 << 24) >> 24);
   1972 
   1973     return _bcm_esw_time_accuracy_parse(unit,accuracy,
   1974                                         &(time->received_accuracy));
   1975 }
   1976 
   1977 /*
   1978  * Function:
   1979  *      _bcm_esw_time_capture_counter_read
   1980  * Purpose:
   1981  *      Internal routine to read HW clocks
   1982  * Parameters:
   1983  *      unit    - (IN) StrataSwitch Unit #.
   1984  *      id      - (IN) Time interface identifier
   1985  *      time    - (OUT) Structure to contain HW clocks values
   1986  * Returns:
   1987  *      BCM_E_NONE
   1988  *      BCM_E_XXX
   1989  */
   1990 
   1991 STATIC int
   1992 _bcm_esw_time_capture_counter_read(int unit, bcm_time_if_t id,
   1993                                    bcm_time_capture_t *time)
   1994 {
   1995     uint32                  regval;
   1996     bcm_time_interface_t    *intf;
   1997 
   1998 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   1999     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   2000         uint32 regval2, event_id, lower;
   2001         uint32 upper;
   2002         sal_memset(time, 0, sizeof(bcm_time_capture_t));
   2003 
   2004         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   2005             /* Read timestamp from FIFO */
   2006             uint32 regval1, regval3;
   2007             READ_NS_TS_INT_STATUSr(unit, &regval);
   2008             if (0 == soc_reg_field_get(unit, NS_TS_INT_STATUSr, 
   2009                                        regval, TS_FIFO_NOT_EMPTYf)) {
   2010                 return (BCM_E_EMPTY);
   2011             }
   2012 
   2013             /* Must read LOWER regiser first */
   2014             /* Read to this register POPs the FIFO */
   2015             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_0r(unit, &regval);
   2016             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_1r(unit, &regval1);
   2017             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_2r(unit, &regval2);
   2018             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r(unit, &regval3);
   2019 
   2020              /* If it's not valid, something is wrong (since FIFO is not empty) */
   2021             if (0 == soc_reg_field_get(
   2022                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r, regval3, 
   2023                             TS_VALIDf)) {
   2024                 return (BCM_E_FAIL);
   2025             }
   2026             /* Check capture event id */
   2027             event_id = soc_reg_field_get(
   2028                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r, 
   2029                             regval3, TS_EVENT_IDf);
   2030             
   2031             if (event_id == 0) {
   2032                 time->flags |= BCM_TIME_CAPTURE_IMMEDIATE;
   2033             }
   2034             /* Calculate seconds/nanoseconds from the timestamp value */
   2035             lower = soc_reg_field_get(
   2036                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_0r,
   2037                             regval, TS0_Lf);
   2038 
   2039             upper = soc_reg_field_get(
   2040                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_1r,
   2041                             regval1, TS0_Uf);
   2042             /* Discard 4bits from lower*/
   2043             lower = (lower >> 4);
   2044             lower = (lower & 0x0FFFFFFF) | ((upper & 0xF) << 28);
   2045             upper = (upper >> 4);
   2046 
   2047         } else {
   2048             /* Read timestamp from FIFO */
   2049             READ_CMIC_TIMESYNC_CAPTURE_STATUS_1r(unit, &regval);
   2050             if (0 == soc_reg_field_get(unit, CMIC_TIMESYNC_CAPTURE_STATUS_1r, 
   2051                                        regval, FIFO_DEPTHf)) {
   2052                 return (BCM_E_EMPTY);
   2053             }
   2054 
   2055             /* Must read LOWER regiser first */
   2056             READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr(unit, &regval2);
   2057 
   2058             /* Then read UPPER register */
   2059             READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr(unit, &regval);
   2060              /* If it's not valid, something is wrong (since FIFO is not empty) */
   2061             if (0 == soc_reg_field_get(
   2062                             unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr, regval, 
   2063                             VALIDf)) {
   2064                 return (BCM_E_FAIL);
   2065             }
   2066             /* Check capture event id */
   2067             event_id = soc_reg_field_get(
   2068                             unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr, 
   2069                             regval, EVENT_IDf);
   2070             if (event_id == 0) {
   2071                 time->flags |= BCM_TIME_CAPTURE_IMMEDIATE;
   2072             }
   2073             /* Calculate seconds/nanoseconds from the timestamp value */
   2074             lower = soc_reg_field_get(
   2075                             unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr,
   2076                             regval2, TIMESTAMPf);
   2077 
   2078             upper = soc_reg_field_get(
   2079                             unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr,
   2080                             regval, TIMESTAMPf);
   2081 
   2082         }
   2083 
   2084         if (soc_feature(unit, soc_feature_timesync_timestampingmode)) {
   2085             /* 48-bit timestamping supported */
   2086             uint64 time_val, secs, nano_secs;
   2087             uint64 div;
   2088             /* Get the 48-bit timestamp value */
   2089             COMPILER_64_SET(time_val, upper, lower);
   2090 
   2091             /* Get seconds from the timestamp value */
   2092             secs = time_val;
   2093             COMPILER_64_SET(div, 0, 1000000000);
   2094             COMPILER_64_UDIV_64(secs, div);
   2095             time->synchronous.seconds = secs;
   2096 
   2097             /* Get nanoseconds from the timestamp value */
   2098             nano_secs = time_val;
   2099             COMPILER_64_UMUL_32(secs, 1000000000);
   2100             COMPILER_64_SUB_64(nano_secs, secs);
   2101             time->synchronous.nanoseconds = COMPILER_64_LO(nano_secs);
   2102         } else {
   2103             COMPILER_64_SET(time->synchronous.seconds, 0, lower / 1000000000);
   2104             time->synchronous.nanoseconds = lower % 1000000000;
   2105         }
   2106 
   2107         /* For backward compatibility */
   2108         time->free = time->synchronous;
   2109         time->syntonous = time->synchronous;
   2110 
   2111     } else 
   2112 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   2113 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   2114     if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) ||
   2115         SOC_IS_TD2_TT2(unit)) {
   2116         uint32 event_id;
   2117 
   2118         /* Check FIFO depth */
   2119         sal_memset(time, 0, sizeof(bcm_time_capture_t));
   2120         READ_CMIC_TS_CAPTURE_STATUSr(unit, &regval);
   2121         if (0 == soc_reg_field_get(unit, CMIC_TS_CAPTURE_STATUSr,
   2122                                    regval, FIFO_DEPTHf)) {
   2123             return (BCM_E_EMPTY);
   2124         }
   2125 
   2126         /* Read timestamp from FIFO */
   2127         READ_CMIC_TS_INPUT_TIME_FIFO_TSr(unit, &regval);
   2128         time->synchronous.nanoseconds =  soc_reg_field_get(unit,
   2129                                           CMIC_TS_INPUT_TIME_FIFO_TSr, regval,
   2130                                           TIMESTAMPf);
   2131 
   2132         /* If it's not valid, something is wrong (since FIFO is not empty) */
   2133         READ_CMIC_TS_INPUT_TIME_FIFO_IDr(unit, &regval);
   2134         if (0 == soc_reg_field_get(
   2135                         unit, CMIC_TS_INPUT_TIME_FIFO_IDr, regval,
   2136                         VALIDf)) {
   2137             return (BCM_E_FAIL);
   2138         }
   2139 
   2140         /* Check capture event id */
   2141         event_id = soc_reg_field_get(
   2142                         unit, CMIC_TS_INPUT_TIME_FIFO_IDr,
   2143                         regval, EVENT_IDf);
   2144 
   2145         if (event_id == 0) {
   2146             time->flags |= BCM_TIME_CAPTURE_IMMEDIATE;
   2147         }
   2148 
   2149         /* For backward compatibility */
   2150         time->free = time->synchronous;
   2151         time->syntonous = time->synchronous;
   2152 
   2153     } else 
   2154 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   2155     {
   2156         /* Read free running time capture */
   2157         READ_CMIC_BS_CAPTURE_FREE_RUN_TIME_0r(unit, &regval);
   2158         COMPILER_64_SET(time->free.seconds, 0,  
   2159             soc_reg_field_get(unit, CMIC_BS_CAPTURE_FREE_RUN_TIME_0r, 
   2160                               regval, SECONDf)); 
   2161         READ_CMIC_BS_CAPTURE_FREE_RUN_TIME_1r(unit, &regval);
   2162         time->free.nanoseconds =  
   2163          soc_reg_field_get(unit, CMIC_BS_CAPTURE_FREE_RUN_TIME_1r, regval, NSf); 
   2164         /* Read syntonous time capture */
   2165         READ_CMIC_BS_CAPTURE_SYNT_TIME_0r(unit, &regval);
   2166         COMPILER_64_SET(time->syntonous.seconds, 0,
   2167          soc_reg_field_get(unit, CMIC_BS_CAPTURE_SYNT_TIME_0r, regval, SECONDf));
   2168         READ_CMIC_BS_CAPTURE_SYNT_TIME_1r(unit, &regval);
   2169         time->syntonous.nanoseconds = 
   2170             soc_reg_field_get(unit, CMIC_BS_CAPTURE_SYNT_TIME_1r, regval, NSf);
   2171         /* Read synchronous time capture */
   2172         READ_CMIC_BS_CAPTURE_SYNC_TIME_0r(unit, &regval);
   2173         COMPILER_64_SET(time->synchronous.seconds, 0, 
   2174          soc_reg_field_get(unit, CMIC_BS_CAPTURE_SYNC_TIME_0r, regval, SECONDf));
   2175         READ_CMIC_BS_CAPTURE_SYNC_TIME_1r(unit, &regval);
   2176         time->synchronous.nanoseconds = 
   2177             soc_reg_field_get(unit, CMIC_BS_CAPTURE_SYNC_TIME_1r, regval, NSf);
   2178     }
   2179 
   2180     time->free.isnegative = time->synchronous.isnegative = 
   2181         time->syntonous.isnegative = 0;
   2182 
   2183     /* If interface is in input mode read time provided by the master */
   2184     intf = TIME_INTERFACE(unit, id);
   2185     if (intf->flags & BCM_TIME_INPUT) {
   2186         uint32  data0 = 0, data1 = 0, data2 = 0;
   2187 
   2188 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   2189         if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   2190             if (!soc_feature(unit, soc_feature_time_v3_no_bs)) {
   2191                 if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   2192                     READ_NS_BS0_BS_INPUT_TIME_2r(unit, &regval);
   2193                     if (soc_reg_field_get(unit, NS_BS0_BS_INPUT_TIME_2r, regval, 
   2194                                           CHECKSUM_ERRORf)) {
   2195                         return BCM_E_INTERNAL;
   2196                     }
   2197                     data2 = soc_reg_field_get(
   2198                                 unit, NS_BS0_BS_INPUT_TIME_2r, regval, DATAf);
   2199                     READ_NS_BS0_BS_INPUT_TIME_1r(unit, &regval);
   2200                     data1 = soc_reg_field_get(
   2201                                 unit, NS_BS0_BS_INPUT_TIME_1r, regval, DATAf);
   2202                     READ_NS_BS0_BS_INPUT_TIME_0r(unit, &regval);
   2203                     data0 = soc_reg_field_get(
   2204                                 unit, NS_BS0_BS_INPUT_TIME_0r, regval, DATAf);
   2205                 } else {
   2206                     READ_CMIC_BS0_INPUT_TIME_2r(unit, &regval);
   2207                     if (soc_reg_field_get(unit, CMIC_BS0_INPUT_TIME_2r, regval, 
   2208                                           CHECKSUM_ERRORf)) {
   2209                         return BCM_E_INTERNAL;
   2210                     }
   2211                     data2 = soc_reg_field_get(
   2212                                 unit, CMIC_BS0_INPUT_TIME_2r, regval, DATAf);
   2213                     READ_CMIC_BS0_INPUT_TIME_1r(unit, &regval);
   2214                     data1 = soc_reg_field_get(
   2215                                 unit, CMIC_BS0_INPUT_TIME_1r, regval, DATAf);
   2216                     READ_CMIC_BS0_INPUT_TIME_0r(unit, &regval);
   2217                     data0 = soc_reg_field_get(
   2218                                 unit, CMIC_BS0_INPUT_TIME_0r, regval, DATAf);
   2219                 }
   2220             }
   2221         } else
   2222 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   2223         {
   2224             READ_CMIC_BS_INPUT_TIME_2r(unit, &regval);
   2225             if (soc_reg_field_get(unit, CMIC_BS_INPUT_TIME_2r, regval, 
   2226                                   CHECKSUM_ERRORf)) {
   2227                 return BCM_E_INTERNAL;
   2228             }
   2229             data2 = soc_reg_field_get(unit, CMIC_BS_INPUT_TIME_2r, regval, DATAf);
   2230             READ_CMIC_BS_INPUT_TIME_1r(unit, &regval);
   2231             data1 = soc_reg_field_get(unit, CMIC_BS_INPUT_TIME_1r, regval, DATAf);
   2232             READ_CMIC_BS_INPUT_TIME_0r(unit, &regval);
   2233             data0 = soc_reg_field_get(unit, CMIC_BS_INPUT_TIME_0r, regval, DATAf);
   2234         }
   2235 
   2236         BCM_IF_ERROR_RETURN(
   2237             _bcm_esw_time_input_parse(unit, data0, data1, data2, time));
   2238     }
   2239 
   2240     return (BCM_E_NONE);
   2241 }
   2242 
   2243 /*
   2244  * Function:
   2245  *      _bcm_esw_time_capture_get
   2246  * Purpose:
   2247  *      Internal routine to read HW clocks
   2248  * Parameters:
   2249  *      unit    - (IN) StrataSwitch Unit #.
   2250  *      id      - (IN) Time interface identifier
   2251  *      time    - (OUT) Structure to contain HW clocks values
   2252  *      flags   - (IN) Flags BCM_TIME_CAPTURE_
   2253  * Returns:
   2254  *      BCM_E_NONE
   2255  *      BCM_E_XXX
   2256  */
   2257 STATIC int 
   2258 _bcm_esw_time_capture_get (int unit, bcm_time_if_t id, bcm_time_capture_t *time, uint32 flags)
   2259 {
   2260     uint32          regval, orgval; /* To keep register value */
   2261     int             hw_complete;    /* HW read completion indicator*/
   2262     soc_timeout_t   timeout;        /* Timeout in case of HW error */
   2263 #if defined(BCM_GREYHOUND_SUPPORT)
   2264     uint32 lower, upper;
   2265 #endif
   2266 
   2267 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   2268     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   2269         /* Read capture mode */
   2270         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   2271             uint32 lower, upper;
   2272             READ_NS_MISC_CLK_EVENT_CTRLr(unit, &regval);
   2273             orgval = soc_reg_field_get(unit, NS_MISC_CLK_EVENT_CTRLr, 
   2274                                        regval, ENABLEf);
   2275             if (flags == BCM_TIME_CAPTURE_IMMEDIATE || orgval == TIME_CAPTURE_MODE_DISABLE ||
   2276                    orgval == TIME_CAPTURE_MODE_IMMEDIATE) {
   2277                 /* do an immediate capture */
   2278                 READ_NS_TIMESYNC_TS0_TIMESTAMP_UPPER_STATUSr(unit, &regval);
   2279                 upper = regval;
   2280                 READ_NS_TIMESYNC_TS0_TIMESTAMP_LOWER_STATUSr(unit, &regval);
   2281                 lower = regval;
   2282                 /* Discard 4bits from lower*/
   2283                 lower = (lower >> 4);
   2284                 lower = (lower & 0x0FFFFFFF) | ((upper & 0xF) << 28);
   2285                 upper = (upper >> 4);
   2286 
   2287                 if (soc_feature(unit, soc_feature_timesync_timestampingmode)) {
   2288                     /* 48-bit timestamping supported */
   2289                     uint64 time_val, secs, nano_secs;
   2290                     uint64 div;
   2291                     /* Get the 48-bit timestamp value */
   2292                     COMPILER_64_SET(time_val, upper, lower);
   2293                     /* Get seconds from the timestamp value */
   2294                     secs = time_val;
   2295                     COMPILER_64_SET(div, 0, 1000000000);
   2296                     COMPILER_64_UDIV_64(secs, div);
   2297                     time->synchronous.seconds = secs;
   2298 
   2299                     /* Get nanoseconds from the timestamp value */
   2300                     nano_secs = time_val;
   2301                     COMPILER_64_UMUL_32(secs, 1000000000);
   2302                     COMPILER_64_SUB_64(nano_secs, secs);
   2303                     time->synchronous.nanoseconds = COMPILER_64_LO(nano_secs);
   2304                 } else {
   2305                     COMPILER_64_SET(time->synchronous.seconds, 0, lower / 1000000000);
   2306                     time->synchronous.nanoseconds = lower % 1000000000;
   2307                 }
   2308 
   2309                 /* For backward compatibility */
   2310                 time->free = time->synchronous;
   2311                 time->syntonous = time->synchronous;
   2312                 time->flags |= BCM_TIME_CAPTURE_IMMEDIATE;
   2313                 return BCM_E_NONE;
   2314             } else {
   2315 
   2316                 /* If any trigger condition is set, get the timestamp from FIFO */
   2317                 return _bcm_esw_time_capture_counter_read(unit, id, time);
   2318             }
   2319         }
   2320 #if defined(BCM_GREYHOUND_SUPPORT)
   2321         if (flags == BCM_TIME_CAPTURE_IMMEDIATE) {
   2322             /* do an immediate capture */
   2323             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_LOWERr(unit, &regval);
   2324             lower = regval;
   2325             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr(unit, &regval);
   2326             upper = regval;
   2327             if (soc_feature(unit, soc_feature_timesync_timestampingmode)) {
   2328                 /* 48-bit timestamping supported */
   2329                 uint64 time_val, secs, nano_secs;
   2330                 uint64 div;
   2331                 /* Get the 48-bit timestamp value */
   2332                 COMPILER_64_SET(time_val, upper, lower);
   2333                 /* Get seconds from the timestamp value */
   2334                 secs = time_val;
   2335                 COMPILER_64_SET(div, 0, 1000000000);
   2336                 COMPILER_64_UDIV_64(secs, div);
   2337                 time->synchronous.seconds = secs;
   2338 
   2339                 /* Get nanoseconds from the timestamp value */
   2340                 nano_secs = time_val;
   2341                 COMPILER_64_UMUL_32(secs, 1000000000);
   2342                 COMPILER_64_SUB_64(nano_secs, secs);
   2343                 time->synchronous.nanoseconds = COMPILER_64_LO(nano_secs);
   2344             } else {
   2345                 COMPILER_64_SET(time->synchronous.seconds, 0, lower / 1000000000);
   2346                 time->synchronous.nanoseconds = lower % 1000000000;
   2347             }
   2348 
   2349             /* For backward compatibility */
   2350             time->free = time->synchronous;
   2351             time->syntonous = time->synchronous;
   2352             return BCM_E_NONE;
   2353         }
   2354 #endif
   2355         READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &regval);
   2356         orgval = soc_reg_field_get(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, 
   2357                                    regval, TIME_CAPTURE_MODEf);
   2358 
   2359         /* If any trigger condition is set, get the timestamp from FIFO */
   2360         if ((orgval != TIME_CAPTURE_MODE_DISABLE) && 
   2361             (orgval != TIME_CAPTURE_MODE_IMMEDIATE)) {
   2362             return _bcm_esw_time_capture_counter_read(unit, id, time);
   2363         }
   2364         /* Make sure timestamp capture is enabled */
   2365         READ_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, &regval);
   2366         if (0 == soc_reg_field_get(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, 
   2367                                    regval, TIME_CAPTURE_ENABLEf)) {
   2368             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, 
   2369                             &regval, TIME_CAPTURE_ENABLEf, 1 );
   2370             WRITE_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, regval);
   2371         }
   2372 
   2373         /* Clear the FIFO if not empty */
   2374         for(;;) {
   2375             READ_CMIC_TIMESYNC_CAPTURE_STATUS_1r(unit, &regval);
   2376             if (0 == soc_reg_field_get(unit, CMIC_TIMESYNC_CAPTURE_STATUS_1r, 
   2377                                        regval, FIFO_DEPTHf)) {
   2378                 break;
   2379             }
   2380             /* There is still something in the FIFO, pop it */
   2381             READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr(unit, &regval);
   2382             READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr(unit, &regval);
   2383         }
   2384 
   2385         /* Make sure the capture status is cleared */
   2386         READ_CMIC_TIMESYNC_CAPTURE_STATUS_1r(unit, &regval);
   2387         if (regval != 0) {
   2388             soc_reg_field_set(unit, CMIC_TIMESYNC_CAPTURE_STATUS_CLR_1r, 
   2389                               &regval, TIME_CAPTURE_COMPLETE_CLRf, 1);
   2390             soc_reg_field_set(unit, CMIC_TIMESYNC_CAPTURE_STATUS_CLR_1r, 
   2391                               &regval, FIFO_WRITE_COMPLETE_CLRf, 1);
   2392             WRITE_CMIC_TIMESYNC_CAPTURE_STATUS_CLR_1r(unit, regval);
   2393         }
   2394 
   2395         /* Program HW to capture time immediately */
   2396         READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &regval);
   2397         soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &regval, 
   2398                           TIME_CAPTURE_MODEf, TIME_CAPTURE_MODE_IMMEDIATE);
   2399         WRITE_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, regval);
   2400 
   2401         /* Wait for HW time capture completion */
   2402         hw_complete = 0;
   2403         soc_timeout_init(&timeout, BROAD_SYNC_TIME_CAPTURE_TIMEOUT, 0);
   2404         while (!hw_complete) {
   2405             READ_CMIC_TIMESYNC_CAPTURE_STATUS_1r(unit, &regval);
   2406             hw_complete = soc_reg_field_get(unit, CMIC_TIMESYNC_CAPTURE_STATUS_1r,
   2407                                             regval, TIME_CAPTURE_COMPLETEf); 
   2408             if (soc_timeout_check(&timeout)) {
   2409                 return (BCM_E_TIMEOUT);
   2410             }
   2411         }
   2412 
   2413         /* Program HW to disable time capture */
   2414         READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &regval);
   2415         soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &regval, 
   2416                             TIME_CAPTURE_MODEf, TIME_CAPTURE_MODE_DISABLE);
   2417         WRITE_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, regval);
   2418 
   2419         /* Read the HW time */
   2420         BCM_IF_ERROR_RETURN(
   2421             _bcm_esw_time_capture_counter_read(unit, id, time));
   2422 
   2423     } else
   2424 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   2425 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   2426     if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) ||
   2427         SOC_IS_TD2_TT2(unit)) {
   2428         /* Read capture mode */
   2429         READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
   2430         /* If any trigger condition is set, get the timestamp from FIFO */
   2431         if (TIME_CAPTURE_MODE_DISABLE != soc_reg_field_get(unit,
   2432                    CMIC_TS_TIME_CAPTURE_CTRLr, regval, TIME_CAPTURE_MODEf) ) {
   2433             return _bcm_esw_time_capture_counter_read(unit, id, time);
   2434         }
   2435 
   2436         /* if different than interrupt remember original capture mode */
   2437         orgval = regval;
   2438 
   2439         /* Program HW to disable time capture */
   2440         soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, 
   2441                             TIME_CAPTURE_MODEf, TIME_CAPTURE_MODE_DISABLE);
   2442         if (orgval != regval) {
   2443             WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, regval);
   2444         }
   2445 
   2446         /* Make sure timestamp capture is enabled */
   2447         READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
   2448         if (0 == soc_reg_field_get(unit, CMIC_TS_TIME_CAPTURE_CTRLr,
   2449                                    regval, TIME_CAPTURE_ENABLEf)) {
   2450             soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr,
   2451                             &regval, TIME_CAPTURE_ENABLEf, 1 );
   2452             WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, regval);
   2453         }
   2454 
   2455         /* Clear the FIFO if not empty */
   2456         for(;;) {
   2457             READ_CMIC_TS_CAPTURE_STATUSr(unit, &regval);
   2458             if (0 == soc_reg_field_get(unit, CMIC_TS_CAPTURE_STATUSr,
   2459                                        regval, FIFO_DEPTHf)) {
   2460                 break;
   2461             }
   2462             /* There is still something in the FIFO, pop it */
   2463             READ_CMIC_TS_INPUT_TIME_FIFO_TSr(unit, &regval);
   2464         }
   2465 
   2466         /* Make sure the capture status is cleared */
   2467         READ_CMIC_TS_CAPTURE_STATUSr(unit, &regval);
   2468         if (regval != 0) {
   2469             soc_reg_field_set(unit, CMIC_TS_CAPTURE_STATUS_CLRr,
   2470                               &regval, TIME_CAPTURE_COMPLETE_CLRf, 1);
   2471             soc_reg_field_set(unit, CMIC_TS_CAPTURE_STATUS_CLRr,
   2472                               &regval, FIFO_WRITE_COMPLETE_CLRf, 1);
   2473             WRITE_CMIC_TS_CAPTURE_STATUS_CLRr(unit, regval);
   2474         }
   2475  
   2476         /* Program HW to capture time immediately */
   2477         READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
   2478         soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, 
   2479                         TIME_CAPTURE_MODEf,TIME_CAPTURE_MODE_IMMEDIATE);
   2480         WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, regval);
   2481 
   2482         /* Wait for HW time capture completion */
   2483         hw_complete = 0;
   2484         soc_timeout_init(&timeout, BROAD_SYNC_TIME_CAPTURE_TIMEOUT, 0);
   2485 
   2486         while (!hw_complete) {
   2487             READ_CMIC_TS_CAPTURE_STATUSr(unit, &regval);
   2488             hw_complete = soc_reg_field_get(unit, CMIC_TS_CAPTURE_STATUSr,
   2489                                             regval, TIME_CAPTURE_COMPLETEf); 
   2490             if (soc_timeout_check(&timeout)) {
   2491                 return (BCM_E_TIMEOUT);
   2492             }
   2493         }
   2494 
   2495         /* Read the HW time */
   2496         BCM_IF_ERROR_RETURN(
   2497             _bcm_esw_time_capture_counter_read(unit, id, time));
   2498 
   2499         /* Program HW to original time capture value */
   2500         WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, orgval);
   2501 
   2502     } else
   2503 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   2504     {
   2505         /* Read capture mode */
   2506         READ_CMIC_BS_CAPTURE_CTRLr(unit, &regval);
   2507         /* If in interrupt mode, return time captured on last interrupt */
   2508         if (TIME_CAPTURE_MODE_HEARTBEAT == soc_reg_field_get(unit, 
   2509                             CMIC_BS_CAPTURE_CTRLr, regval, TIME_CAPTURE_MODEf)) {
   2510             return _bcm_esw_time_capture_counter_read(unit, id, time);
   2511         }
   2512         /* if different than interrupt remember original capture mode */
   2513         orgval = regval;
   2514 
   2515         /* Program HW to disable time capture */
   2516         soc_reg_field_set(unit, CMIC_BS_CAPTURE_CTRLr, &regval, TIME_CAPTURE_MODEf,
   2517                           TIME_CAPTURE_MODE_DISABLE);
   2518         if (orgval != regval) {
   2519             WRITE_CMIC_BS_CAPTURE_CTRLr(unit, regval);
   2520         }
   2521 
   2522         /* Program HW to capture time immediately */
   2523         soc_reg_field_set(unit, CMIC_BS_CAPTURE_CTRLr, &regval, TIME_CAPTURE_MODEf,
   2524                           TIME_CAPTURE_MODE_IMMEDIATE);
   2525         WRITE_CMIC_BS_CAPTURE_CTRLr(unit, regval);
   2526 
   2527         /* Wait for HW time capture completion */
   2528         hw_complete = 0;
   2529         soc_timeout_init(&timeout, BROAD_SYNC_TIME_CAPTURE_TIMEOUT, 0);
   2530 
   2531         while (!hw_complete) {
   2532             READ_CMIC_BS_CAPTURE_STATUSr(unit, &regval);
   2533             hw_complete = soc_reg_field_get(unit, CMIC_BS_CAPTURE_STATUSr, regval,
   2534                                             TIME_CAPTURE_COMPLETEf); 
   2535             if (soc_timeout_check(&timeout)) {
   2536                 return (BCM_E_TIMEOUT);
   2537             }
   2538         }
   2539         /* Read the HW time */
   2540         BCM_IF_ERROR_RETURN(
   2541             _bcm_esw_time_capture_counter_read(unit, id, time));
   2542 
   2543         /* Program HW to original time capture value */
   2544         WRITE_CMIC_BS_CAPTURE_CTRLr(unit, orgval);
   2545     }
   2546 
   2547     return BCM_E_NONE;
   2548 }
   2549 
   2550 /*
   2551  * Function:
   2552  *      _bcm_esw_time_interface_offset_get
   2553  * Purpose:
   2554  *      Internal routine to read HW offset value and convert it into 
   2555  *      bcm_time_spec_t structure 
   2556  * Parameters:
   2557  *      unit    -  (IN) StrataSwitch Unit #.
   2558  *      id      -  (IN) Time interface identifier
   2559  *      offset  - (OUT) Time interface  offset 
   2560  * Returns:
   2561  *      BCM_E_NONE
   2562  *      BCM_E_XXX
   2563  */
   2564 STATIC int 
   2565 _bcm_esw_time_interface_offset_get(int unit, bcm_time_if_t id, 
   2566                                    bcm_time_spec_t *offset)
   2567 {
   2568     uint32 regval, sec, epoch;
   2569 
   2570 #if defined(BCM_TIME_V3_SUPPORT)
   2571     /* Not supported in 3rd generation time arch */
   2572     if (soc_feature(unit, soc_feature_time_v3)) {
   2573         return BCM_E_UNAVAIL;
   2574     }
   2575 #endif /* defined(BCM_TIME_V3_SUPPORT) */
   2576 
   2577 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   2578     /* Katana does not support clock offset */
   2579     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   2580         SOC_IS_TD2_TT2(unit)) {
   2581         return BCM_E_UNAVAIL;
   2582     }
   2583 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   2584 
   2585     READ_CMIC_BS_OFFSET_ADJUST_0r(unit, &regval);
   2586     sec = soc_reg_field_get(unit, CMIC_BS_OFFSET_ADJUST_0r, regval, SECONDf);
   2587     READ_CMIC_BS_OFFSET_ADJUST_1r(unit, &regval);
   2588     offset->nanoseconds= soc_reg_field_get(unit, CMIC_BS_OFFSET_ADJUST_1r,
   2589                                            regval, NSf); 
   2590     offset->isnegative = soc_reg_field_get(unit, CMIC_BS_OFFSET_ADJUST_1r, 
   2591                                            regval, SIGN_BITf);
   2592     /* If the epoch was installed read it */
   2593     READ_CMIC_BS_CONFIGr(unit, &regval);
   2594     epoch = soc_reg_field_get(unit,CMIC_BS_CONFIGr, regval, EPOCHf);
   2595 
   2596     COMPILER_64_SET(offset->seconds, epoch, sec);
   2597 
   2598     return (BCM_E_NONE);
   2599 }
   2600 
   2601 /*
   2602  * Function:
   2603  *      _bcm_esw_time_interface_drift_get
   2604  * Purpose:
   2605  *      Internal routine to read HW drift value and convert it into 
   2606  *      bcm_time_spec_t structure 
   2607  * Parameters:
   2608  *      unit    -  (IN) StrataSwitch Unit #.
   2609  *      id      -  (IN) Time interface identifier
   2610  *      drift   - (OUT) Time interface  drift 
   2611  * Returns:
   2612  *      BCM_E_NONE
   2613  *      BCM_E_XXX
   2614  */
   2615 STATIC int 
   2616 _bcm_esw_time_interface_drift_get(int unit, bcm_time_if_t id,
   2617                                   bcm_time_spec_t *drift)
   2618 {
   2619     uint32 regval, val, ns;
   2620 
   2621 #if defined(BCM_TIME_V3_SUPPORT)
   2622     /* Not supported in 3rd generation time arch */
   2623     if (soc_feature(unit, soc_feature_time_v3)) {
   2624         return BCM_E_UNAVAIL;
   2625     }
   2626 #endif /* defined(BCM_TIME_V3_SUPPORT) */
   2627 
   2628 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   2629     /* Katana does not support clock drift */
   2630     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   2631         SOC_IS_TD2_TT2(unit)) {
   2632         return BCM_E_UNAVAIL;
   2633     }
   2634 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   2635 
   2636 
   2637     READ_CMIC_BS_DRIFT_RATEr(unit, &regval);
   2638     val = soc_reg_field_get(unit, CMIC_BS_DRIFT_RATEr, regval, FRAC_NSf);
   2639 
   2640     ns = (val / 8);
   2641 
   2642     drift->nanoseconds = (ns > TIME_DRIFT_MAX) ? TIME_DRIFT_MAX : ns;
   2643 
   2644     drift->isnegative = soc_reg_field_get(unit, CMIC_BS_DRIFT_RATEr, 
   2645                                           regval, SIGNf);
   2646     return (BCM_E_NONE);
   2647 }
   2648 
   2649 #if defined(BCM_TIME_MANAGED_BROADSYNC)
   2650 /*
   2651  * Function:
   2652  *      _bcm_esw_time_interface_ref_clock_get
   2653  * Purpose:
   2654  *      Internal routine to read ref clock divisor 
   2655  * Parameters:
   2656  *      unit    -  (IN) StrataSwitch Unit #.
   2657  *      id      -  (IN) Time interface identifier
   2658  *      divisor - (OUT) Time interface  ref clock resolution 
   2659  * Returns:
   2660  *      BCM_E_NONE
   2661  *      BCM_E_XXX
   2662  */
   2663 STATIC int 
   2664 _bcm_esw_time_interface_ref_clock_get(int unit, bcm_time_if_t id,
   2665                                   int *clk_resolution)
   2666 {
   2667     uint32 regval, val, hdiv = 0;
   2668 
   2669 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   2670     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   2671         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   2672             READ_NS_BROADSYNC_REF_CLK_GEN_CTRLr(unit, &regval); 
   2673             val = soc_reg_field_get(unit, NS_BROADSYNC_REF_CLK_GEN_CTRLr, 
   2674                                     regval, ENABLEf);
   2675             hdiv = soc_reg_field_get(unit, NS_BROADSYNC_REF_CLK_GEN_CTRLr, 
   2676                                      regval, DIVISORf);
   2677         } else {
   2678             READ_CMIC_BROADSYNC_REF_CLK_GEN_CTRLr(unit, &regval); 
   2679             val = soc_reg_field_get(unit, CMIC_BROADSYNC_REF_CLK_GEN_CTRLr, 
   2680                                     regval, ENABLEf);
   2681             hdiv = soc_reg_field_get(unit, CMIC_BROADSYNC_REF_CLK_GEN_CTRLr, 
   2682                                      regval, DIVISORf);
   2683         }
   2684     } else
   2685 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   2686     {
   2687         READ_CMIC_BS_REF_CLK_GEN_CTRLr(unit, &regval); 
   2688         val = soc_reg_field_get(unit, CMIC_BS_REF_CLK_GEN_CTRLr, regval, 
   2689                                 ENABLEf);
   2690         hdiv = soc_reg_field_get(unit, CMIC_BS_REF_CLK_GEN_CTRLr, regval, 
   2691                                  DIVISORf);
   2692     }
   2693 
   2694     if (val) {
   2695         /* Divisor is half period for reference clock */ 
   2696         *clk_resolution = TIME_TS_CLK_FREQUENCY_40NS / (hdiv * 2);
   2697     } else {
   2698         *clk_resolution = 0;
   2699     }
   2700 
   2701     return (BCM_E_NONE);
   2702 }
   2703 #endif /*BCM_TIME_MANAGED_BROADSYNC */
   2704 
   2705 /*
   2706  * Function:
   2707  *      _bcm_esw_time_interface_accuracy_get
   2708  * Purpose:
   2709  *      Internal routine to read HW accuracy value and convert it into 
   2710  *      bcm_time_spec_t structure 
   2711  * Parameters:
   2712  *      unit        -  (IN) StrataSwitch Unit #.
   2713  *      id          -  (IN) Time interface identifier
   2714  *      accuracy    - (OUT) Time interface  accuracy 
   2715  * Returns:
   2716  *      BCM_E_NONE
   2717  *      BCM_E_XXX
   2718  */
   2719 STATIC int 
   2720 _bcm_esw_time_interface_accuracy_get(int unit, bcm_time_if_t id,
   2721                                      bcm_time_spec_t *accuracy)
   2722 {
   2723     uint32  regval, val; 
   2724 
   2725 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   2726     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   2727         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   2728             READ_NS_BS0_BS_OUTPUT_TIME_0r(unit, &regval);
   2729             val = soc_reg_field_get(unit, NS_BS0_BS_OUTPUT_TIME_0r, regval, ACCURACYf);
   2730         } else {
   2731             READ_CMIC_BS0_OUTPUT_TIME_0r(unit, &regval);
   2732             val = soc_reg_field_get(unit, CMIC_BS0_OUTPUT_TIME_0r, regval, ACCURACYf);
   2733         }
   2734     } else
   2735 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   2736 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   2737     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   2738         SOC_IS_TD2_TT2(unit)) {
   2739         READ_CMIC_BS_OUTPUT_TIME_0r(unit, &regval);
   2740         val = soc_reg_field_get(unit, CMIC_BS_OUTPUT_TIME_0r, regval, ACCURACYf);
   2741     } else 
   2742 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   2743     {
   2744         READ_CMIC_BS_CONFIGr(unit, &regval);
   2745         val = soc_reg_field_get(unit, CMIC_BS_CONFIGr, regval, ACCURACYf);
   2746     }
   2747 
   2748     return _bcm_esw_time_accuracy_parse(unit, val, accuracy);
   2749 }
   2750 
   2751 /*
   2752  * Function:
   2753  *      _bcm_esw_time_interface_get
   2754  * Purpose:
   2755  *      Internal routine to get a time sync interface by id
   2756  * Parameters:
   2757  *      unit -  (IN) StrataSwitch Unit #.
   2758  *      id   -  (IN) Time interface identifier
   2759  *      intf - (IN/OUT) Time Sync Interface to get
   2760  * Returns:
   2761  *      BCM_E_NONE
   2762  *      BCM_E_XXX
   2763  */
   2764 STATIC int 
   2765 _bcm_esw_time_interface_get(int unit, bcm_time_if_t id, bcm_time_interface_t *intf)
   2766 {
   2767     uint32                  regval;
   2768     bcm_time_interface_t    *intf_ptr;
   2769     uint32                  orig_flags;
   2770 
   2771     intf_ptr = TIME_INTERFACE(unit, id);
   2772     orig_flags = intf_ptr->flags;
   2773 
   2774     intf_ptr->flags = intf->flags;
   2775     intf_ptr->id = id;
   2776     if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   2777         READ_NS_BS0_BS_CONFIGr(unit, &regval);
   2778         /* Update output flags */
   2779         if (TIME_MODE_INPUT == soc_reg_field_get(unit, NS_BS0_BS_CONFIGr, 
   2780                                                  regval, MODEf)) {
   2781             intf_ptr->flags |= BCM_TIME_INPUT;
   2782         } else {
   2783             intf_ptr->flags &= ~BCM_TIME_INPUT;
   2784         }
   2785     } else {
   2786         READ_CMIC_BS_CONFIGr(unit, &regval);
   2787 
   2788         /* Update output flags */
   2789         if (TIME_MODE_INPUT == soc_reg_field_get(unit, CMIC_BS_CONFIGr, 
   2790                                                  regval, MODEf)) {
   2791             intf_ptr->flags |= BCM_TIME_INPUT;
   2792         } else {
   2793             intf_ptr->flags &= ~BCM_TIME_INPUT;
   2794         }
   2795     }
   2796 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   2797     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   2798         SOC_IS_TD2_TT2(unit)) {
   2799        if (soc_reg_field_get(unit, CMIC_BS_CONFIGr, 
   2800                              regval, BS_CLK_OUTPUT_ENABLEf)) {
   2801             intf_ptr->flags |= BCM_TIME_ENABLE;
   2802         } else {
   2803             intf_ptr->flags &= ~BCM_TIME_ENABLE;
   2804         }
   2805 
   2806         READ_CMIC_BS_OUTPUT_TIME_0r(unit, &regval);
   2807         if (soc_reg_field_get(unit, CMIC_BS_OUTPUT_TIME_0r,
   2808                               regval, LOCKf)) {
   2809             intf_ptr->flags |= BCM_TIME_LOCKED;
   2810         } else {
   2811             intf_ptr->flags &= ~BCM_TIME_LOCKED;
   2812         }
   2813     } else
   2814 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   2815     {
   2816         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   2817             if (soc_reg_field_get(unit, NS_BS0_BS_CONFIGr, regval, ENABLEf)) {
   2818                 intf_ptr->flags |= BCM_TIME_ENABLE;
   2819             } else {
   2820                 intf_ptr->flags &= ~BCM_TIME_ENABLE;
   2821             }
   2822             if (soc_reg_field_get(unit, NS_BS0_BS_CONFIGr, regval, LOCKf)) {
   2823                 intf_ptr->flags |= BCM_TIME_LOCKED;
   2824             } else {
   2825                 intf_ptr->flags &= ~BCM_TIME_LOCKED;
   2826             }
   2827         } else {
   2828             if (soc_reg_field_get(unit, CMIC_BS_CONFIGr, regval, ENABLEf)) {
   2829                 intf_ptr->flags |= BCM_TIME_ENABLE;
   2830             } else {
   2831                 intf_ptr->flags &= ~BCM_TIME_ENABLE;
   2832             }
   2833             if (soc_reg_field_get(unit, CMIC_BS_CONFIGr, regval, LOCKf)) {
   2834                 intf_ptr->flags |= BCM_TIME_LOCKED;
   2835             } else {
   2836                 intf_ptr->flags &= ~BCM_TIME_LOCKED;
   2837             }
   2838         }
   2839     }
   2840 
   2841 #if defined(INCLUDE_PTP)
   2842     if ((orig_flags & BCM_TIME_SYNC_STAMPER) && 
   2843             (_bcm_ptp_running(unit) == BCM_E_NONE)) {
   2844         intf_ptr->flags = orig_flags;
   2845         *intf = *intf_ptr;
   2846         return BCM_E_NONE;
   2847     }
   2848 #endif /* INCLUDE_PTP */
   2849 
   2850     if (intf->flags & BCM_TIME_ACCURACY) {
   2851         BCM_IF_ERROR_RETURN(
   2852             _bcm_esw_time_interface_accuracy_get(unit, id, 
   2853                                                  &(intf_ptr->accuracy)));
   2854     }
   2855 
   2856     if (intf->flags & BCM_TIME_OFFSET) {
   2857         if (orig_flags & BCM_TIME_SYNC_STAMPER) {
   2858             
   2859         } else {
   2860             /* Get value from hardware */
   2861             BCM_IF_ERROR_RETURN(
   2862                 _bcm_esw_time_interface_offset_get(unit, id, &(intf_ptr->offset)));
   2863         }
   2864     }
   2865 
   2866     if (intf->flags & BCM_TIME_DRIFT) {
   2867         if (orig_flags & BCM_TIME_SYNC_STAMPER) {
   2868             
   2869         } else {
   2870             /* Get value from hardware */
   2871             BCM_IF_ERROR_RETURN(
   2872                 _bcm_esw_time_interface_drift_get(unit, id, &(intf_ptr->drift)));
   2873         }
   2874     }
   2875 
   2876 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   2877     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   2878         SOC_IS_TD2_TT2(unit)) {
   2879         if (intf->flags & BCM_TIME_REF_CLOCK) {
   2880             BCM_IF_ERROR_RETURN(
   2881                 _bcm_esw_time_interface_ref_clock_get(unit, id,
   2882                                             &(intf_ptr->clk_resolution)));
   2883         }
   2884     }
   2885 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   2886 
   2887     if (orig_flags & BCM_TIME_SYNC_STAMPER) {
   2888         intf_ptr->flags = orig_flags;
   2889     }
   2890 
   2891     *intf = *(TIME_INTERFACE(unit, id));
   2892 
   2893     return (BCM_E_NONE);
   2894 }
   2895 
   2896 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   2897 STATIC int 
   2898 _bcm_esw_time_interface_dual_bs_get(int unit, bcm_time_if_t id, bcm_time_interface_t *intf)
   2899 {
   2900     uint32                  regval;
   2901     bcm_time_interface_t    *intf_ptr;
   2902     uint32                  orig_flags;
   2903 
   2904     /* Feature unavailable on devices without BroadSync support. */
   2905     if (soc_feature(unit, soc_feature_time_v3_no_bs)) {
   2906         return BCM_E_UNAVAIL;
   2907     }
   2908 
   2909     intf_ptr = TIME_INTERFACE(unit, id);
   2910     orig_flags = intf_ptr->flags;
   2911     intf_ptr->flags = intf->flags;
   2912     intf_ptr->id = id;
   2913     if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   2914         READ_NS_BS0_BS_CONFIGr(unit, &regval);
   2915 
   2916         /* Update output flags */
   2917         if (TIME_MODE_INPUT == soc_reg_field_get(unit, NS_BS0_BS_CONFIGr, 
   2918                                                  regval, MODEf)) {
   2919             intf_ptr->flags |= BCM_TIME_INPUT;
   2920         } else {
   2921             intf_ptr->flags &= ~BCM_TIME_INPUT;
   2922         }
   2923 
   2924        if (soc_reg_field_get(unit, NS_BS0_BS_CONFIGr, 
   2925                              regval, BS_CLK_OUTPUT_ENABLEf)) {
   2926             intf_ptr->flags |= BCM_TIME_ENABLE;
   2927         } else {
   2928             intf_ptr->flags &= ~BCM_TIME_ENABLE;
   2929         }
   2930 
   2931         READ_NS_BS0_BS_OUTPUT_TIME_0r(unit, &regval);
   2932         if (soc_reg_field_get(unit, NS_BS0_BS_OUTPUT_TIME_0r,
   2933                               regval, LOCKf)) {
   2934             intf_ptr->flags |= BCM_TIME_LOCKED;
   2935         } else {
   2936             intf_ptr->flags &= ~BCM_TIME_LOCKED;
   2937         }
   2938     } else {
   2939         READ_CMIC_BS0_CONFIGr(unit, &regval);
   2940 
   2941         /* Update output flags */
   2942         if (TIME_MODE_INPUT == soc_reg_field_get(unit, CMIC_BS0_CONFIGr, 
   2943                                                  regval, MODEf)) {
   2944             intf_ptr->flags |= BCM_TIME_INPUT;
   2945         } else {
   2946             intf_ptr->flags &= ~BCM_TIME_INPUT;
   2947         }
   2948 
   2949        if (soc_reg_field_get(unit, CMIC_BS0_CONFIGr, 
   2950                              regval, BS_CLK_OUTPUT_ENABLEf)) {
   2951             intf_ptr->flags |= BCM_TIME_ENABLE;
   2952         } else {
   2953             intf_ptr->flags &= ~BCM_TIME_ENABLE;
   2954         }
   2955 
   2956         READ_CMIC_BS0_OUTPUT_TIME_0r(unit, &regval);
   2957         if (soc_reg_field_get(unit, CMIC_BS0_OUTPUT_TIME_0r,
   2958                               regval, LOCKf)) {
   2959             intf_ptr->flags |= BCM_TIME_LOCKED;
   2960         } else {
   2961             intf_ptr->flags &= ~BCM_TIME_LOCKED;
   2962         }
   2963     }
   2964 
   2965 
   2966 #if defined(INCLUDE_PTP)
   2967     if (_bcm_ptp_running(unit) == BCM_E_NONE) {
   2968         intf_ptr->flags = orig_flags;
   2969         *intf = *intf_ptr;
   2970         return BCM_E_NONE;
   2971     }
   2972 #endif /* INCLUDE_PTP */
   2973 
   2974     if (intf->flags & BCM_TIME_ACCURACY) {
   2975         BCM_IF_ERROR_RETURN(
   2976             _bcm_esw_time_interface_accuracy_get(unit, id, 
   2977                                                  &(intf_ptr->accuracy)));
   2978     }
   2979 
   2980     if (intf->flags & BCM_TIME_OFFSET) {
   2981         if (orig_flags & BCM_TIME_SYNC_STAMPER) {
   2982             
   2983         } else {
   2984             /* Get value from hardware */
   2985             BCM_IF_ERROR_RETURN(
   2986                 _bcm_esw_time_interface_offset_get(unit, id, &(intf_ptr->offset)));
   2987         }
   2988     }
   2989 
   2990     if (intf->flags & BCM_TIME_DRIFT) {
   2991         if (orig_flags & BCM_TIME_SYNC_STAMPER) {
   2992             
   2993         } else {
   2994             /* Get value from hardware */
   2995             BCM_IF_ERROR_RETURN(
   2996                 _bcm_esw_time_interface_drift_get(unit, id, &(intf_ptr->drift)));
   2997         }
   2998     }
   2999 
   3000     if (intf->flags & BCM_TIME_REF_CLOCK) {
   3001         BCM_IF_ERROR_RETURN(
   3002             _bcm_esw_time_interface_ref_clock_get(unit, id,
   3003                                         &(intf_ptr->clk_resolution)));
   3004     }
   3005 
   3006     if (orig_flags & BCM_TIME_SYNC_STAMPER) {
   3007         intf_ptr->flags = orig_flags;
   3008     }
   3009 
   3010     *intf = *(TIME_INTERFACE(unit, id));
   3011 
   3012     return (BCM_E_NONE);
   3013 }
   3014 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   3015 
   3016 /*
   3017  * Function:
   3018  *      _bcm_esw_time_hw_interrupt_dflt
   3019  * Purpose:
   3020  *      Default handler for broadsync heartbeat interrupt
   3021  * Parameters:  
   3022  *      unit - StrataSwitch unit #.
   3023  * Returns:
   3024  *      Nothing
   3025  */
   3026 
   3027 STATIC void
   3028 _bcm_esw_time_hw_interrupt_dflt(int unit)
   3029 {
   3030     uint32  regval;
   3031 
   3032     /* Due to HW constrains we need to reinable the interrupt on every rising */
   3033     /* edge and update the capture mode */
   3034 
   3035 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   3036     uint32  intr, mode;
   3037 
   3038     if (soc_feature(unit, soc_feature_time_v3)) {
   3039         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   3040             
   3041             return;
   3042         } else {
   3043             /* Read original values */
   3044             READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &mode);
   3045             READ_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, &regval);
   3046             READ_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, &intr);
   3047 
   3048             /* Disable all */
   3049             WRITE_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, 0);
   3050             WRITE_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, 0);
   3051             WRITE_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, 0);
   3052 
   3053             /* Enable with the original settings */
   3054             WRITE_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, intr);
   3055             WRITE_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, regval);
   3056             WRITE_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, mode);
   3057         }
   3058 
   3059     } else
   3060 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   3061 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   3062     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   3063         SOC_IS_TD2_TT2(unit)) {
   3064         READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
   3065         WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, 0);
   3066         WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, regval);
   3067     } else
   3068 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   3069     {
   3070         READ_CMIC_BS_CAPTURE_CTRLr(unit, &regval);
   3071         WRITE_CMIC_BS_CAPTURE_CTRLr(unit, 0);
   3072         WRITE_CMIC_BS_CAPTURE_CTRLr(unit, regval);
   3073     }
   3074     return;
   3075 }
   3076 
   3077 /*
   3078  * Function:
   3079  *      _bcm_esw_time_hw_interrupt
   3080  * Purpose:
   3081  *      Handles broadsync heartbeat interrupt
   3082  * Parameters:  
   3083  *      unit - StrataSwitch unit #.
   3084  * Returns:
   3085  *      Nothing
   3086  */
   3087 STATIC void
   3088 _bcm_esw_time_hw_interrupt(int unit)
   3089 {
   3090     void                    *u_data; 
   3091     bcm_time_heartbeat_cb   u_cb;
   3092     int                     idx;    /* interface itterator */
   3093     bcm_time_capture_t      time;
   3094 
   3095     for (idx = 0; idx < NUM_TIME_INTERFACE(unit); idx++) {
   3096         if (NULL != TIME_INTERFACE(unit, idx) &&
   3097             NULL != TIME_INTERFACE_CONFIG(unit,idx).user_cb) {
   3098             u_cb = TIME_INTERFACE_CONFIG(unit,idx).user_cb->heartbeat_cb;
   3099             u_data = TIME_INTERFACE_CONFIG(unit,idx).user_cb->user_data;
   3100             _bcm_esw_time_capture_counter_read(unit, idx, &time);
   3101             if (NULL != u_cb) {
   3102                 u_cb(unit, idx, &time, u_data);
   3103             }
   3104         }
   3105     }
   3106 
   3107     _bcm_esw_time_hw_interrupt_dflt(unit);
   3108 
   3109     return;
   3110 }
   3111 
   3112 /****************************************************************************/
   3113 /*                      API functions implementation                        */
   3114 /****************************************************************************/
   3115 
   3116 /*
   3117  * Function:
   3118  *      bcm_esw_time_init
   3119  * Purpose:
   3120  *      Initialize time module 
   3121  * Parameters:
   3122  *      unit - (IN) StrataSwitch Unit #.
   3123  * Returns:
   3124  *      BCM_E_NONE
   3125  *      BCM_E_XXX
   3126  */
   3127 int 
   3128 bcm_esw_time_init (int unit)
   3129 {
   3130     _bcm_time_config_p      time_cfg_ptr;   /* Pointer to Time module config */
   3131     bcm_time_interface_t    *intf;          /* Time interfaces iterator.     */
   3132     int                     alloc_sz;       /* Memory allocation size.       */
   3133     int                     idx;            /* Time interface array iterator */
   3134     int                     rv;             /* Return Value                  */
   3135     soc_control_t *soc = SOC_CONTROL(unit); /* Soc control structure         */
   3136 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   3137         uint32_t    regVal = 0;
   3138         uint32_t    eventId;
   3139 #endif
   3140 
   3141     /* Check if time feature is supported on a device */
   3142     if (!soc_feature(unit, soc_feature_time_support)) {
   3143         return (BCM_E_UNAVAIL);
   3144     }
   3145 
   3146     /* If already initialized then deinitialize time module */
   3147     if (TIME_INIT(unit)) {
   3148         _bcm_esw_time_deinit(unit, &TIME_CONFIG(unit));
   3149     }
   3150 
   3151     /* Allocate time config structure. */
   3152     alloc_sz = sizeof(_bcm_time_config_t);
   3153     time_cfg_ptr = sal_alloc(alloc_sz, "Time module");
   3154     if (NULL == time_cfg_ptr) {
   3155         return (BCM_E_MEMORY);
   3156     }
   3157     sal_memset(time_cfg_ptr, 0, alloc_sz);
   3158 
   3159     /* Currently only one interface per unit */
   3160     time_cfg_ptr->intf_count = NUM_TIME_INTERFACE(unit); 
   3161 
   3162     /* Allocate memory for all time interfaces, supported */
   3163     alloc_sz = time_cfg_ptr->intf_count * sizeof(_bcm_time_interface_config_t);
   3164     time_cfg_ptr->intf_arr = sal_alloc(alloc_sz, "Time Interfaces");
   3165     if (NULL == time_cfg_ptr->intf_arr) {
   3166         _bcm_esw_time_deinit(unit, &time_cfg_ptr);
   3167         return (BCM_E_MEMORY);
   3168     }
   3169     sal_memset(time_cfg_ptr->intf_arr, 0, alloc_sz);
   3170     for (idx = 0; idx < time_cfg_ptr->intf_count; idx++) {
   3171         intf = &time_cfg_ptr->intf_arr[idx].time_interface;
   3172         intf->id = idx;
   3173     }
   3174 
   3175     /* For each time interface allocate memory for tuser_cb */
   3176     alloc_sz = sizeof(_bcm_time_user_cb_t);
   3177     for (idx = 0; idx < NUM_TIME_INTERFACE(unit); idx++) {
   3178         time_cfg_ptr->intf_arr[idx].user_cb = 
   3179             sal_alloc(alloc_sz, "Time Interface User Callback");
   3180         if (NULL == time_cfg_ptr->intf_arr[idx].user_cb) {
   3181             _bcm_esw_time_deinit(unit,  &time_cfg_ptr);
   3182             return (BCM_E_MEMORY);
   3183         }
   3184         sal_memset(time_cfg_ptr->intf_arr[idx].user_cb, 0, alloc_sz);
   3185     }
   3186 
   3187     /* Interrupt handling function initialization */
   3188     soc->time_call_ref_count = 0;
   3189     soc->soc_time_callout = NULL;
   3190 
   3191     /* Create protection mutex. */
   3192     time_cfg_ptr->mutex = sal_mutex_create("Time mutex");
   3193     if (NULL == time_cfg_ptr->mutex) {
   3194         _bcm_esw_time_deinit(unit, &time_cfg_ptr);
   3195         return (BCM_E_MEMORY);
   3196     } 
   3197 
   3198     sal_mutex_take(time_cfg_ptr->mutex, sal_mutex_FOREVER);
   3199 
   3200     TIME_CONFIG(unit) = time_cfg_ptr;
   3201 
   3202 #ifdef BCM_WARM_BOOT_SUPPORT
   3203     _bcm_time_scache_alloc(unit);
   3204 #endif
   3205 
   3206     /* Clear memories/registers on Cold boot only */
   3207     if (!SOC_WARM_BOOT(unit) &&
   3208         _bcm_esw_time_hitless_reset(unit, idx) != BCM_E_NONE) {
   3209     for (idx = 0; idx < NUM_TIME_INTERFACE(unit); idx++) {
   3210         rv  = _bcm_esw_time_hw_clear(unit, idx);
   3211         if (BCM_FAILURE(rv)) {
   3212             TIME_UNLOCK(unit);
   3213             _bcm_esw_time_deinit(unit, &time_cfg_ptr);
   3214             TIME_CONFIG(unit) = NULL;
   3215             return (BCM_E_MEMORY);
   3216         }
   3217     }
   3218     } else {
   3219         /* If Warm boot reinitialize module based on HW state */
   3220 #ifdef BCM_WARM_BOOT_SUPPORT
   3221         for (idx = 0; idx < NUM_TIME_INTERFACE(unit); idx++) {
   3222             rv = _bcm_esw_time_reinit(unit, idx);
   3223             if (BCM_FAILURE(rv)) {
   3224                 TIME_UNLOCK(unit);
   3225                 _bcm_esw_time_deinit(unit, &time_cfg_ptr);
   3226                 TIME_CONFIG(unit) = NULL;
   3227                 return (rv);
   3228             }
   3229         }
   3230 
   3231 #endif /* BCM_WARM_BOOT_SUPPORT */
   3232     }
   3233 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   3234     if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   3235         /* Set the event ids for Nanosync, both miscellaneous and port events
   3236          * i.e, NS_TIMESYNC_TS_EVENT_FWD_CFG - 150 Numels
   3237          *      NS_TIMESYNC_MAPPER_FWD_CFG - 128 Numels
   3238          *
   3239          * EventId 0 to 191 for port events for 64-ports
   3240          * Events could be RXCDR/RXSOF, ROE, TXSOF/TXPI
   3241          * 0, 2, 4...126 -> RXCDR/RXSOF
   3242          * 1, 3, 5...127 -> ROE
   3243          * 128, 129, 130..191 -> TXSOF/TXPI
   3244          */
   3245 
   3246         /* Set the Miscellaneous event id's */
   3247         eventId = 192;
   3248         for (idx = 128; idx < 150; idx++) {
   3249             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, &regVal);
   3250             soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal, EVENT_IDf, eventId);
   3251             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, regVal);
   3252             eventId++;
   3253         }
   3254 
   3255         
   3256     }
   3257 
   3258     /* Check availability of TS FIFO to host */
   3259     tsfifo_flag = soc_property_get(unit, "tsfifo_available_flag", 0);
   3260 #endif
   3261 
   3262     TIME_UNLOCK(unit);
   3263 
   3264     return (BCM_E_NONE);
   3265 }
   3266 
   3267 /*
   3268  * Function:
   3269  *      bcm_esw_time_deinit
   3270  * Purpose:
   3271  *      Uninitialize time module 
   3272  * Parameters:
   3273  *      unit - (IN) StrataSwitch Unit #.
   3274  * Returns:
   3275  *      BCM_E_NONE
   3276  *      BCM_E_XXX
   3277  */
   3278 int 
   3279 bcm_esw_time_deinit (int unit)
   3280 {
   3281     /* Chek if time feature is supported on a device */
   3282     if (!soc_feature(unit, soc_feature_time_support)) {
   3283         return (BCM_E_UNAVAIL);
   3284     }
   3285 
   3286     if (0 == TIME_INIT(unit)) {
   3287         return (BCM_E_INIT);
   3288     }
   3289 
   3290     return _bcm_esw_time_deinit(unit, &TIME_CONFIG(unit));
   3291 }
   3292 
   3293 static int _bcm_time_interface_traverse_cb(int unit,
   3294                             bcm_time_interface_t *intf, void *user_data)
   3295 {
   3296     uint8 *ptr = (uint8 *)user_data;
   3297     if (intf->flags & BCM_TIME_SYNC_STAMPER) {
   3298         *ptr = 1;
   3299      } else {
   3300         *ptr = 0;
   3301      }
   3302     return BCM_E_NONE;
   3303 }
   3304 
   3305 /*
   3306  * Function:
   3307  *      bcm_esw_time_bs_log_config_set
   3308  * Purpose:
   3309  *      Configure Broadsync logging
   3310  * Parameters:
   3311  *      unit - (IN) StrataSwitch Unit #.
   3312  * Returns:
   3313  *      BCM_E_NONE
   3314  *      BCM_E_XXX
   3315  */
   3316 int
   3317 bcm_esw_time_bs_log_configure_set (int unit, bcm_time_bs_log_cfg_t bs_log_cfg)
   3318 {
   3319     uint8 bs_initialized=0;
   3320 
   3321     /* Chek if time feature is supported on a device */
   3322     if (!soc_feature(unit, soc_feature_time_support)) {
   3323         return (BCM_E_UNAVAIL);
   3324     }
   3325 
   3326     if (!SOC_UNIT_VALID(unit)) {
   3327         return BCM_E_UNIT;
   3328     }
   3329 
   3330     bcm_esw_time_interface_traverse(unit, _bcm_time_interface_traverse_cb,
   3331                                         (void*)&bs_initialized);
   3332     if (!bs_initialized) {
   3333         return BCM_E_INIT;
   3334     }
   3335 
   3336     _bcm_time_bs_debug(bs_log_cfg.debug_mask);
   3337 
   3338     return _bcm_time_bs_log_configure(unit, bs_log_cfg.debug_mask,
   3339                     bs_log_cfg.udp_log_mask, bs_log_cfg.src_mac,
   3340                     bs_log_cfg.dest_mac, bs_log_cfg.tpid, bs_log_cfg.vid,
   3341                     bs_log_cfg.ttl, bs_log_cfg.src_addr, bs_log_cfg.dest_addr,
   3342                     bs_log_cfg.udp_port);
   3343 }
   3344 
   3345 /*
   3346  * Function:
   3347  *      bcm_esw_time_bs_log_config_get
   3348  * Purpose:
   3349  *      Configure Broadsync logging
   3350  * Parameters:
   3351  *      unit - (IN) StrataSwitch Unit #.
   3352  * Returns:
   3353  *      BCM_E_NONE
   3354  *      BCM_E_XXX
   3355  */
   3356 int
   3357 bcm_esw_time_bs_log_configure_get (int unit, bcm_time_bs_log_cfg_t *bs_log_cfg)
   3358 {
   3359     uint8 bs_initialized=0;
   3360 
   3361     /* Chek if time feature is supported on a device */
   3362     if (!soc_feature(unit, soc_feature_time_support)) {
   3363         return (BCM_E_UNAVAIL);
   3364     }
   3365 
   3366     if (!SOC_UNIT_VALID(unit)) {
   3367         return BCM_E_UNIT;
   3368     }
   3369 
   3370     bcm_esw_time_interface_traverse(unit, _bcm_time_interface_traverse_cb,
   3371                                         (void*)&bs_initialized);
   3372     if (!bs_initialized) {
   3373         return BCM_E_INIT;
   3374     }
   3375 
   3376     return _bcm_time_bs_log_configure_get(unit, bs_log_cfg);
   3377 
   3378 }
   3379 
   3380 /*
   3381  * Function:
   3382  *      bcm_esw_time_interface_add
   3383  * Purpose:
   3384  *      Adding a time sync interface to a specified unit 
   3385  * Parameters:
   3386  *      unit - (IN) StrataSwitch Unit #.
   3387  *      intf - (IN/OUT) Time Sync Interface
   3388  * Returns:
   3389  *      BCM_E_NONE
   3390  *      BCM_E_XXX
   3391  */
   3392 int 
   3393 bcm_esw_time_interface_add (int unit, bcm_time_interface_t *intf)
   3394 {
   3395     int rv = BCM_E_NONE; /* Return value */
   3396 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
   3397     defined(BCM_HELIX4_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \
   3398     defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_SABER2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   3399     int replacing = 0;
   3400     int reset_hardware = 0;
   3401 #endif
   3402 
   3403     if (!SOC_UNIT_VALID(unit)) {
   3404         return BCM_E_UNIT;
   3405     }
   3406 
   3407     /* Check if time feature is supported on a device */
   3408     if (!soc_feature(unit, soc_feature_time_support)) {
   3409         return (BCM_E_UNAVAIL);
   3410     }
   3411 
   3412     BCM_IF_ERROR_RETURN(
   3413         _bcm_esw_time_interface_input_validate(unit, intf));
   3414 
   3415     if (TIME_CONFIG(unit) == NULL) {
   3416         return (BCM_E_INIT);
   3417     }
   3418 
   3419     TIME_LOCK(unit);
   3420     if (intf->flags & BCM_TIME_WITH_ID) {
   3421         /* If interface already been in use */
   3422         if (0 != TIME_INTERFACE_CONFIG_REF_COUNT(unit, intf->id)) {
   3423             if (0 == (intf->flags & BCM_TIME_REPLACE)) {
   3424                 TIME_UNLOCK(unit);
   3425                 return BCM_E_EXISTS;
   3426             }
   3427 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
   3428     defined(BCM_HELIX4_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \
   3429     defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_SABER2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   3430             replacing = 1;
   3431 #endif
   3432         } else {
   3433             TIME_INTERFACE_CONFIG_REF_COUNT(unit, intf->id) = 1;
   3434         }
   3435     } else {
   3436         rv = _bcm_esw_time_interface_allocate_id(unit, &(intf->id));
   3437         if (BCM_FAILURE(rv)) {
   3438             TIME_UNLOCK(unit);
   3439             return rv;
   3440         }
   3441     }
   3442 
   3443 #if defined(BCM_TIME_MANAGED_BROADSYNC)
   3444     if (intf->flags & BCM_TIME_SYNC_STAMPER) {
   3445 #if defined(INCLUDE_PTP)
   3446         if (_bcm_ptp_running(unit) == BCM_E_NONE) {
   3447             /* Unit is running PTP, so let PTP firmware know if timecodes should be output */
   3448             int tc_output_enable = 0;
   3449             int locked = 0;
   3450             int include_servo_offset = 0;
   3451             int needs_restart = 1;
   3452             /* if either enable or "ref_clock" is changed, we'll need to stop and/or restart */
   3453             uint32 restart_mask = (BCM_TIME_ENABLE | BCM_TIME_INPUT | BCM_TIME_REF_CLOCK);
   3454             unsigned two_cycle_delay_usec = 500;  /* two cycles @ 4KHz */
   3455 
   3456             if ((intf->flags & BCM_TIME_ENABLE) &&
   3457                 !(intf->flags & BCM_TIME_INPUT)) {
   3458                 tc_output_enable = 1;
   3459             }
   3460             if (intf->flags & BCM_TIME_REF_CLOCK) {
   3461                 include_servo_offset = 1;
   3462             }
   3463             if (intf->flags & BCM_TIME_LOCKED) {
   3464                 locked = 1;
   3465             }
   3466 
   3467             if (replacing) {
   3468                 /* clear 'needs_restart' if the only change is to the LOCK status */
   3469                 needs_restart = ((intf->flags & restart_mask) !=
   3470                                  ((TIME_INTERFACE(unit, intf->id))->flags & restart_mask));
   3471             }
   3472 
   3473 #if defined(BCM_CMICM_SUPPORT)
   3474             if (soc_feature(unit, soc_feature_cmicm) && /* CMICM, not iProc */
   3475                 !soc_feature(unit, soc_feature_iproc)) {
   3476                 if (needs_restart) {
   3477                     soc_reg_field32_modify(unit, CMIC_BS_CONFIGr, REG_PORT_ANY, BS_TC_OUTPUT_ENABLEf, 0);
   3478                     /* use "lock" field as a signal on startup that the servo offset should be included */
   3479                     soc_reg_field32_modify(unit, CMIC_BS_OUTPUT_TIME_0r, REG_PORT_ANY, LOCKf, include_servo_offset);
   3480 
   3481                     sal_usleep(two_cycle_delay_usec);
   3482 
   3483                     soc_reg_field32_modify(unit, CMIC_BS_CONFIGr, REG_PORT_ANY, BS_TC_OUTPUT_ENABLEf, tc_output_enable);
   3484 
   3485                     sal_usleep(two_cycle_delay_usec);
   3486                 }
   3487                 soc_reg_field32_modify(unit, CMIC_BS_OUTPUT_TIME_0r, REG_PORT_ANY, LOCKf, locked);
   3488             } else
   3489 #endif /* BCM_CMICM_SUPPORT */
   3490 #if defined (BCM_IPROC_SUPPORT)
   3491             {
   3492                 if (soc_feature(unit, soc_feature_iproc)) {  /* IPROC/CMICD */
   3493                     if (needs_restart) {
   3494                         soc_reg_field32_modify(unit, CMIC_BS0_CONFIGr,
   3495                                                REG_PORT_ANY,
   3496                                                BS_TC_OUTPUT_ENABLEf, 0);
   3497                         /* use "lock" field as a signal on startup that the servo offset should be included */
   3498                         soc_reg_field32_modify(unit, CMIC_BS0_OUTPUT_TIME_0r,
   3499                                                REG_PORT_ANY,
   3500                                                LOCKf, include_servo_offset);
   3501 
   3502                         sal_usleep(two_cycle_delay_usec);
   3503 
   3504                         soc_reg_field32_modify(unit, CMIC_BS0_CONFIGr,
   3505                                                REG_PORT_ANY,
   3506                                                BS_TC_OUTPUT_ENABLEf, tc_output_enable);
   3507 
   3508                         sal_usleep(two_cycle_delay_usec);
   3509                     }
   3510                     soc_reg_field32_modify(unit, CMIC_BS0_OUTPUT_TIME_0r,
   3511                                            REG_PORT_ANY,
   3512                                            LOCKf, locked);
   3513                 }
   3514             }
   3515 #endif /* BCM_IPROC_SUPPORT */
   3516 #if defined(BCM_TOMAHAWK3_SUPPORT)
   3517         {
   3518               if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {  /* IPROC/CMICD */
   3519                     if (needs_restart) {
   3520                         soc_reg_field32_modify(unit, NS_BS0_BS_CONFIGr,
   3521                                                REG_PORT_ANY,
   3522                                                BS_TC_OUTPUT_ENABLEf, 0);
   3523                         /* use "lock" field as a signal on startup that the servo offset should be included */
   3524                         soc_reg_field32_modify(unit, NS_BS0_BS_OUTPUT_TIME_0r,
   3525                                                REG_PORT_ANY,
   3526                                                LOCKf, include_servo_offset);
   3527 
   3528                         sal_usleep(two_cycle_delay_usec);
   3529 
   3530                         soc_reg_field32_modify(unit, NS_BS0_BS_CONFIGr,
   3531                                                REG_PORT_ANY,
   3532                                                BS_TC_OUTPUT_ENABLEf, tc_output_enable);
   3533 
   3534                         sal_usleep(two_cycle_delay_usec);
   3535                     }
   3536                     soc_reg_field32_modify(unit, NS_BS0_BS_OUTPUT_TIME_0r,
   3537                                            REG_PORT_ANY,
   3538                                            LOCKf, locked);
   3539                 }
   3540 
   3541         }
   3542 #endif
   3543             /* copy the used flags */
   3544             (TIME_INTERFACE(unit, intf->id))->flags &= ~(BCM_TIME_ENABLE | BCM_TIME_INPUT | BCM_TIME_REF_CLOCK | BCM_TIME_LOCKED);
   3545             (TIME_INTERFACE(unit, intf->id))->flags |=
   3546                 intf->flags & (BCM_TIME_ENABLE | BCM_TIME_INPUT | BCM_TIME_REF_CLOCK | BCM_TIME_LOCKED);
   3547 
   3548             TIME_UNLOCK(unit);
   3549             return (BCM_E_NONE);
   3550         }
   3551 #endif /* INCLUDE_PTP */
   3552 
   3553         /* Set time interface configuration. */
   3554         if (replacing) {
   3555             if (((TIME_INTERFACE(unit, intf->id))->flags &
   3556                  (BCM_TIME_ENABLE | BCM_TIME_INPUT)) !=
   3557                 (intf->flags & (BCM_TIME_ENABLE | BCM_TIME_INPUT))) {
   3558                 /* either master or enabled state changed, so copy those bits in flags */
   3559                 (TIME_INTERFACE(unit, intf->id))->flags &= ~(BCM_TIME_ENABLE | BCM_TIME_INPUT);
   3560                 (TIME_INTERFACE(unit, intf->id))->flags |=
   3561                     intf->flags & (BCM_TIME_ENABLE | BCM_TIME_INPUT);
   3562                 /* either master or enabled state changed, so re-init */
   3563                 reset_hardware = 1;
   3564             }
   3565             if (intf->flags & BCM_TIME_DRIFT) {
   3566                 (TIME_INTERFACE(unit, intf->id))->drift = intf->drift;
   3567             }
   3568             if (intf->flags & BCM_TIME_OFFSET) {
   3569                 (TIME_INTERFACE(unit, intf->id))->offset = intf->offset;
   3570             }
   3571             if (intf->flags & BCM_TIME_ACCURACY) {
   3572                 (TIME_INTERFACE(unit, intf->id))->accuracy = intf->accuracy;
   3573             }
   3574             if (intf->flags & BCM_TIME_HEARTBEAT) {
   3575                 if ((TIME_INTERFACE(unit, intf->id))->heartbeat_hz != intf->heartbeat_hz) {
   3576                     (TIME_INTERFACE(unit, intf->id))->heartbeat_hz = intf->heartbeat_hz;
   3577                     /* Also use heartbeat flag to indicate whether to replace bitclock freq */
   3578                     (TIME_INTERFACE(unit, intf->id))->bitclock_hz = intf->bitclock_hz;
   3579                     reset_hardware = 1;
   3580                 }
   3581             }
   3582             if (intf->flags & BCM_TIME_BS_TIME) {
   3583                 (TIME_INTERFACE(unit, intf->id))->bs_time = intf->bs_time;
   3584             }
   3585         } else {
   3586             /* Is new, so just copy wholesale */
   3587             *(TIME_INTERFACE(unit, intf->id)) = *intf;
   3588             reset_hardware = 1;
   3589         }
   3590 
   3591 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   3592         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   3593             uint32 regval;
   3594             /* in case of broadsync, enable common control for both counters */
   3595             READ_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, &regval);
   3596             soc_reg_field_set(unit, NS_TIMESYNC_COUNTER_CONFIG_SELECTr, &regval,
   3597                               ENABLE_COMMON_CONTROLf, 1);
   3598             WRITE_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, regval);
   3599 
   3600         } else if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   3601             uint32 regval;
   3602             /* in case of broadsync, enable common control for both counters */
   3603             READ_CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, &regval);
   3604             soc_reg_field_set(unit, CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr, &regval,
   3605                               ENABLE_COMMON_CONTROLf, 1);
   3606             WRITE_CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, regval);
   3607         }
   3608 #endif /* defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC) */
   3609 
   3610 
   3611         if (reset_hardware) {
   3612             /* Enable/Setup TIME API BroadSync on the unit */
   3613             rv = _bcm_esw_time_bs_init(unit, TIME_INTERFACE(unit, intf->id));
   3614             if (BCM_FAILURE(rv)) {
   3615                 TIME_UNLOCK(unit);
   3616                 return rv;
   3617             }
   3618         }
   3619 
   3620         if (!replacing) {
   3621             /* Enable BS firmware on the unit */
   3622             rv = _bcm_mbox_comm_init(unit, MOS_MSG_MBOX_APPL_BS);
   3623             if (BCM_FAILURE(rv)) {
   3624                 TIME_UNLOCK(unit);
   3625                 return rv;
   3626             }
   3627         }
   3628 
   3629         /* Set BroadSync time */
   3630         if (intf->flags & BCM_TIME_BS_TIME) {
   3631             rv = _bcm_time_bs_time_set(unit, intf->bs_time);
   3632             if (BCM_FAILURE(rv)) {
   3633                 TIME_UNLOCK(unit);
   3634                 return rv;
   3635             }
   3636         }
   3637 
   3638         /* Set specified offsets */
   3639         if (intf->flags & BCM_TIME_DRIFT) {
   3640             rv = _bcm_time_bs_frequency_offset_set(unit, intf->drift);
   3641             if (BCM_FAILURE(rv)) {
   3642                 TIME_UNLOCK(unit);
   3643                 return rv;
   3644             }
   3645         }
   3646 
   3647         if (intf->flags & BCM_TIME_OFFSET) {
   3648             rv = _bcm_time_bs_phase_offset_set(unit, intf->offset);
   3649             if (BCM_FAILURE(rv)) {
   3650                 TIME_UNLOCK(unit);
   3651                 return rv;
   3652             }
   3653         }
   3654 
   3655         TIME_UNLOCK(unit);
   3656 
   3657 #ifdef BCM_WARM_BOOT_SUPPORT
   3658         SOC_CONTROL_LOCK(unit);
   3659         SOC_CONTROL(unit)->scache_dirty = 1;
   3660         SOC_CONTROL_UNLOCK(unit);
   3661 #endif
   3662 
   3663         return (BCM_E_NONE);
   3664     }
   3665 
   3666 
   3667     if (SOC_HAS_MANAGED_BROADSYNC(unit)) {
   3668         uint32          regval = 0;
   3669 
   3670     if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   3671             /* Enable Timestamp Generation */
   3672             READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, &regval);
   3673             /* 500 Mhz NCO - 2.000 ns */
   3674             soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr, &regval, UINCf, 
   3675                                             0x2000);
   3676             WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, regval);
   3677 
   3678             READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, &regval);
   3679             soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr, &regval, LINCf, 0);
   3680             WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, regval);
   3681 
   3682             READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &regval);
   3683             soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &regval, ENABLEf, 1);
   3684             WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, regval);
   3685 
   3686         } else
   3687 #if defined (BCM_IPROC_SUPPORT)
   3688         if (soc_feature(unit, soc_feature_iproc)) {
   3689             /* Enable Timestamp Generation */
   3690             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, &regval);
   3691             /* 250 Mhz - 4.000 ns */
   3692             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr, &regval, FRACf,
   3693                               ((soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0)
   3694                                 == 12800000 ) ? 0x40842108 : 0x40000000));
   3695             WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, regval);
   3696 
   3697             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr(unit, &regval);
   3698             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr, &regval, NSf, 0);
   3699             WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr(unit, regval);
   3700 
   3701             READ_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &regval);
   3702             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_COUNTER_ENABLEr, &regval, ENABLEf, 1);
   3703             WRITE_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, regval);
   3704         } else
   3705 #endif
   3706         {
   3707             /* Enable Timestamp Generation */
   3708             READ_CMIC_TS_FREQ_CTRL_LOWERr(unit, &regval);
   3709             /* 250 Mhz - 4.000 ns */
   3710             soc_reg_field_set(unit, CMIC_TS_FREQ_CTRL_LOWERr, &regval, FRACf,
   3711                               ((soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0)
   3712                                 == 12800000 ) ? 0x40842108 : 0x40000000));
   3713             WRITE_CMIC_TS_FREQ_CTRL_LOWERr(unit, regval);
   3714 
   3715             READ_CMIC_TS_FREQ_CTRL_UPPERr(unit, &regval);
   3716             soc_reg_field_set(unit, CMIC_TS_FREQ_CTRL_UPPERr, &regval, NSf, 0);
   3717             soc_reg_field_set(unit, CMIC_TS_FREQ_CTRL_UPPERr, &regval, ENABLEf, 1);
   3718             WRITE_CMIC_TS_FREQ_CTRL_UPPERr(unit, regval);
   3719         }
   3720 
   3721         if (intf->flags & BCM_TIME_REF_CLOCK) {
   3722             rv = _bcm_esw_time_interface_ref_clock_install(unit, intf->id);
   3723             if (BCM_FAILURE(rv)) {
   3724                 TIME_INTERFACE_CONFIG_REF_COUNT(unit, intf->id) -= 1;
   3725                 TIME_UNLOCK(unit);
   3726                 return rv;
   3727             }
   3728         }
   3729     }
   3730 #endif /* BCM_TIME_MANAGED_BROADSYNC */
   3731 
   3732 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   3733     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   3734         uint32 regval;
   3735 
   3736         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   3737             /* Enable common control for both counters */
   3738             READ_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, &regval);
   3739             soc_reg_field_set(unit, NS_TIMESYNC_COUNTER_CONFIG_SELECTr, &regval, 
   3740                               ENABLE_COMMON_CONTROLf, 1);
   3741             WRITE_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, regval);
   3742 
   3743             /* Enable Timestamp Generation */
   3744             READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, &regval);
   3745 
   3746             /* TH3 1GHz input to iProc 2.000 ns */
   3747             soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr, &regval, UINCf, 
   3748                                             0x2000);
   3749             WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, regval);
   3750 
   3751             READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, &regval);
   3752             soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr, &regval, LINCf, 0);
   3753             WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, regval);
   3754 
   3755             READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &regval);
   3756             soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &regval, ENABLEf, 1);
   3757             WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, regval);
   3758         } else {
   3759             /* Enable common control for both counters */
   3760             READ_CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, &regval);
   3761             soc_reg_field_set(unit, CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr, &regval, 
   3762                               ENABLE_COMMON_CONTROLf, 1);
   3763             WRITE_CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, regval);
   3764 
   3765             /* 250 Mhz - 4.000 ns */
   3766             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, &regval);
   3767             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr, &regval, 
   3768                               FRACf,
   3769                               ((soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0)
   3770                               == 12800000 ) ? 0x40842108 : 0x40000000));
   3771             WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, regval);
   3772 
   3773             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr(unit, &regval);
   3774             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr, &regval, 
   3775                               NSf, 0);
   3776             WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr(unit, regval);
   3777 
   3778             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_LOWERr(unit, &regval);
   3779             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_LOWERr, &regval, 
   3780                               NSf, 0);
   3781             WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_LOWERr(unit, regval);
   3782 
   3783             /* Enable Timestamp Generation */
   3784             READ_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &regval);
   3785             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_COUNTER_ENABLEr, &regval, 
   3786                               ENABLEf, 1);
   3787             WRITE_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, regval);
   3788         }
   3789         if (intf->flags & BCM_TIME_REF_CLOCK) {
   3790             rv = _bcm_esw_time_interface_ref_clock_install(unit, intf->id);
   3791             if (BCM_FAILURE(rv)) {
   3792                 TIME_INTERFACE_CONFIG_REF_COUNT(unit, intf->id) -= 1;
   3793                 TIME_UNLOCK(unit);
   3794                 return rv;
   3795             }
   3796         }
   3797     }
   3798 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   3799 
   3800     /* Set time interface configuration. */
   3801     *(TIME_INTERFACE(unit, intf->id)) = *intf;
   3802 
   3803     /* Install the interface into the HW */
   3804 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   3805     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   3806         if (!soc_feature(unit, soc_feature_time_v3_no_bs)) {
   3807             rv = _bcm_esw_time_interface_dual_bs_install(unit, intf->id);
   3808         }
   3809     } else
   3810 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   3811     {
   3812         rv = _bcm_esw_time_interface_install(unit, intf->id);
   3813     }
   3814 
   3815     if (BCM_FAILURE(rv)) {
   3816         TIME_INTERFACE_CONFIG_REF_COUNT(unit, intf->id) -= 1;
   3817         TIME_UNLOCK(unit);
   3818         return rv;
   3819     }
   3820 
   3821     TIME_UNLOCK(unit);
   3822 
   3823 #ifdef BCM_WARM_BOOT_SUPPORT
   3824     SOC_CONTROL_LOCK(unit);
   3825     SOC_CONTROL(unit)->scache_dirty = 1;
   3826     SOC_CONTROL_UNLOCK(unit);
   3827 #endif
   3828 
   3829     return (BCM_E_NONE);
   3830 }
   3831 
   3832 /*
   3833  * Function:
   3834  *      bcm_esw_time_interface_delete
   3835  * Purpose:
   3836  *      Deleting a time sync interface from unit 
   3837  * Parameters:
   3838  *      unit    - (IN) StrataSwitch Unit #.
   3839  *      intf_id - (IN) Time Sync Interface id to remove
   3840  * Returns:
   3841  *      BCM_E_NONE
   3842  *      BCM_E_XXX
   3843  */
   3844 int 
   3845 bcm_esw_time_interface_delete (int unit, bcm_time_if_t intf_id)
   3846 {
   3847     int rv;
   3848 
   3849     /* Chek if time feature is supported on a device */
   3850     if (!soc_feature(unit, soc_feature_time_support)) {
   3851         return (BCM_E_UNAVAIL);
   3852     }
   3853 
   3854     /* Initialization check. */
   3855     BCM_IF_ERROR_RETURN(
   3856         _bcm_esw_time_interface_id_validate(unit, intf_id));
   3857 
   3858     TIME_LOCK(unit);
   3859 
   3860     /* If interface still in use return an Error */
   3861     if (1 < TIME_INTERFACE_CONFIG_REF_COUNT(unit, intf_id)) {
   3862         TIME_UNLOCK(unit);
   3863         return (BCM_E_BUSY);
   3864     }
   3865 
   3866     /* Free the interface */
   3867     rv = _bcm_time_interface_free(unit, intf_id); 
   3868     if (BCM_FAILURE(rv)) {
   3869         TIME_UNLOCK(unit);
   3870         return (rv);
   3871     }
   3872 
   3873     rv = _bcm_esw_time_hw_clear(unit, intf_id);
   3874 
   3875 #ifdef BCM_WARM_BOOT_SUPPORT
   3876     SOC_CONTROL_LOCK(unit);
   3877     SOC_CONTROL(unit)->scache_dirty = 1;
   3878     SOC_CONTROL_UNLOCK(unit);
   3879 #endif
   3880 
   3881     TIME_UNLOCK(unit);
   3882     return (rv);
   3883 }
   3884 
   3885 /*
   3886  * Function:
   3887  *      bcm_esw_time_interface_get
   3888  * Purpose:
   3889  *      Get a time sync interface on a specified unit 
   3890  * Parameters:
   3891  *      unit -  (IN) StrataSwitch Unit #.
   3892  *      intf - (IN/OUT) Time Sync Interface to get
   3893  * Returns:
   3894  *      BCM_E_NONE
   3895  *      BCM_E_XXX
   3896  */
   3897 int 
   3898 bcm_esw_time_interface_get (int unit, bcm_time_interface_t *intf)
   3899 {
   3900     int rv; 
   3901     /* Chek if time feature is supported on a device */
   3902     if (!soc_feature(unit, soc_feature_time_support)) {
   3903         return (BCM_E_UNAVAIL);
   3904     }
   3905 
   3906     /* Validation checks */
   3907     if (NULL == intf) {
   3908         return BCM_E_PARAM;
   3909     }
   3910 
   3911     BCM_IF_ERROR_RETURN(
   3912         _bcm_esw_time_interface_id_validate(unit, intf->id));
   3913 
   3914     TIME_LOCK(unit);
   3915 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   3916     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   3917         rv = _bcm_esw_time_interface_dual_bs_get(unit, intf->id, intf);
   3918     } else
   3919 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   3920     {
   3921         rv = _bcm_esw_time_interface_get(unit, intf->id, intf);
   3922     }
   3923 
   3924     if (intf->flags & BCM_TIME_SYNC_STAMPER) {
   3925         if (!soc_feature(unit, soc_feature_time_v3_no_bs)) {
   3926             BCM_IF_ERROR_RETURN(_bcm_time_bs_status_get(unit,
   3927                                  (int *)(&(intf->status))));
   3928         }
   3929     }
   3930     TIME_UNLOCK(unit);
   3931 
   3932     return (rv);
   3933 }
   3934 
   3935 /*
   3936  * Function:
   3937  *      bcm_esw_time_interface_delete_all
   3938  * Purpose:
   3939  *      Deleting all time sync interfaces on a unit 
   3940  * Parameters:
   3941  *      unit    - (IN) StrataSwitch Unit #.
   3942  * Returns:
   3943  *      BCM_E_NONE
   3944  *      BCM_E_XXX
   3945  */
   3946 int 
   3947 bcm_esw_time_interface_delete_all (int unit)
   3948 {
   3949     bcm_time_if_t   intf;
   3950 
   3951     /* Chek if time feature is supported on a device */
   3952     if (!soc_feature(unit, soc_feature_time_support)) {
   3953         return (BCM_E_UNAVAIL);
   3954     }
   3955 
   3956     /* Initialization check */
   3957     if (0 == TIME_INIT(unit)) {
   3958         return BCM_E_INIT;
   3959     }
   3960 
   3961     for (intf = 0; intf < NUM_TIME_INTERFACE(unit); intf++ ) {
   3962         BCM_IF_ERROR_RETURN(
   3963             bcm_esw_time_interface_delete(unit, intf));
   3964     }
   3965 
   3966     return (BCM_E_NONE);
   3967 }
   3968 
   3969 /*
   3970  * Function:
   3971  *      bcm_esw_time_interface_traverse
   3972  * Purpose:
   3973  *      Itterates over all time sync interfaces and calls given callback 
   3974  * Parameters:
   3975  *      unit        - (IN) StrataSwitch Unit #.
   3976  *      cb          - (IN) Call back function
   3977  *      user_data   - (IN) void pointer to store any user information
   3978  * Returns:
   3979  *      BCM_E_NONE
   3980  *      BCM_E_XXX
   3981  */
   3982 int 
   3983 bcm_esw_time_interface_traverse (int unit, bcm_time_interface_traverse_cb cb, 
   3984                                  void *user_data)
   3985 {
   3986     bcm_time_if_t   intf;
   3987 
   3988     /* Chek if time feature is supported on a device */
   3989     if (!soc_feature(unit, soc_feature_time_support)) {
   3990         return (BCM_E_UNAVAIL);
   3991     }
   3992 
   3993     /* Initialization check. */
   3994     if (0 == TIME_INIT(unit)) {
   3995         return BCM_E_INIT;
   3996     }
   3997 
   3998     if (NULL == cb) {
   3999         return (BCM_E_PARAM);
   4000     }
   4001 
   4002     for (intf = 0; intf < NUM_TIME_INTERFACE(unit); intf++ ) {
   4003         if (NULL != TIME_INTERFACE(unit, intf)) {
   4004             BCM_IF_ERROR_RETURN(cb(unit, TIME_INTERFACE(unit, intf), user_data));
   4005         }
   4006     }
   4007     return (BCM_E_NONE);
   4008 }
   4009 
   4010 /*
   4011  * Function:
   4012  *      bcm_esw_time_capture_get
   4013  * Purpose:
   4014  *      Gets a time captured by HW clock
   4015  * Parameters:
   4016  *      unit    - (IN) StrataSwitch Unit #.
   4017  *      id      - (IN) Time interface identifier 
   4018  *      time    - (OUT) Structure to contain HW clocks values
   4019  * Returns:
   4020  *      BCM_E_NONE
   4021  *      BCM_E_XXX
   4022  */
   4023 int 
   4024 bcm_esw_time_capture_get (int unit, bcm_time_if_t id, bcm_time_capture_t *time)
   4025 {
   4026     int rv;   /* Operation return status. */
   4027 
   4028     /* Chek if time feature is supported on a device */
   4029     if (!soc_feature(unit, soc_feature_time_support)) {
   4030         return (BCM_E_UNAVAIL);
   4031     }
   4032 
   4033     /* Initialization check. */
   4034     BCM_IF_ERROR_RETURN(
   4035         _bcm_esw_time_interface_id_validate(unit, id));
   4036 
   4037     if (NULL == time) {
   4038         return (BCM_E_PARAM);
   4039     }
   4040     if (NULL == TIME_CAPTURE(unit, id)) {
   4041         return (BCM_E_NOT_FOUND);
   4042     }
   4043 
   4044     TIME_LOCK(unit);
   4045     rv = _bcm_esw_time_capture_get(unit, id, TIME_CAPTURE(unit, id), time->flags);
   4046     if (BCM_FAILURE(rv)) {
   4047         TIME_UNLOCK(unit);
   4048         return (rv);
   4049     }
   4050 
   4051     *time = *(TIME_CAPTURE(unit, id));
   4052 
   4053     TIME_UNLOCK(unit);
   4054 
   4055     return (BCM_E_NONE);
   4056 }
   4057 
   4058 /*
   4059  * Function:
   4060  *      bcm_esw_time_heartbeat_enable_set
   4061  * Purpose:
   4062  *      Enables/Disables interrupt handling for each heartbeat provided by a 
   4063  *      HW clock
   4064  * Parameters:
   4065  *      unit    - (IN) StrataSwitch Unit #.
   4066  *      id      - (IN) Time Sync Interface Id
   4067  *      enable  - (IN) Enable/Disable parameter
   4068  * Returns:
   4069  *      BCM_E_NONE
   4070  *      BCM_E_XXX
   4071  */
   4072 int 
   4073 bcm_esw_time_heartbeat_enable_set (int unit, bcm_time_if_t id, int enable)
   4074 {
   4075     uint32          regval;
   4076     soc_control_t   *soc = SOC_CONTROL(unit);
   4077 
   4078     /* Check if time feature is supported on a device */
   4079     if (!soc_feature(unit, soc_feature_time_support)) {
   4080         return (BCM_E_UNAVAIL);
   4081     }
   4082 
   4083     /* Feature unavailable on devices without BroadSync support. */
   4084     if (soc_feature(unit, soc_feature_time_v3_no_bs)) {
   4085         return BCM_E_UNAVAIL;
   4086     }
   4087 
   4088     /* Param validation check. */
   4089     BCM_IF_ERROR_RETURN(
   4090         _bcm_esw_time_interface_id_validate(unit, id));
   4091 
   4092     TIME_LOCK(unit);
   4093 
   4094 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
   4095     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \
   4096     defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   4097     if ((TIME_INTERFACE(unit, id))->flags & BCM_TIME_SYNC_STAMPER) {
   4098         int rv = _bcm_time_bs_debug_1pps_set(unit, enable);
   4099         if (BCM_FAILURE(rv)) {
   4100             TIME_UNLOCK(unit);
   4101             return rv;
   4102         }
   4103 
   4104         TIME_UNLOCK(unit);
   4105         return BCM_E_NONE;
   4106     }
   4107 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) ||
   4108           defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) ||
   4109           defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) */
   4110 
   4111     /* Install heartbeat and external trigger clock interval */
   4112 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   4113     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   4114         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   4115             READ_NS_MISC_CLK_EVENT_CTRLr(unit, &regval);
   4116             soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, ENABLEf,
   4117                 (enable) ? IPROC_TIME_CAPTURE_MODE_HB_BS_0 : IPROC_TIME_CAPTURE_MODE_DISABLE);
   4118             WRITE_NS_MISC_CLK_EVENT_CTRLr(unit, regval);
   4119 
   4120             if (enable) {
   4121                 /* Configure the HW to raise interrupt on every heartbeat */
   4122                 READ_NS_MISC_CLK_EVENT_CTRLr(unit, &regval);
   4123                 soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, ENABLEf, 1);
   4124                 soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, BS0_TX_HB_STATUS_ENABLEf, 1);
   4125                 soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, BS0_RX_HB_STATUS_ENABLEf, 1);
   4126                 WRITE_NS_MISC_CLK_EVENT_CTRLr(unit, regval);
   4127             } else {
   4128                 /* Leave TIME_CAPTURE_ENABLEf for other trigger sources */
   4129                 READ_NS_MISC_CLK_EVENT_CTRLr(unit, &regval);
   4130                 soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, BS0_RX_HB_STATUS_ENABLEf, 0);
   4131                 soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regval, BS0_TX_HB_STATUS_ENABLEf, 0);
   4132                 WRITE_NS_MISC_CLK_EVENT_CTRLr(unit, regval);
   4133             }
   4134         } else {
   4135             READ_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, &regval);
   4136             soc_reg_field_set(unit, CMIC_TIMESYNC_INTERRUPT_ENABLEr, &regval, INT_ENABLEf,
   4137                 (enable) ? IPROC_TIME_CAPTURE_MODE_HB_BS_0 : IPROC_TIME_CAPTURE_MODE_DISABLE);
   4138             WRITE_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, regval);
   4139 
   4140             if (enable) {
   4141                 /* Configure the HW to raise interrupt on every heartbeat */
   4142                 READ_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, &regval);
   4143                 soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, TIME_CAPTURE_ENABLEf, 1);
   4144                 soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, BSYNC0_TX_HB_STATUS_ENABLEf, 1);
   4145                 soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, BSYNC0_RX_HB_STATUS_ENABLEf, 1);
   4146                 WRITE_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, regval);
   4147             } else {
   4148                 /* Leave TIME_CAPTURE_ENABLEf for other trigger sources */
   4149                 READ_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, &regval);
   4150                 soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, BSYNC0_RX_HB_STATUS_ENABLEf, 0);
   4151                 soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &regval, BSYNC0_TX_HB_STATUS_ENABLEf, 0);
   4152                 WRITE_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, regval);
   4153             }
   4154 
   4155             /* Configure the HW to capture time on every heartbeat */
   4156             READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &regval);
   4157             soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &regval, TIME_CAPTURE_MODEf,
   4158                 (enable) ? IPROC_TIME_CAPTURE_MODE_HB_BS_0 : IPROC_TIME_CAPTURE_MODE_DISABLE);
   4159 
   4160             WRITE_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, regval);
   4161 
   4162             /* set interrupt enables to match the mode */
   4163             WRITE_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, regval);
   4164         }
   4165 
   4166 
   4167     } else
   4168 
   4169 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   4170 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   4171     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) {
   4172         READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
   4173         /* Configure the HW to raise interrupt on every heartbeat */
   4174         soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, INT_ENABLEf, 
   4175                           (enable) ? TIME_CAPTURE_MODE_HEARTBEAT : 0);
   4176         soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, TIME_CAPTURE_ENABLEf, 1);
   4177         soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, TX_HB_STATUS_ENABLEf, 1);
   4178         soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, RX_HB_STATUS_ENABLEf, 1);
   4179 
   4180         /* Configure the HW to capture time on every heartbeat */
   4181         soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, TIME_CAPTURE_MODEf,
   4182                           (enable) ? TIME_CAPTURE_MODE_HEARTBEAT : TIME_CAPTURE_MODE_DISABLE);
   4183         WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, regval);
   4184     } else
   4185 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   4186     {
   4187         READ_CMIC_BS_CAPTURE_CTRLr(unit, &regval);
   4188         /* Configure the HW to give interrupt on every heartbeat */
   4189         soc_reg_field_set(unit, CMIC_BS_CAPTURE_CTRLr, &regval, INT_ENf, (enable) ? 1: 0);
   4190         /* Configure the HW to capture time on every heartbeat */
   4191         soc_reg_field_set(unit, CMIC_BS_CAPTURE_CTRLr, &regval, TIME_CAPTURE_MODEf,
   4192                           (enable) ? TIME_CAPTURE_MODE_HEARTBEAT : TIME_CAPTURE_MODE_DISABLE);
   4193         WRITE_CMIC_BS_CAPTURE_CTRLr(unit, regval);
   4194     }
   4195 
   4196     TIME_UNLOCK(unit);
   4197 
   4198     /* Enable/disable broadsync interrupt */
   4199     if (enable) {
   4200         soc_intr_enable(unit, IRQ_BROADSYNC_INTR);
   4201         if (!soc->time_call_ref_count) {
   4202             soc->soc_time_callout = _bcm_esw_time_hw_interrupt_dflt;
   4203         }
   4204 
   4205     } else {
   4206         soc_intr_disable(unit, IRQ_BROADSYNC_INTR);
   4207         if (!soc->time_call_ref_count) {
   4208             soc->soc_time_callout = NULL;
   4209         }
   4210     }
   4211 
   4212     return (BCM_E_NONE);
   4213 }
   4214 
   4215 /*
   4216  * Function:
   4217  *      bcm_esw_time_heartbeat_enable_get
   4218  * Purpose:
   4219  *      Gets interrupt handling status for each heartbeat provided by a 
   4220  *      HW clock
   4221  * Parameters:
   4222  *      unit    - (IN) StrataSwitch Unit #.
   4223  *      id      - (IN) Time Sync Interface Id
   4224  *      enable  - (OUT) Enable status of interrupt handling
   4225  * Returns:
   4226  *      BCM_E_NONE
   4227  *      BCM_E_XXX
   4228  */
   4229 int 
   4230 bcm_esw_time_heartbeat_enable_get (int unit, bcm_time_if_t id, int *enable)
   4231 {
   4232     uint32      regval;
   4233 
   4234     /* Check if time feature is supported on a device */
   4235     if (!soc_feature(unit, soc_feature_time_support)) {
   4236         return (BCM_E_UNAVAIL);
   4237     }
   4238 
   4239     /* Feature unavailable on devices without BroadSync support. */
   4240     if (soc_feature(unit, soc_feature_time_v3_no_bs)) {
   4241         return BCM_E_UNAVAIL;
   4242     }
   4243 
   4244     /* Param validation check. */
   4245     if (enable == NULL) {
   4246         return (BCM_E_PARAM);
   4247     }
   4248     BCM_IF_ERROR_RETURN(
   4249         _bcm_esw_time_interface_id_validate(unit, id));
   4250 
   4251     /* Read HW Configuration */
   4252 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   4253     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   4254         if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
   4255             READ_NS_MISC_CLK_EVENT_CTRLr(unit, &regval);
   4256             *enable = soc_reg_field_get(unit, NS_MISC_CLK_EVENT_CTRLr, regval, ENABLEf) &
   4257                     soc_reg_field_get(unit, NS_MISC_CLK_EVENT_CTRLr, regval, BS0_TX_HB_STATUS_ENABLEf) &
   4258                     soc_reg_field_get(unit, NS_MISC_CLK_EVENT_CTRLr, regval, BS0_RX_HB_STATUS_ENABLEf);
   4259         } else {
   4260             READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &regval);
   4261             *enable = (regval & TIME_CAPTURE_MODE_HEARTBEAT)? 1 : 0;
   4262         }
   4263     } else
   4264 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   4265 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   4266     if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) ||
   4267         SOC_IS_TD2_TT2(unit)) {
   4268         READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
   4269         *enable = soc_reg_field_get(unit, CMIC_TS_TIME_CAPTURE_CTRLr,
   4270                                     regval, INT_ENABLEf);
   4271         *enable = (*enable ==  TIME_CAPTURE_MODE_HEARTBEAT) ? 1 : 0; 
   4272     } else
   4273 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   4274     {
   4275         READ_CMIC_BS_CAPTURE_CTRLr(unit, &regval);
   4276         *enable = soc_reg_field_get(unit, CMIC_BS_CAPTURE_CTRLr, regval, INT_ENf); 
   4277     }
   4278 
   4279     return (BCM_E_NONE);
   4280 }
   4281 
   4282 
   4283 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   4284 /*
   4285  * Function:
   4286  *      _bcm_esw_time_trigger_to_timestamp_mode
   4287  * Purpose: 
   4288  *      Convert capture mode flags to time control capture modes
   4289  *
   4290  * Parameters: 
   4291  *      unit       - (IN) mode_flags
   4292  *
   4293  * Returns:
   4294  *      Timesync captude modes 
   4295  * Notes:
   4296  */
   4297 STATIC uint32
   4298 _bcm_esw_time_trigger_to_timestamp_mode(int unit, uint32 mode_flags)
   4299 {
   4300     uint32 capture_mode = 0;
   4301     uint32 regval;
   4302     int    bit_cnt;
   4303 
   4304     /* processing on user mode flags reduces the dependencies on 
   4305      * hardware bit maps, byte shift of mode flags
   4306      * should have been efficient 
   4307      */
   4308     for (bit_cnt = 0; bit_cnt < sizeof(uint32); bit_cnt++)
   4309     {
   4310         switch (mode_flags & (1 << bit_cnt))
   4311         {
   4312         case BCM_TIME_CAPTURE_GPIO_0:
   4313             capture_mode |=  TIME_CAPTURE_MODE_GPIO_0;
   4314             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr, ENABLEf)) {
   4315                 READ_CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr(unit, &regval);
   4316                 soc_reg_field_set(unit, CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr, &regval, ENABLEf, 1);
   4317                 WRITE_CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr(unit, regval);
   4318             }
   4319             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_1_UP_EVENT_CTRLr, ENABLEf)) {
   4320                 READ_CMIC_TS_GPIO_1_UP_EVENT_CTRLr(unit, &regval);
   4321                 soc_reg_field_set(unit, CMIC_TS_GPIO_1_UP_EVENT_CTRLr, &regval, ENABLEf, 1);
   4322                 WRITE_CMIC_TS_GPIO_1_UP_EVENT_CTRLr(unit, regval);
   4323             }
   4324             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_1_CTRLr, ENABLEf)) {
   4325                 READ_CMIC_TS_GPIO_1_CTRLr(unit, &regval);
   4326                 soc_reg_field_set(unit, CMIC_TS_GPIO_1_CTRLr, &regval, ENABLEf, 1);
   4327                 WRITE_CMIC_TS_GPIO_1_CTRLr(unit, regval);
   4328             }
   4329             break;
   4330 
   4331         case BCM_TIME_CAPTURE_GPIO_1:
   4332             capture_mode |=  TIME_CAPTURE_MODE_GPIO_1;
   4333             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr, ENABLEf)) {
   4334                 READ_CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr(unit, &regval);
   4335                 soc_reg_field_set(unit, CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr, &regval, ENABLEf, 1);
   4336                 WRITE_CMIC_TS_GPIO_1_DOWN_EVENT_CTRLr(unit, regval);
   4337             }
   4338             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_1_UP_EVENT_CTRLr, ENABLEf)) {
   4339                 READ_CMIC_TS_GPIO_1_UP_EVENT_CTRLr(unit, &regval);
   4340                 soc_reg_field_set(unit, CMIC_TS_GPIO_1_UP_EVENT_CTRLr, &regval, ENABLEf, 1);
   4341                 WRITE_CMIC_TS_GPIO_1_UP_EVENT_CTRLr(unit, regval);
   4342             }
   4343             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_1_CTRLr, ENABLEf)) {
   4344                 READ_CMIC_TS_GPIO_1_CTRLr(unit, &regval);
   4345                 soc_reg_field_set(unit, CMIC_TS_GPIO_1_CTRLr, &regval, ENABLEf, 1);
   4346                 WRITE_CMIC_TS_GPIO_1_CTRLr(unit, regval);
   4347             }
   4348             break;
   4349 
   4350         case BCM_TIME_CAPTURE_GPIO_2:
   4351             capture_mode |=  TIME_CAPTURE_MODE_GPIO_2;
   4352             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_2_DOWN_EVENT_CTRLr, ENABLEf)) {
   4353                 READ_CMIC_TS_GPIO_2_DOWN_EVENT_CTRLr(unit, &regval);
   4354                 soc_reg_field_set(unit, CMIC_TS_GPIO_2_DOWN_EVENT_CTRLr, &regval, ENABLEf, 1);
   4355                 WRITE_CMIC_TS_GPIO_2_DOWN_EVENT_CTRLr(unit, regval);
   4356             }
   4357             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_2_UP_EVENT_CTRLr, ENABLEf)) {
   4358                 READ_CMIC_TS_GPIO_2_UP_EVENT_CTRLr(unit, &regval);
   4359                 soc_reg_field_set(unit, CMIC_TS_GPIO_2_UP_EVENT_CTRLr, &regval, ENABLEf, 1);
   4360                 WRITE_CMIC_TS_GPIO_2_UP_EVENT_CTRLr(unit, regval);
   4361             }
   4362             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_2_CTRLr, ENABLEf)) {
   4363                 READ_CMIC_TS_GPIO_2_CTRLr(unit, &regval);
   4364                 soc_reg_field_set(unit, CMIC_TS_GPIO_2_CTRLr, &regval, ENABLEf, 1);
   4365                 WRITE_CMIC_TS_GPIO_2_CTRLr(unit, regval);
   4366             }
   4367             break;
   4368 
   4369         case BCM_TIME_CAPTURE_GPIO_3:
   4370             capture_mode |=  TIME_CAPTURE_MODE_GPIO_3;
   4371             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_3_DOWN_EVENT_CTRLr, ENABLEf)) {
   4372                 READ_CMIC_TS_GPIO_3_DOWN_EVENT_CTRLr(unit, &regval);
   4373                 soc_reg_field_set(unit, CMIC_TS_GPIO_3_DOWN_EVENT_CTRLr, &regval, ENABLEf, 1);
   4374                 WRITE_CMIC_TS_GPIO_3_DOWN_EVENT_CTRLr(unit, regval);
   4375             }
   4376             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_3_UP_EVENT_CTRLr, ENABLEf)) {
   4377                 READ_CMIC_TS_GPIO_3_UP_EVENT_CTRLr(unit, &regval);
   4378                 soc_reg_field_set(unit, CMIC_TS_GPIO_3_UP_EVENT_CTRLr, &regval, ENABLEf, 1);
   4379                 WRITE_CMIC_TS_GPIO_3_UP_EVENT_CTRLr(unit, regval);
   4380             }
   4381             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_3_CTRLr, ENABLEf)) {
   4382                 READ_CMIC_TS_GPIO_3_CTRLr(unit, &regval);
   4383                 soc_reg_field_set(unit, CMIC_TS_GPIO_3_CTRLr, &regval, ENABLEf, 1);
   4384                 WRITE_CMIC_TS_GPIO_3_CTRLr(unit, regval);
   4385             }
   4386             break;
   4387 
   4388         case BCM_TIME_CAPTURE_GPIO_4:
   4389             capture_mode |=  TIME_CAPTURE_MODE_GPIO_4;
   4390             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_4_DOWN_EVENT_CTRLr, ENABLEf)) {
   4391                 READ_CMIC_TS_GPIO_4_DOWN_EVENT_CTRLr(unit, &regval);
   4392                 soc_reg_field_set(unit, CMIC_TS_GPIO_4_DOWN_EVENT_CTRLr, &regval, ENABLEf, 1);
   4393                 WRITE_CMIC_TS_GPIO_4_DOWN_EVENT_CTRLr(unit, regval);
   4394             }
   4395             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_4_UP_EVENT_CTRLr, ENABLEf)) {
   4396                 READ_CMIC_TS_GPIO_4_UP_EVENT_CTRLr(unit, &regval);
   4397                 soc_reg_field_set(unit, CMIC_TS_GPIO_4_UP_EVENT_CTRLr, &regval, ENABLEf, 1);
   4398                 WRITE_CMIC_TS_GPIO_4_UP_EVENT_CTRLr(unit, regval);
   4399             }
   4400             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_4_CTRLr, ENABLEf)) {
   4401                 READ_CMIC_TS_GPIO_4_CTRLr(unit, &regval);
   4402                 soc_reg_field_set(unit, CMIC_TS_GPIO_4_CTRLr, &regval, ENABLEf, 1);
   4403                 WRITE_CMIC_TS_GPIO_4_CTRLr(unit, regval);
   4404             }
   4405             break;
   4406 
   4407         case BCM_TIME_CAPTURE_GPIO_5:
   4408             capture_mode |=  TIME_CAPTURE_MODE_GPIO_5;
   4409             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_5_DOWN_EVENT_CTRLr, ENABLEf)) {
   4410                 READ_CMIC_TS_GPIO_5_DOWN_EVENT_CTRLr(unit, &regval);
   4411                 soc_reg_field_set(unit, CMIC_TS_GPIO_5_DOWN_EVENT_CTRLr, &regval, ENABLEf, 1);
   4412                 WRITE_CMIC_TS_GPIO_5_DOWN_EVENT_CTRLr(unit, regval);
   4413             }
   4414             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_5_UP_EVENT_CTRLr, ENABLEf)) {
   4415                 READ_CMIC_TS_GPIO_5_UP_EVENT_CTRLr(unit, &regval);
   4416                 soc_reg_field_set(unit, CMIC_TS_GPIO_5_UP_EVENT_CTRLr, &regval, ENABLEf, 1);
   4417                 WRITE_CMIC_TS_GPIO_5_UP_EVENT_CTRLr(unit, regval);
   4418             }
   4419             if (soc_reg_field_valid(unit, CMIC_TS_GPIO_5_CTRLr, ENABLEf)) {
   4420                 READ_CMIC_TS_GPIO_5_CTRLr(unit, &regval);
   4421                 soc_reg_field_set(unit, CMIC_TS_GPIO_5_CTRLr, &regval, ENABLEf, 1);
   4422                 WRITE_CMIC_TS_GPIO_5_CTRLr(unit, regval);
   4423             }
   4424             break;
   4425 
   4426         case BCM_TIME_CAPTURE_L1_CLOCK_PRIMARY:
   4427             capture_mode |=  TIME_CAPTURE_MODE_L1_CLOCK_PRIMARY;
   4428             READ_CMIC_TS_L1_CLK_RECOVERED_CLK_COUNT_CTRLr(unit, &regval);
   4429             soc_reg_field_set(unit, CMIC_TS_L1_CLK_RECOVERED_CLK_COUNT_CTRLr, &regval, ENABLEf, 1);
   4430             WRITE_CMIC_TS_L1_CLK_RECOVERED_CLK_COUNT_CTRLr(unit, regval);
   4431             break;
   4432 
   4433         case BCM_TIME_CAPTURE_L1_CLOCK_SECONDARY:
   4434             capture_mode |=  TIME_CAPTURE_MODE_L1_CLOCK_SECONDARY;
   4435             READ_CMIC_TS_L1_CLK_RECOVERED_CLK_BKUP_COUNT_CTRLr(unit, &regval);
   4436             soc_reg_field_set(unit, CMIC_TS_L1_CLK_RECOVERED_CLK_BKUP_COUNT_CTRLr, &regval, ENABLEf, 1);
   4437             WRITE_CMIC_TS_L1_CLK_RECOVERED_CLK_BKUP_COUNT_CTRLr(unit, regval);
   4438             break;
   4439 
   4440         case BCM_TIME_CAPTURE_LCPLL:
   4441             capture_mode |= TIME_CAPTURE_MODE_LCPLL;
   4442             READ_CMIC_TS_LCPLL_CLK_COUNT_CTRLr(unit, &regval);
   4443             soc_reg_field_set(unit, CMIC_TS_LCPLL_CLK_COUNT_CTRLr, &regval, ENABLEf, 1);
   4444             WRITE_CMIC_TS_LCPLL_CLK_COUNT_CTRLr(unit, regval);
   4445             break;
   4446 
   4447         case BCM_TIME_CAPTURE_IP_DM_0:
   4448             capture_mode |= TIME_CAPTURE_MODE_IP_DM_0;
   4449             break;
   4450 
   4451         case BCM_TIME_CAPTURE_IP_DM_1:
   4452             capture_mode |= TIME_CAPTURE_MODE_IP_DM_1;
   4453             break;
   4454 
   4455         default:
   4456             break;
   4457         }
   4458     }
   4459 
   4460     return capture_mode;
   4461 }
   4462 
   4463 /*
   4464  * Function:
   4465  *      _bcm_esw_time_trigger_from_timestamp_mode
   4466  * Purpose: 
   4467  *      Convert Timesync capture modes to mode flags 
   4468  *
   4469  * Parameters: 
   4470  *      unit       - (IN) capture_mode
   4471  *
   4472  * Returns:
   4473  *      Capture mode flags
   4474  * Notes:
   4475  */
   4476 
   4477 STATIC uint32
   4478 _bcm_esw_time_trigger_from_timestamp_mode (uint32 capture_mode)
   4479 {
   4480     uint32 user_flags = 0;
   4481     int    bit_cnt;
   4482 
   4483     /* processing on user mode flags reduces the dependencies on 
   4484      * hardware bit maps, byte shift of mode flags
   4485      * should have been efficient 
   4486      */
   4487     for (bit_cnt = 0; bit_cnt < sizeof(uint32); bit_cnt++)
   4488     {
   4489         switch (capture_mode & (1 << bit_cnt))
   4490         {
   4491         case TIME_CAPTURE_MODE_GPIO_0:
   4492             user_flags |=  BCM_TIME_CAPTURE_GPIO_0;
   4493             break;
   4494         case TIME_CAPTURE_MODE_GPIO_1:
   4495             user_flags |=  BCM_TIME_CAPTURE_GPIO_1;
   4496             break;
   4497         case TIME_CAPTURE_MODE_GPIO_2:
   4498             user_flags |=  BCM_TIME_CAPTURE_GPIO_2;
   4499             break;
   4500         case TIME_CAPTURE_MODE_GPIO_3:
   4501             user_flags |=  BCM_TIME_CAPTURE_GPIO_3;
   4502             break;
   4503         case TIME_CAPTURE_MODE_GPIO_4:
   4504             user_flags |=  BCM_TIME_CAPTURE_GPIO_4;
   4505             break;
   4506         case TIME_CAPTURE_MODE_GPIO_5:
   4507             user_flags |=  BCM_TIME_CAPTURE_GPIO_5;
   4508             break;
   4509         case TIME_CAPTURE_MODE_L1_CLOCK_PRIMARY:
   4510             user_flags |=  BCM_TIME_CAPTURE_L1_CLOCK_PRIMARY;
   4511             break;
   4512         case TIME_CAPTURE_MODE_L1_CLOCK_SECONDARY:
   4513             user_flags |=  BCM_TIME_CAPTURE_L1_CLOCK_SECONDARY;
   4514             break;
   4515         case TIME_CAPTURE_MODE_LCPLL:
   4516             user_flags |=  BCM_TIME_CAPTURE_LCPLL;
   4517             break;
   4518         case TIME_CAPTURE_MODE_IP_DM_0:
   4519             user_flags |=  BCM_TIME_CAPTURE_IP_DM_0;
   4520             break;
   4521         case TIME_CAPTURE_MODE_IP_DM_1:
   4522             user_flags |= BCM_TIME_CAPTURE_IP_DM_1;
   4523             break;
   4524         default:
   4525             break;
   4526         }
   4527     }
   4528 
   4529     return user_flags;
   4530 }
   4531 
   4532 #endif /* (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)) */
   4533 
   4534 /*
   4535  * Function:
   4536  *      bcm_esw_time_trigger_enable_set
   4537  * Purpose:
   4538  *      Enables/Disables interrupt handling for external triggers
   4539  * Parameters:
   4540  *      unit        - (IN) StrataSwitch Unit #.
   4541  *      id          - (IN) Time Sync Interface Id
   4542  *      mode_flags  - (IN) Enable/Disable parameter
   4543  * Returns:
   4544  *      BCM_E_NONE
   4545  *      BCM_E_XXX
   4546  */
   4547 int 
   4548 bcm_esw_time_trigger_enable_set(int unit, bcm_time_if_t id, uint32 mode_flags)
   4549 {
   4550 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   4551     uint32          regval, capture_mode = 0;
   4552     soc_control_t   *soc = SOC_CONTROL(unit);
   4553 #endif
   4554 
   4555     /* Check if time feature is supported on a device */
   4556     if (!(soc_feature(unit, soc_feature_time_support) &&
   4557           (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   4558            SOC_IS_TD2_TT2(unit)))) {
   4559         return (BCM_E_UNAVAIL);
   4560     }
   4561 #if defined(BCM_TIME_V3_SUPPORT)
   4562     /* Not supported in 3rd generation time arch */
   4563     if (soc_feature(unit, soc_feature_time_v3)) {
   4564         return BCM_E_UNAVAIL;
   4565         }
   4566 #endif /* defined(BCM_TIME_V3_SUPPORT) */
   4567 
   4568 
   4569     /* Param validation check. */
   4570     BCM_IF_ERROR_RETURN(
   4571         _bcm_esw_time_interface_id_validate(unit, id));
   4572 
   4573     TIME_LOCK(unit);
   4574 
   4575 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   4576     /* 
   4577      *   Read time capture control capture modes and 
   4578      *   Convert to hardware cature mode bitmap.
   4579      *   Enable interrupt for all capture mode bitmap and
   4580      *   Write time capture mode.
   4581      *
   4582      *   If for ALL capture mode, ignore individual capture modes and
   4583      *   Enable Interrupts.
   4584      */
   4585     READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
   4586 
   4587     if (mode_flags & BCM_TIME_CAPTURE_ALL) {
   4588         /* Enable all Time capture mechanisms */
   4589         soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, 
   4590                             TIME_CAPTURE_ENABLEf, 1 );
   4591 
   4592         /* Return and  ignore setting of individual capture modes */
   4593         return BCM_E_NONE;
   4594     }
   4595 
   4596     /* Set time capture modes */
   4597     capture_mode = _bcm_esw_time_trigger_to_timestamp_mode (unit, mode_flags);
   4598 
   4599     /* Configure the HW with capture modes */
   4600     soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, 
   4601                     TIME_CAPTURE_MODEf, (capture_mode) ? capture_mode : 
   4602                     TIME_CAPTURE_MODE_DISABLE);
   4603 
   4604     /* Configure the HW to trigger interrupt for capture events */
   4605     soc_reg_field_set(unit, CMIC_TS_TIME_CAPTURE_CTRLr, &regval, INT_ENABLEf, 
   4606                       (capture_mode) ? capture_mode : 0);
   4607 
   4608     WRITE_CMIC_TS_TIME_CAPTURE_CTRLr(unit, regval);
   4609 
   4610     TIME_UNLOCK(unit);
   4611 
   4612     /* Enable/disable broadsync interrupt */
   4613     if (capture_mode) {
   4614         /* Enable Interrupt */
   4615         soc_intr_enable(unit, IRQ_BROADSYNC_INTR);
   4616         if (!soc->time_call_ref_count) {
   4617             soc->soc_time_callout = _bcm_esw_time_hw_interrupt_dflt;
   4618         }
   4619 
   4620     } else {
   4621         /* Check on the references and disable interrupt and handler */
   4622         soc_intr_disable(unit, IRQ_BROADSYNC_INTR);
   4623         if (!soc->time_call_ref_count) {
   4624             soc->soc_time_callout = NULL;
   4625         }
   4626     }
   4627 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   4628 
   4629     return (BCM_E_NONE);
   4630 }
   4631 
   4632 /*
   4633  * Function:
   4634  *      bcm_esw_time_trigger_enable_get
   4635  * Purpose:
   4636  *      Gets interrupt handling status for each heartbeat provided by a 
   4637  *      HW clock
   4638  * Parameters:
   4639  *      unit    - (IN) StrataSwitch Unit #.
   4640  *      id      - (IN) Time Sync Interface Id
   4641  *      enable  - (OUT) Enable status of interrupt handling
   4642  * Returns:
   4643  *      BCM_E_NONE
   4644  *      BCM_E_XXX
   4645  */
   4646 int 
   4647 bcm_esw_time_trigger_enable_get(int unit, bcm_time_if_t id, uint32 *mode_flags)
   4648 {
   4649 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   4650     uint32      regval, capture_mode = 0;
   4651 #endif
   4652 
   4653     /* Chek if time feature is supported on a device */
   4654     if (!(soc_feature(unit, soc_feature_time_support) &&
   4655           (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   4656            SOC_IS_TD2_TT2(unit)))) {
   4657         return (BCM_E_UNAVAIL);
   4658     }
   4659 
   4660     /* Param validation check. */
   4661     BCM_IF_ERROR_RETURN(
   4662         _bcm_esw_time_interface_id_validate(unit, id));
   4663 
   4664 #ifdef BCM_TOMAHAWK_SUPPORT
   4665     if (SOC_IS_TOMAHAWKX(unit)) {
   4666         return BCM_E_UNAVAIL;
   4667     }
   4668 #endif /* BCM_TOMAHAWK_SUPPORT */
   4669 
   4670 #if defined(BCM_TIME_V3_SUPPORT)
   4671     /* Not supported in 3rd generation time arch */
   4672     if (soc_feature(unit, soc_feature_time_v3)) {
   4673         return BCM_E_UNAVAIL;
   4674     }
   4675 #endif /* defined(BCM_TIME_V3_SUPPORT) */
   4676 
   4677 
   4678 #if (defined(BCM_KATANA2_SUPPORT) || defined(BCM_HELIX4_SUPPORT))
   4679     /* Install heartbeat and external trigger clock interval */
   4680     if (SOC_IS_KATANA2(unit) || SOC_IS_HELIX4(unit)) {
   4681         /* Read HW Configuration */
   4682         READ_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, &regval);
   4683 
   4684         /* Get interrupt enabled capture modes */
   4685         capture_mode = soc_reg_field_get(unit, CMIC_TIMESYNC_INTERRUPT_ENABLEr, regval, INT_ENABLEf); 
   4686         *mode_flags = _bcm_esw_time_trigger_from_timestamp_mode (capture_mode);
   4687     } else 
   4688 #endif
   4689     {
   4690 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT))
   4691         /* Read HW Configuration */
   4692         READ_CMIC_TS_TIME_CAPTURE_CTRLr(unit, &regval);
   4693 
   4694         /* Get interrupt enabled capture modes */
   4695         capture_mode = soc_reg_field_get(unit, CMIC_TS_TIME_CAPTURE_CTRLr, regval, INT_ENABLEf); 
   4696 
   4697         *mode_flags = _bcm_esw_time_trigger_from_timestamp_mode (capture_mode);
   4698 #endif /* (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)) */
   4699     }
   4700 
   4701     return (BCM_E_NONE);
   4702 }
   4703 
   4704 
   4705 /*
   4706  * Function:
   4707  *      bcm_esw_time_heartbeat_register
   4708  * Purpose:
   4709  *      Registers a call back function to be called on each heartbeat
   4710  * Parameters:
   4711  *      unit        - (IN) StrataSwitch Unit #.
   4712  *      id          - (IN) Time Sync Interface Id
   4713  *      f           - (IN) Function to register
   4714  *      user_data   - (IN) void pointer to store any user information
   4715  * Returns:
   4716  *      BCM_E_NONE
   4717  *      BCM_E_XXX
   4718  */
   4719 int 
   4720 bcm_esw_time_heartbeat_register (int unit, bcm_time_if_t id, bcm_time_heartbeat_cb f,
   4721                                  void *user_data)
   4722 {
   4723     soc_control_t   *soc = SOC_CONTROL(unit);
   4724 
   4725     /* Chek if time feature is supported on a device */
   4726     if (!soc_feature(unit, soc_feature_time_support)) {
   4727         return (BCM_E_UNAVAIL);
   4728     }
   4729 
   4730     /* Param validation check. */
   4731     BCM_IF_ERROR_RETURN(
   4732         _bcm_esw_time_interface_id_validate(unit, id));
   4733     if (NULL == f) {
   4734         return (BCM_E_PARAM);
   4735     }
   4736 
   4737     TIME_LOCK(unit);
   4738     /* If HW interrupt handler been registered protect from race condition */
   4739     if (soc->time_call_ref_count) {
   4740         soc->soc_time_callout = _bcm_esw_time_hw_interrupt_dflt;
   4741     }
   4742 
   4743     /* Register user call back */
   4744     TIME_INTERFACE_CONFIG(unit, id).user_cb->heartbeat_cb = f;
   4745     TIME_INTERFACE_CONFIG(unit, id).user_cb->user_data = user_data;
   4746 
   4747     /* After registering user cb function and user_data turn on 
   4748     HW interrupt handler */
   4749     soc->soc_time_callout = _bcm_esw_time_hw_interrupt;
   4750     /* Only single call back at a time is currently supported */
   4751     soc->time_call_ref_count = 1; 
   4752 
   4753     TIME_UNLOCK(unit);
   4754 
   4755     return (BCM_E_NONE);
   4756 }
   4757 
   4758 /*
   4759  * Function:
   4760  *      bcm_esw_time_heartbeat_unregister
   4761  * Purpose:
   4762  *      Unregisters a call back function to be called on each heartbeat
   4763  * Parameters:
   4764  *      unit        - (IN) StrataSwitch Unit #.
   4765  *      id          - (IN) Time Sync Interface Id
   4766  * Returns:
   4767  *      BCM_E_NONE
   4768  *      BCM_E_XXX
   4769  */
   4770 int 
   4771 bcm_esw_time_heartbeat_unregister (int unit, bcm_time_if_t id)
   4772 {
   4773     soc_control_t   *soc = SOC_CONTROL(unit);
   4774 
   4775     /* Chek if time feature is supported on a device */
   4776     if (!soc_feature(unit, soc_feature_time_support)) {
   4777         return (BCM_E_UNAVAIL);
   4778     }
   4779 
   4780     /* Param validation check. */
   4781     BCM_IF_ERROR_RETURN(
   4782         _bcm_esw_time_interface_id_validate(unit, id));
   4783 
   4784     TIME_LOCK(unit);
   4785 
   4786     if (--soc->time_call_ref_count <= 0) {
   4787         soc->time_call_ref_count = 0;
   4788         soc->soc_time_callout = _bcm_esw_time_hw_interrupt_dflt;
   4789     }
   4790     TIME_INTERFACE_CONFIG(unit, id).user_cb->heartbeat_cb = NULL;
   4791     TIME_INTERFACE_CONFIG(unit, id).user_cb->user_data = NULL;
   4792 
   4793     TIME_UNLOCK(unit);
   4794 
   4795     return (BCM_E_NONE);
   4796 }
   4797 
   4798 
   4799 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP
   4800 /*
   4801  * Function:
   4802  *     _bcm_time_sw_dump
   4803  * Purpose:
   4804  *     Displays time information maintained by software.
   4805  * Parameters:
   4806  *     unit - Device unit number
   4807  * Returns:
   4808  *     None
   4809  */
   4810 void
   4811 _bcm_time_sw_dump(int unit)
   4812 {
   4813     soc_control_t   *soc = SOC_CONTROL(unit);
   4814 
   4815     LOG_CLI((BSL_META_U(unit,
   4816                         "\nSW Information TIME - Unit %d\n"), unit));
   4817     LOG_CLI((BSL_META_U(unit,
   4818                         " Time call reference counter = %d\n"), soc->time_call_ref_count));
   4819     if (NULL != soc->soc_time_callout) {
   4820         LOG_CLI((BSL_META_U(unit,
   4821                             " Time interrupt handler address is = %p\n"),
   4822                  (void *)(unsigned long)soc->soc_time_callout));
   4823     } else {
   4824         LOG_CLI((BSL_META_U(unit,
   4825                             " Time interrupt handler is NULL \n")));
   4826     }
   4827 }
   4828 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */
   4829 
   4830 
   4831 /********************************** ESW BroadSync Time Support ***********************************/
   4832 
   4833 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
   4834     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \
   4835     defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \
   4836     defined(BCM_HURRICANE2_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) || \
   4837     defined(BCM_SABER2_SUPPORT)
   4838 STATIC
   4839 int
   4840 _bcm_esw_time_bs_init(int unit, bcm_time_interface_t *intf)
   4841 {
   4842     const int bspll_freq = 20000000; /* 20 MHz */
   4843 
   4844     uint32 regval = 0;
   4845 
   4846     int master = ((intf->flags & BCM_TIME_INPUT) == 0);
   4847     int output_enable = master && ((intf->flags & BCM_TIME_ENABLE) != 0);
   4848 
   4849     int bitclk_divisor = bspll_freq / intf->bitclock_hz;
   4850     int bitclk_high = bitclk_divisor / 2;
   4851     int bitclk_low = bitclk_divisor - bitclk_high;
   4852     int hb_divisor = intf->bitclock_hz / intf->heartbeat_hz;
   4853     int hb_up = (hb_divisor > 200) ? 100 : (hb_divisor / 2);
   4854     int hb_down = hb_divisor - hb_up;
   4855     int bs_ndiv_int = 0;
   4856 
   4857     uint32 freq_ctrl_lower = 0x40000000;  /* 4ns increment, for 250MHz TSPLL output */
   4858 
   4859 
   4860 #if defined(BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC)
   4861 /*****************************************************************************/
   4862 /*   Perform KATANA2, HELIX4, HURRICANE2, GREYHOUND, SABER2, APACHE IPROC HW configuration   */
   4863 /*****************************************************************************/
   4864     if (SOC_HAS_TIME_V3_OR_IPROC_MANAGED_BROADSYNC(unit)) {
   4865         freq_ctrl_lower = 4;  /* 4ns increment, for 250MHz TSPLL output */
   4866 
   4867         if (SOC_IS_GREYHOUND(unit) || SOC_IS_SABER2(unit) || 
   4868             SOC_IS_HURRICANE3(unit)) {
   4869             /* Feature unavailable on devices without BroadSync support. */
   4870             if (soc_feature(unit, soc_feature_time_v3_no_bs)) {
   4871                 return BCM_E_UNAVAIL;
   4872             }
   4873         }
   4874         if (SOC_IS_TOMAHAWK3(unit)) {
   4875              /* configure BS0/BS1 Clock control registers (HIGH_DURATION / LOW_DURATION) */
   4876             READ_NS_BS0_BS_CLK_CTRLr(unit, &regval);
   4877             soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   4878             soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   4879             WRITE_NS_BS0_BS_CLK_CTRLr(unit, regval);
   4880 
   4881             READ_NS_BS0_BS_CLK_CTRLr(unit, &regval);
   4882             soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   4883             WRITE_NS_BS0_BS_CLK_CTRLr(unit, regval);
   4884 
   4885             READ_NS_BS1_BS_CLK_CTRLr(unit, &regval);
   4886             soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   4887             soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   4888             WRITE_NS_BS1_BS_CLK_CTRLr(unit, regval);
   4889 
   4890             READ_NS_BS1_BS_CLK_CTRLr(unit, &regval);
   4891             soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   4892             WRITE_NS_BS1_BS_CLK_CTRLr(unit, regval);
   4893 
   4894             /* configure BS0/BS1 Clock configuration registers */
   4895             READ_NS_BS0_BS_CONFIGr(unit, &regval);
   4896             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   4897             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   4898             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   4899             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   4900             WRITE_NS_BS0_BS_CONFIGr(unit, regval);
   4901 
   4902             READ_NS_BS1_BS_CONFIGr(unit, &regval);
   4903             soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   4904             soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   4905             soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   4906             soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   4907             WRITE_NS_BS1_BS_CONFIGr(unit, regval);
   4908 
   4909             READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, &regval);
   4910             soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr, &regval, LINCf, freq_ctrl_lower);
   4911             WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, regval);
   4912 
   4913             READ_NS_TIMESYNC_TS0_CURRENT_FREQ_CTRL_LOWERr(unit, &regval);
   4914             soc_reg_field_set(unit, NS_TIMESYNC_TS0_CURRENT_FREQ_CTRL_LOWERr, &regval, FCLf, 0);
   4915             WRITE_NS_TIMESYNC_TS0_CURRENT_FREQ_CTRL_LOWERr(unit, regval);
   4916 
   4917             READ_NS_TIMESYNC_TS0_CURRENT_FREQ_CTRL_UPPERr(unit, &regval);
   4918             soc_reg_field_set(unit, NS_TIMESYNC_TS0_CURRENT_FREQ_CTRL_UPPERr, &regval, FCUf, 0);
   4919             WRITE_NS_TIMESYNC_TS0_CURRENT_FREQ_CTRL_UPPERr(unit, regval);
   4920 
   4921             READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &regval);
   4922             soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &regval, ENABLEf, 1);
   4923             WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, regval);
   4924 
   4925             /* Setup BS0/BS1 HeartBeat Control registers */
   4926             READ_NS_BS0_BS_HEARTBEAT_CTRLr(unit, &regval);
   4927             soc_reg_field_set(unit, NS_BS0_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   4928             WRITE_NS_BS0_BS_HEARTBEAT_CTRLr(unit, regval);
   4929 
   4930             READ_NS_BS1_BS_HEARTBEAT_CTRLr(unit, &regval);
   4931             soc_reg_field_set(unit, NS_BS1_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   4932             WRITE_NS_BS1_BS_HEARTBEAT_CTRLr(unit, regval);
   4933 
   4934             READ_NS_BS0_BS_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   4935             soc_reg_field_set(unit, NS_BS0_BS_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, hb_down);
   4936             WRITE_NS_BS0_BS_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   4937 
   4938             READ_NS_BS1_BS_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   4939             soc_reg_field_set(unit, NS_BS1_BS_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, hb_down);
   4940             WRITE_NS_BS1_BS_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   4941 
   4942             READ_NS_BS0_BS_HEARTBEAT_UP_DURATIONr(unit, &regval);
   4943             soc_reg_field_set(unit, NS_BS0_BS_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, hb_up);
   4944             WRITE_NS_BS0_BS_HEARTBEAT_UP_DURATIONr(unit, regval);
   4945 
   4946             READ_NS_BS1_BS_HEARTBEAT_UP_DURATIONr(unit, &regval);
   4947             soc_reg_field_set(unit, NS_BS1_BS_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, hb_up);
   4948             WRITE_NS_BS1_BS_HEARTBEAT_UP_DURATIONr(unit, regval);
   4949 
   4950             READ_NS_BS0_BS_CLK_CTRLr(unit, &regval);
   4951             soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, ENABLEf, 0);
   4952             WRITE_NS_BS0_BS_CLK_CTRLr(unit, regval);
   4953 
   4954             READ_NS_BS1_BS_CLK_CTRLr(unit, &regval);
   4955             soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, ENABLEf, 0);
   4956             WRITE_NS_BS1_BS_CLK_CTRLr(unit, regval);
   4957 
   4958             READ_NS_BROADSYNC_REF_CLK_GEN_CTRLr(unit, &regval);
   4959             soc_reg_field_set(unit, NS_BROADSYNC_REF_CLK_GEN_CTRLr, &regval, ENABLEf, 0);
   4960             WRITE_NS_BROADSYNC_REF_CLK_GEN_CTRLr(unit, regval);
   4961 
   4962             /* configure BS0/BS1 Clock control registers (HIGH_DURATION / LOW_DURATION) */
   4963             READ_NS_BS0_BS_CLK_CTRLr(unit, &regval);
   4964             soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   4965             soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   4966             WRITE_NS_BS0_BS_CLK_CTRLr(unit, regval);
   4967 
   4968             READ_NS_BS0_BS_CLK_CTRLr(unit, &regval);
   4969             soc_reg_field_set(unit, NS_BS0_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   4970             WRITE_NS_BS0_BS_CLK_CTRLr(unit, regval);
   4971 
   4972             READ_NS_BS1_BS_CLK_CTRLr(unit, &regval);
   4973             soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   4974             soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   4975             WRITE_NS_BS1_BS_CLK_CTRLr(unit, regval);
   4976 
   4977             READ_NS_BS1_BS_CLK_CTRLr(unit, &regval);
   4978             soc_reg_field_set(unit, NS_BS1_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   4979             WRITE_NS_BS1_BS_CLK_CTRLr(unit, regval);
   4980 
   4981             /* configure BS0/BS1 Clock configuration registers */
   4982             READ_NS_BS0_BS_CONFIGr(unit, &regval);
   4983             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   4984             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   4985             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   4986             soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   4987             WRITE_NS_BS0_BS_CONFIGr(unit, regval);
   4988 
   4989             READ_NS_BS1_BS_CONFIGr(unit, &regval);
   4990             soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   4991             soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   4992             soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   4993             soc_reg_field_set(unit, NS_BS1_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   4994             WRITE_NS_BS1_BS_CONFIGr(unit, regval);
   4995       } else {
   4996 
   4997             /* configure BS0/BS1 Clock control registers (HIGH_DURATION / LOW_DURATION) */
   4998             READ_CMIC_BS0_CLK_CTRLr(unit, &regval);
   4999             soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   5000             soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   5001             WRITE_CMIC_BS0_CLK_CTRLr(unit, regval);
   5002 
   5003             READ_CMIC_BS0_CLK_CTRLr(unit, &regval);
   5004             soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, ENABLEf, 1);
   5005             WRITE_CMIC_BS0_CLK_CTRLr(unit, regval);
   5006 
   5007             READ_CMIC_BS1_CLK_CTRLr(unit, &regval);
   5008             soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   5009             soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   5010             WRITE_CMIC_BS1_CLK_CTRLr(unit, regval);
   5011 
   5012             READ_CMIC_BS1_CLK_CTRLr(unit, &regval);
   5013             soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, ENABLEf, 1);
   5014             WRITE_CMIC_BS1_CLK_CTRLr(unit, regval);
   5015 
   5016             /* configure BS0/BS1 Clock configuration registers */
   5017             READ_CMIC_BS0_CONFIGr(unit, &regval);
   5018             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   5019             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   5020             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   5021             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   5022             WRITE_CMIC_BS0_CONFIGr(unit, regval);
   5023 
   5024             READ_CMIC_BS1_CONFIGr(unit, &regval);
   5025             soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   5026             soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   5027             soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   5028             soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   5029             WRITE_CMIC_BS1_CONFIGr(unit, regval);
   5030 
   5031             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, &regval);
   5032             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr, &regval, FRACf, freq_ctrl_lower);
   5033             WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, regval);
   5034 
   5035             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_LOWERr(unit, &regval);
   5036             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_LOWERr, &regval, NSf, 0);
   5037             WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_LOWERr(unit, regval);
   5038 
   5039             READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr(unit, &regval);
   5040             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr, &regval, NSf, 0);
   5041             WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_UPPERr(unit, regval);
   5042 
   5043             READ_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &regval);
   5044             soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_COUNTER_ENABLEr, &regval, ENABLEf, 1);
   5045             WRITE_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, regval);
   5046 
   5047             /* Setup BS0/BS1 HeartBeat Control registers */
   5048             READ_CMIC_BS0_HEARTBEAT_CTRLr(unit, &regval);
   5049             soc_reg_field_set(unit, CMIC_BS0_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   5050             WRITE_CMIC_BS0_HEARTBEAT_CTRLr(unit, regval);
   5051 
   5052             READ_CMIC_BS1_HEARTBEAT_CTRLr(unit, &regval);
   5053             soc_reg_field_set(unit, CMIC_BS1_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   5054             WRITE_CMIC_BS1_HEARTBEAT_CTRLr(unit, regval);
   5055 
   5056             READ_CMIC_BS0_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   5057             soc_reg_field_set(unit, CMIC_BS0_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, hb_down);
   5058             WRITE_CMIC_BS0_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   5059 
   5060             READ_CMIC_BS1_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   5061             soc_reg_field_set(unit, CMIC_BS1_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, hb_down);
   5062             WRITE_CMIC_BS1_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   5063 
   5064             READ_CMIC_BS0_HEARTBEAT_UP_DURATIONr(unit, &regval);
   5065             soc_reg_field_set(unit, CMIC_BS0_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, hb_up);
   5066             WRITE_CMIC_BS0_HEARTBEAT_UP_DURATIONr(unit, regval);
   5067 
   5068             READ_CMIC_BS1_HEARTBEAT_UP_DURATIONr(unit, &regval);
   5069             soc_reg_field_set(unit, CMIC_BS1_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, hb_up);
   5070             WRITE_CMIC_BS1_HEARTBEAT_UP_DURATIONr(unit, regval);
   5071 
   5072             READ_CMIC_BS0_CLK_CTRLr(unit, &regval);
   5073             soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, ENABLEf, 0);
   5074             WRITE_CMIC_BS0_CLK_CTRLr(unit, regval);
   5075 
   5076             READ_CMIC_BS1_CLK_CTRLr(unit, &regval);
   5077             soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, ENABLEf, 0);
   5078             WRITE_CMIC_BS1_CLK_CTRLr(unit, regval);
   5079 
   5080             READ_CMIC_BROADSYNC_REF_CLK_GEN_CTRLr(unit, &regval);
   5081             soc_reg_field_set(unit, CMIC_BROADSYNC_REF_CLK_GEN_CTRLr, &regval, ENABLEf, 0);
   5082             WRITE_CMIC_BROADSYNC_REF_CLK_GEN_CTRLr(unit, regval);
   5083 
   5084             /* configure BS0/BS1 Clock control registers (HIGH_DURATION / LOW_DURATION) */
   5085             READ_CMIC_BS0_CLK_CTRLr(unit, &regval);
   5086             soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   5087             soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   5088             WRITE_CMIC_BS0_CLK_CTRLr(unit, regval);
   5089 
   5090             READ_CMIC_BS0_CLK_CTRLr(unit, &regval);
   5091             soc_reg_field_set(unit, CMIC_BS0_CLK_CTRLr, &regval, ENABLEf, 1);
   5092             WRITE_CMIC_BS0_CLK_CTRLr(unit, regval);
   5093 
   5094             READ_CMIC_BS1_CLK_CTRLr(unit, &regval);
   5095             soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   5096             soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   5097             WRITE_CMIC_BS1_CLK_CTRLr(unit, regval);
   5098 
   5099             READ_CMIC_BS1_CLK_CTRLr(unit, &regval);
   5100             soc_reg_field_set(unit, CMIC_BS1_CLK_CTRLr, &regval, ENABLEf, 1);
   5101             WRITE_CMIC_BS1_CLK_CTRLr(unit, regval);
   5102 
   5103             /* configure BS0/BS1 Clock configuration registers */
   5104             READ_CMIC_BS0_CONFIGr(unit, &regval);
   5105             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   5106             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   5107             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   5108             soc_reg_field_set(unit, CMIC_BS0_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   5109             WRITE_CMIC_BS0_CONFIGr(unit, regval);
   5110 
   5111             READ_CMIC_BS1_CONFIGr(unit, &regval);
   5112             soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   5113             soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   5114             soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   5115             soc_reg_field_set(unit, CMIC_BS1_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   5116             WRITE_CMIC_BS1_CONFIGr(unit, regval);
   5117         }
   5118     } else
   5119 #endif /* BCM_TIME_V3_OR_IPROC_MANAGED_BROADSYNC */
   5120 /*****************************************************************************/
   5121 /*        Non-KATANA2, HELIX4, HURRICANE2, GREYHOUND HW configuration        */
   5122 /*****************************************************************************/
   5123     {
   5124 #if defined(BCM_KATANA_SUPPORT)
   5125         if (SOC_IS_KATANA(unit)) {
   5126             READ_TOP_BROAD_SYNC_PLL_CTRL_REGISTER_3r(unit, &regval);
   5127             bs_ndiv_int = soc_reg_field_get(unit, TOP_BROAD_SYNC_PLL_CTRL_REGISTER_3r,
   5128                                             regval, NDIV_INTf);
   5129         }
   5130 #endif /* defined(BCM_KATANA_SUPPORT) */
   5131 
   5132 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   5133         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_TD2P_TT2P(unit)) {
   5134             READ_TOP_BS_PLL_CTRL_3r(unit, &regval);
   5135             bs_ndiv_int = soc_reg_field_get(unit, TOP_BS_PLL_CTRL_3r,
   5136                                             regval, NDIV_INTf);
   5137             bs_ndiv_int = (regval & 0x3ff);
   5138         } else if (SOC_IS_TD2P_TT2P(unit)) {
   5139             READ_TOP_BS_PLL_CTRL_4r(unit, &regval);
   5140             bs_ndiv_int = soc_reg_field_get(unit, TOP_BS_PLL_CTRL_4r,
   5141                                             regval, NDIV_INTf);
   5142             bs_ndiv_int = (regval & 0x3ff);
   5143        }
   5144 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) */
   5145 
   5146         if (bs_ndiv_int == 300) {
   5147             /* Take a BroadSync NDIV_INT value of 0 as a signal that the input
   5148              * reference frequency is 12.8 MHz, so TSPLL will produce 248MHz,
   5149              * not 250MHz
   5150              */
   5151             freq_ctrl_lower = 0x40842108;
   5152         }
   5153 
   5154 #if defined(BCM_TRIDENT2_SUPPORT)
   5155         if (SOC_IS_TD2_TT2(unit)) {
   5156             /* m top_soft_reset_reg_2 top_bs_pll_rst_l=0 top_bs_pll_post_rst_l=0 */
   5157             READ_TOP_SOFT_RESET_REG_2r(unit, &regval);
   5158             soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &regval, TOP_BS_PLL_RST_Lf, 0);
   5159             soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &regval, TOP_BS_PLL_POST_RST_Lf, 0);
   5160             WRITE_TOP_SOFT_RESET_REG_2r(unit, regval);
   5161 
   5162             if (!SOC_IS_TD2P_TT2P(unit)) {
   5163                 /* m TOP_BS_PLL_CTRL_0 VCO_DIV2=1 */
   5164                 READ_TOP_BS_PLL_CTRL_0r(unit, &regval);
   5165                 soc_reg_field_set(unit, TOP_BS_PLL_CTRL_0r, &regval, VCO_DIV2f, 1);
   5166                 WRITE_TOP_BS_PLL_CTRL_0r(unit, regval);
   5167 
   5168                 /* m TOP_BS_PLL_CTRL_2 PDIV=1 CH0_MDIV=175 */
   5169                 READ_TOP_BS_PLL_CTRL_2r(unit, &regval);
   5170                 soc_reg_field_set(unit, TOP_BS_PLL_CTRL_2r, &regval, PDIVf, 1);
   5171                 soc_reg_field_set(unit, TOP_BS_PLL_CTRL_2r, &regval, CH0_MDIVf, 175);
   5172                 WRITE_TOP_BS_PLL_CTRL_2r(unit, regval);
   5173             } else {
   5174 
   5175                 READ_TOP_BS_PLL_CTRL_0r(unit, &regval);
   5176                 soc_reg_field_set(unit, TOP_BS_PLL_CTRL_0r, &regval, VCO_FB_DIV2f, 1);
   5177                 WRITE_TOP_BS_PLL_CTRL_0r(unit, regval);
   5178 
   5179                 /* TD2+: Keeping default for VCO_DIV2(=1), NDIV(=140.0), PDIV(=1) */
   5180                 READ_TOP_BS_PLL_CTRL_3r(unit, &regval);
   5181                 soc_reg_field_set(unit, TOP_BS_PLL_CTRL_3r, &regval, PDIVf, 1);
   5182                 soc_reg_field_set(unit, TOP_BS_PLL_CTRL_3r, &regval, CH0_MDIVf, 175);
   5183                 WRITE_TOP_BS_PLL_CTRL_3r(unit, regval);
   5184             }
   5185 
   5186             /* m top_soft_reset_reg_2 top_bs_pll_rst_l=1 */
   5187             READ_TOP_SOFT_RESET_REG_2r(unit, &regval);
   5188             soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &regval, TOP_BS_PLL_RST_Lf, 1);
   5189             WRITE_TOP_SOFT_RESET_REG_2r(unit, regval);
   5190 
   5191             /* m top_soft_reset_reg_2 top_bs_pll_post_rst_l=1 */
   5192             READ_TOP_SOFT_RESET_REG_2r(unit, &regval);
   5193             soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &regval, TOP_BS_PLL_POST_RST_Lf, 1);
   5194             WRITE_TOP_SOFT_RESET_REG_2r(unit, regval);
   5195         }
   5196 #endif /* defined(BCM_TRIDENT2_SUPPORT) */
   5197 
   5198         if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) {
   5199 
   5200             /* Validate calculated output based on bitclock_hz */
   5201             if(SOC_FAILURE(soc_reg_field_validate(unit, CMIC_BS_CLK_CTRLr,
   5202                                                        LOW_DURATIONf, bitclk_low))) {
   5203                return BCM_E_PARAM;
   5204             } 
   5205             if(SOC_FAILURE(soc_reg_field_validate(unit, CMIC_BS_CLK_CTRLr,
   5206                                                     HIGH_DURATIONf, bitclk_high))) {
   5207                return BCM_E_PARAM;
   5208             } 
   5209 
   5210             /* m CMIC_BS_CLK_CTRL LOW_DURATION=1 HIGH_DURATION=1 */
   5211             READ_CMIC_BS_CLK_CTRLr(unit, &regval);
   5212             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   5213             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   5214             WRITE_CMIC_BS_CLK_CTRLr(unit, regval);
   5215 
   5216             /* m CMIC_BS_CLK_CTRL ENABLE=1 */
   5217             READ_CMIC_BS_CLK_CTRLr(unit, &regval);
   5218             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   5219             WRITE_CMIC_BS_CLK_CTRLr(unit, regval);
   5220 
   5221             /* m CMIC_BS_CONFIG BS_CLK_OUTPUT_ENABLE=1 BS_HB_OUTPUT_ENABLE=1 BS_TC_OUTPUT_ENABLE=1 */
   5222             READ_CMIC_BS_CONFIGr(unit, &regval);
   5223             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   5224             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   5225             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, BS_TC_OUTPUT_ENABLEf, output_enable);
   5226             WRITE_CMIC_BS_CONFIGr(unit, regval);
   5227 
   5228             READ_CMIC_TS_FREQ_CTRL_LOWERr(unit, &regval);
   5229             soc_reg_field_set(unit, CMIC_TS_FREQ_CTRL_LOWERr, &regval, FRACf, freq_ctrl_lower);
   5230             WRITE_CMIC_TS_FREQ_CTRL_LOWERr(unit, regval);
   5231 
   5232             /* m CMIC_TS_FREQ_CTRL_UPPER ENABLE=1 */
   5233             READ_CMIC_TS_FREQ_CTRL_UPPERr(unit, &regval);
   5234             soc_reg_field_set(unit, CMIC_TS_FREQ_CTRL_UPPERr, &regval, ENABLEf, 1);
   5235             WRITE_CMIC_TS_FREQ_CTRL_UPPERr(unit, regval);
   5236 
   5237             /* m CMIC_BS_HEARTBEAT_CTRL ENABLE=1 */
   5238             READ_CMIC_BS_HEARTBEAT_CTRLr(unit, &regval);
   5239             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_CTRLr, &regval, ENABLEf, 1);
   5240             WRITE_CMIC_BS_HEARTBEAT_CTRLr(unit, regval);
   5241 
   5242             /* m CMIC_BS_HEARTBEAT_DOWN_DURATION DOWN_DURATION=2400 */
   5243             /* Validate calculated hb_down based on heartbeat_hz */
   5244             if(SOC_FAILURE(soc_reg_field_validate(unit,
   5245                                                   CMIC_BS_HEARTBEAT_DOWN_DURATIONr,
   5246                                                           DOWN_DURATIONf, hb_down))) {
   5247                return BCM_E_PARAM;
   5248             }
   5249             READ_CMIC_BS_HEARTBEAT_DOWN_DURATIONr(unit, &regval);
   5250             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_DOWN_DURATIONr, &regval, DOWN_DURATIONf, hb_down);
   5251             WRITE_CMIC_BS_HEARTBEAT_DOWN_DURATIONr(unit, regval);
   5252 
   5253             /* m CMIC_BS_HEARTBEAT_UP_DURATION UP_DURATION=100 */
   5254             READ_CMIC_BS_HEARTBEAT_UP_DURATIONr(unit, &regval);
   5255             soc_reg_field_set(unit, CMIC_BS_HEARTBEAT_UP_DURATIONr, &regval, UP_DURATIONf, hb_up);
   5256             WRITE_CMIC_BS_HEARTBEAT_UP_DURATIONr(unit, regval);
   5257 
   5258             /* m CMIC_BS_CLK_CTRL ENABLE=0 */
   5259             READ_CMIC_BS_CLK_CTRLr(unit, &regval);
   5260             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, ENABLEf, 0);
   5261             WRITE_CMIC_BS_CLK_CTRLr(unit, regval);
   5262 
   5263             /* m CMIC_BS_REF_CLK_GEN_CTRL ENABLE=0 */
   5264             /* BS_REF_CLK from BS_PLL_CLK rather than BS_REF_CLK_generated */
   5265 
   5266             READ_CMIC_BS_REF_CLK_GEN_CTRLr(unit, &regval);
   5267             soc_reg_field_set(unit, CMIC_BS_REF_CLK_GEN_CTRLr, &regval, ENABLEf, 0);
   5268             WRITE_CMIC_BS_REF_CLK_GEN_CTRLr(unit, regval);
   5269 
   5270             /* m CMIC_BS_CLK_CTRL ENABLE=1 LOW_DURATION=1 HIGH_DURATION=1 */
   5271             READ_CMIC_BS_CLK_CTRLr(unit, &regval);
   5272             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, ENABLEf, 1);
   5273             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, LOW_DURATIONf, bitclk_low);
   5274             soc_reg_field_set(unit, CMIC_BS_CLK_CTRLr, &regval, HIGH_DURATIONf, bitclk_high);
   5275             WRITE_CMIC_BS_CLK_CTRLr(unit, regval);
   5276 
   5277             /* m CMIC_BS_CONFIG MODE=1 BS_CLK_OUTPUT_ENABLE=1 BS_HB_OUTPUT_ENABLE=1 */
   5278             READ_CMIC_BS_CONFIGr(unit, &regval);
   5279             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, MODEf, master ? TIME_MODE_OUTPUT : TIME_MODE_INPUT);
   5280             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, BS_CLK_OUTPUT_ENABLEf, output_enable);
   5281             soc_reg_field_set(unit, CMIC_BS_CONFIGr, &regval, BS_HB_OUTPUT_ENABLEf, output_enable);
   5282             WRITE_CMIC_BS_CONFIGr(unit, regval);
   5283         }
   5284     }
   5285 
   5286     return BCM_E_NONE;
   5287 }
   5288 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) ||
   5289           defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) ||
   5290           defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||
   5291           defined(BCM_HURRICANE2_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) ||
   5292           defiend(BCM_SABER2_SUPPORT) */
   5293 #if defined(BCM_HELIX4_SUPPORT)
   5294 #define BCM_TIME_HX4_L1_FREQ_SEL_MODE(x) (((x) >= 0) && ((x) <= 3))
   5295 #define BCM_TIME_HX4_PORT_VALID(x) (((x) >= 1 && (x) <= 48 ) || ((x)>=65 && (x) <= 66))
   5296 #define BCM_TIME_HX4_CLK_SRC_VALID(x) \
   5297     (((x) == bcmTimeSynceClockSourcePrimary) || \
   5298      ((x) == bcmTimeSynceClockSourceSecondary) )
   5299 
   5300 /*
   5301  * Function:
   5302  *      _bcm_esw_time_hx4_synce_clock_set
   5303  * Purpose:
   5304  *      Set syncE divisor setting
   5305  * Parameters:
   5306  *      unit      - (IN) Unit number.
   5307  *      clk_src   - (IN) clock source type (Primary, Secondary)
   5308  *      input_src - (IN) input source type (PORT)
   5309  *      index     - (IN) if input_src is PORT, specify  port number 1..48(physical port) or 65..66(LCPLL ports)
   5310  *      divisor   - (IN) divisor setting.
   5311  * Returns:
   5312  *      BCM_E_xxx
   5313  * Notes:
   5314  */
   5315 STATIC int
   5316 _bcm_esw_time_hx4_synce_clock_set(int unit,
   5317                               bcm_time_synce_clock_src_type_t clk_src,
   5318                               bcm_time_synce_divisor_setting_t *divisor)
   5319 {
   5320     /* Assumes input index is logical port number */
   5321     int phy_port = divisor->index;
   5322     int port_sel;
   5323 
   5324     if (!BCM_TIME_HX4_PORT_VALID(phy_port) ||
   5325         !BCM_TIME_HX4_CLK_SRC_VALID(clk_src) ||
   5326         (phy_port == -1)) {
   5327         return BCM_E_PARAM;
   5328     }
   5329 
   5330     port_sel = phy_port - 1;
   5331     if ( clk_src == bcmTimeSynceClockSourcePrimary ) {
   5332         /* TOP_MISC_CONTROL_1 */
   5333         SOC_IF_ERROR_RETURN
   5334             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5335                                     L1_RCVD_CLK_RSTNf, 0));
   5336         /* TOP_MISC_CONTROL_1 */
   5337         SOC_IF_ERROR_RETURN
   5338             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5339                                     L1_RCVD_FREQ_SELf, divisor->stage0_mode));
   5340         /* EGR_L1_CLK_RECOVERY_CTRL */
   5341         SOC_IF_ERROR_RETURN
   5342             (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   5343                                     REG_PORT_ANY, PRI_PORT_SELf, port_sel));
   5344 
   5345         /* Enable L1 prim recov clk as valid,default it is invalid  */
   5346         SOC_IF_ERROR_RETURN
   5347             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5348                                     L1_RCVD_SW_OVWR_VALIDf, 1));
   5349         SOC_IF_ERROR_RETURN
   5350             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5351                                     L1_RCVD_SW_OVWR_ENf, 1));
   5352 
   5353         /* TOP_MISC_CONTROL_1 */
   5354         SOC_IF_ERROR_RETURN
   5355             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5356                                     L1_RCVD_CLK_RSTNf, 1));
   5357     } else { /* Secondary/Backup SyncE source */
   5358         /* TOP_MISC_CONTROL_1 */
   5359         SOC_IF_ERROR_RETURN
   5360             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5361                                     L1_RCVD_CLK_BKUP_RSTNf, 0));
   5362         /* TOP_MISC_CONTROL_1 */
   5363         SOC_IF_ERROR_RETURN
   5364             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5365                                     L1_RCVD_BKUP_FREQ_SELf, divisor->stage0_mode));
   5366         /* EGR_L1_CLK_RECOVERY_CTRL */
   5367         SOC_IF_ERROR_RETURN
   5368             (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   5369                                     REG_PORT_ANY, BKUP_PORT_SELf, port_sel));
   5370 
   5371         /* Enable L1 sec/bkp recov clk as valid,default it is invalid  */
   5372         SOC_IF_ERROR_RETURN
   5373             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5374                                     L1_RCVD_SW_OVWR_BKUP_VALIDf, 1));
   5375         SOC_IF_ERROR_RETURN
   5376             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5377                                     L1_RCVD_SW_OVWR_ENf, 1));
   5378 
   5379         /* TOP_MISC_CONTROL_1 */
   5380         SOC_IF_ERROR_RETURN
   5381             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   5382                                     L1_RCVD_CLK_BKUP_RSTNf, 1));
   5383     }
   5384     return BCM_E_NONE;
   5385 }
   5386 
   5387 /*
   5388  * Function:
   5389  *      _bcm_esw_time_hx4_synce_clock_get
   5390  * Purpose:
   5391  *      Get current setting of syncE clock divisor
   5392  * Parameters:
   5393  *      unit    - (IN)  Unit number.
   5394         divisor - (OUT) Divisor setting
   5395  * Returns:
   5396  *      BCM_E_xxx
   5397  * Notes:
   5398  */
   5399 STATIC int
   5400 _bcm_esw_time_hx4_synce_clock_get(int unit,
   5401                               bcm_time_synce_clock_src_type_t clk_src,
   5402                               bcm_time_synce_divisor_setting_t *divisor)
   5403 {
   5404     uint32 val, phy_port, rval;
   5405 
   5406     switch(clk_src) {
   5407     case bcmTimeSynceClockSourcePrimary:
   5408         /* input source */
   5409         SOC_IF_ERROR_RETURN(
   5410              READ_EGR_L1_CLK_RECOVERY_CTRLr(unit, &rval));
   5411         val = soc_reg_field_get(unit, EGR_L1_CLK_RECOVERY_CTRLr, rval,
   5412                                      PRI_PORT_SELf);
   5413         phy_port = val+ 1;
   5414         divisor->input_src = bcmTimeSynceInputSourceTypePort;
   5415         divisor->index = phy_port;
   5416 
   5417         SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_1r(unit, &rval));
   5418         /* Freq div mode */
   5419         divisor->stage0_mode = soc_reg_field_get(unit, TOP_MISC_CONTROL_1r,
   5420                                                  rval, L1_RCVD_FREQ_SELf);
   5421         break;
   5422     case bcmTimeSynceClockSourceSecondary:
   5423         /* input source */
   5424         SOC_IF_ERROR_RETURN(
   5425              READ_EGR_L1_CLK_RECOVERY_CTRLr(unit, &rval));
   5426         val= soc_reg_field_get(unit, EGR_L1_CLK_RECOVERY_CTRLr, rval,
   5427                                      BKUP_PORT_SELf);
   5428         phy_port = val+ 1;
   5429         divisor->input_src = bcmTimeSynceInputSourceTypePort;
   5430         divisor->index = phy_port;
   5431 
   5432         SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_1r(unit, &rval));
   5433         /* Freq div mode */
   5434         divisor->stage0_mode = soc_reg_field_get(unit, TOP_MISC_CONTROL_1r,
   5435                                                  rval, L1_RCVD_BKUP_FREQ_SELf);
   5436         break;
   5437     default:
   5438         return BCM_E_PARAM;
   5439     }
   5440 
   5441     return BCM_E_NONE;
   5442 }
   5443 
   5444 #endif /* defined(BCM_HELIX4_SUPPORT */
   5445 
   5446 #if defined(BCM_GREYHOUND_SUPPORT)
   5447 #define BCM_TIME_GH_L1_FREQ_SEL_MODE(x) (((x) >= 0) && ((x) <= 3))
   5448 #define BCM_TIME_GH_PORT_VALID(x) (((x) >= 1 && (x) <= 48 ) || ((x)>=65 && (x) <= 66))
   5449 #define BCM_TIME_GH_CLK_SRC_VALID(x) \
   5450     (((x) == bcmTimeSynceClockSourcePrimary) || \
   5451      ((x) == bcmTimeSynceClockSourceSecondary) )
   5452 
   5453 /*
   5454  * Function:
   5455  *      _bcm_esw_time_gh_synce_clock_set
   5456  * Purpose:
   5457  *      Set syncE divisor setting
   5458  * Parameters:
   5459  *      unit      - (IN) Unit number.
   5460  *      clk_src   - (IN) clock source type (Primary, Secondary)
   5461  *      input_src - (IN) input source type (PORT)
   5462  *      index     - (IN) if input_src is PORT, specify  port number 1..48(physical port) or 65..66(LCPLL ports)
   5463  *      divisor   - (IN) divisor setting.
   5464  * Returns:
   5465  *      BCM_E_xxx
   5466  * Notes:
   5467  */
   5468 STATIC int
   5469 _bcm_esw_time_gh_synce_clock_set(int unit,
   5470                               bcm_time_synce_clock_src_type_t clk_src,
   5471                               bcm_time_synce_divisor_setting_t *divisor)
   5472 {
   5473     /* Assumes input index is logical port number */
   5474     int phy_port = divisor->index;
   5475     int port_sel;
   5476 
   5477     if (!BCM_TIME_GH_PORT_VALID(phy_port) ||
   5478         !BCM_TIME_GH_CLK_SRC_VALID(clk_src) ||
   5479         (phy_port == -1)) {
   5480         return BCM_E_PARAM;
   5481     }
   5482     
   5483     if (!SOC_PORT_VALID(unit,phy_port))
   5484     {
   5485         return BCM_E_PARAM;
   5486     }
   5487 
   5488     port_sel = phy_port - 1;
   5489     if ( clk_src == bcmTimeSynceClockSourcePrimary ) {
   5490         /* TOP_MISC_CONTROL_2 */
   5491         SOC_IF_ERROR_RETURN
   5492             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5493                                     L1_RCVD_CLK_RSTNf, 0));
   5494         /* TOP_MISC_CONTROL_2 */
   5495         SOC_IF_ERROR_RETURN
   5496             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5497                                     L1_RCVD_FREQ_SELf, divisor->stage0_mode));
   5498         /* TOP_MISC_CONTROL_2 */
   5499         SOC_IF_ERROR_RETURN
   5500             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r,
   5501                                     REG_PORT_ANY, L1_RCVD_PRI_CLK_PORT_SELf, port_sel));
   5502 
   5503         /* Enable L1 prim recov clk as valid,default it is invalid  */
   5504         SOC_IF_ERROR_RETURN
   5505             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5506                                     L1_RCVD_SW_OVWR_VALIDf, 1));
   5507         SOC_IF_ERROR_RETURN
   5508             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5509                                     L1_RCVD_SW_OVWR_ENf, 1));
   5510 
   5511         /* TOP_MISC_CONTROL_2 */
   5512         SOC_IF_ERROR_RETURN
   5513             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5514                                     L1_RCVD_CLK_RSTNf, 1));
   5515     } else { /* Secondary/Backup SyncE source */
   5516         /* TOP_MISC_CONTROL_2 */
   5517         SOC_IF_ERROR_RETURN
   5518             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5519                                     L1_RCVD_CLK_BKUP_RSTNf, 0));
   5520         /* TOP_MISC_CONTROL_2 */
   5521         SOC_IF_ERROR_RETURN
   5522             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5523                                     L1_RCVD_BKUP_FREQ_SELf, divisor->stage0_mode));
   5524         /* TOP_MISC_CONTROL_2 */
   5525         SOC_IF_ERROR_RETURN
   5526             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r,
   5527                                     REG_PORT_ANY, L1_RCVD_BKUP_CLK_PORT_SELf, port_sel));
   5528 
   5529         /* Enable L1 sec/bkp recov clk as valid,default it is invalid  */
   5530         SOC_IF_ERROR_RETURN
   5531             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5532                                     L1_RCVD_SW_OVWR_BKUP_VALIDf, 1));
   5533         SOC_IF_ERROR_RETURN
   5534             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5535                                     L1_RCVD_SW_OVWR_ENf, 1));
   5536 
   5537         /* TOP_MISC_CONTROL_2 */
   5538         SOC_IF_ERROR_RETURN
   5539             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   5540                                     L1_RCVD_CLK_BKUP_RSTNf, 1));
   5541     }
   5542     return BCM_E_NONE;
   5543 }
   5544 
   5545 /*
   5546  * Function:
   5547  *      _bcm_esw_time_gh_synce_clock_get
   5548  * Purpose:
   5549  *      Get current setting of syncE clock divisor
   5550  * Parameters:
   5551  *      unit    - (IN)  Unit number.
   5552         divisor - (OUT) Divisor setting
   5553  * Returns:
   5554  *      BCM_E_xxx
   5555  * Notes:
   5556  */
   5557 STATIC int
   5558 _bcm_esw_time_gh_synce_clock_get(int unit,
   5559                               bcm_time_synce_clock_src_type_t clk_src,
   5560                               bcm_time_synce_divisor_setting_t *divisor)
   5561 {
   5562     uint32 val, phy_port, rval;
   5563 
   5564     switch(clk_src) {
   5565     case bcmTimeSynceClockSourcePrimary:
   5566         /* input source */
   5567         SOC_IF_ERROR_RETURN(
   5568              READ_TOP_MISC_CONTROL_2r(unit, &rval));
   5569         val = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval,
   5570                                     L1_RCVD_PRI_CLK_PORT_SELf);
   5571         phy_port = val+ 1;
   5572         divisor->input_src = bcmTimeSynceInputSourceTypePort;
   5573         divisor->index = phy_port;
   5574 
   5575         SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_2r(unit, &rval));
   5576         /* Freq div mode */
   5577         divisor->stage0_mode = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r,
   5578                                                  rval, L1_RCVD_FREQ_SELf);
   5579         break;
   5580     case bcmTimeSynceClockSourceSecondary:
   5581         /* input source */
   5582         SOC_IF_ERROR_RETURN(
   5583              READ_TOP_MISC_CONTROL_2r(unit, &rval));
   5584         val = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval,
   5585                                     L1_RCVD_BKUP_CLK_PORT_SELf);
   5586         phy_port = val+ 1;
   5587         divisor->input_src = bcmTimeSynceInputSourceTypePort;
   5588         divisor->index = phy_port;
   5589 
   5590         SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_2r(unit, &rval));
   5591         /* Freq div mode */
   5592         divisor->stage0_mode = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r,
   5593                                                  rval, L1_RCVD_BKUP_FREQ_SELf);
   5594         break;
   5595     default:
   5596         return BCM_E_PARAM;
   5597     }
   5598 
   5599     return BCM_E_NONE;
   5600 }
   5601 
   5602 #endif /* defined(BCM_GREYHOUND_SUPPORT) */
   5603 
   5604 #if defined(BCM_KATANA_SUPPORT)
   5605 /*
   5606  * Function:
   5607  *      _bcm_esw_time_katana_synce_clock_set
   5608  * Purpose:
   5609  *      Set syncE divisor setting
   5610  * Parameters:
   5611  *      unit      - (IN) Unit number.
   5612  *      clk_src   - (IN) clock source type (Primary, Secondary)
   5613  *      input_src - (IN) input source type (PORT)
   5614  *      index     - (IN) port no
   5615  *      divisor   - (IN) divisor setting.
   5616  * Returns:
   5617  *      BCM_E_xxx
   5618  * Notes:
   5619  */
   5620 STATIC int
   5621 _bcm_esw_time_katana_synce_clock_set(int unit,
   5622                               bcm_time_synce_clock_src_type_t clk_src,
   5623                               bcm_time_synce_divisor_setting_t *divisor)
   5624 {
   5625     /* Assumes input index is logical port number */
   5626     int phy_port = divisor->index;
   5627     int port_sel;
   5628     uint32 rval;
   5629 
   5630     port_sel = phy_port - 1;
   5631     if ( clk_src == bcmTimeSynceClockSourcePrimary ) {
   5632       BCM_IF_ERROR_RETURN(
   5633            READ_TOP_MISC_CONTROLr(unit, &rval));
   5634       soc_reg_field_set(unit, TOP_MISC_CONTROLr, &rval,
   5635                         L1_CLK0_RECOVERY_MUX_SELf, port_sel);
   5636       BCM_IF_ERROR_RETURN(
   5637             WRITE_TOP_MISC_CONTROLr(unit, rval));
   5638     } else { /* Secondary/Backup SyncE source */
   5639       BCM_IF_ERROR_RETURN(
   5640            READ_TOP_MISC_CONTROLr(unit, &rval));
   5641        soc_reg_field_set(unit, TOP_MISC_CONTROLr, &rval,
   5642                          L1_CLK1_RECOVERY_MUX_SELf, port_sel);
   5643        BCM_IF_ERROR_RETURN(
   5644             WRITE_TOP_MISC_CONTROLr(unit, rval));
   5645     }
   5646     return BCM_E_NONE;
   5647 }
   5648 
   5649 /*
   5650  * Function:
   5651  *      _bcm_esw_time_katana_synce_clock_get
   5652  * Purpose:
   5653  *      Get current setting of syncE clock divisor
   5654  * Parameters:
   5655  *      unit    - (IN)  Unit number.
   5656         divisor - (OUT) Divisor setting
   5657  * Returns:
   5658  *      BCM_E_xxx
   5659  * Notes:
   5660  */
   5661 STATIC int
   5662 _bcm_esw_time_katana_synce_clock_get(int unit,
   5663                               bcm_time_synce_clock_src_type_t clk_src,
   5664                               bcm_time_synce_divisor_setting_t *divisor)
   5665 {
   5666     uint32 val, phy_port, rval;
   5667 
   5668     switch(clk_src) {
   5669     case bcmTimeSynceClockSourcePrimary:
   5670         BCM_IF_ERROR_RETURN( READ_TOP_MISC_CONTROLr(unit, &rval));
   5671         val = soc_reg_field_get(unit, TOP_MISC_CONTROLr, rval,
   5672                                   L1_CLK0_RECOVERY_MUX_SELf);
   5673         break;
   5674     case bcmTimeSynceClockSourceSecondary:
   5675         BCM_IF_ERROR_RETURN( READ_TOP_MISC_CONTROLr(unit, &rval));
   5676         val = soc_reg_field_get(unit, TOP_MISC_CONTROLr, rval,
   5677                                      L1_CLK1_RECOVERY_MUX_SELf);
   5678         break;
   5679     default:
   5680         return BCM_E_PARAM;
   5681     }
   5682 
   5683     phy_port = val+ 1;
   5684     divisor->input_src = bcmTimeSynceInputSourceTypePort;
   5685     divisor->index = phy_port;
   5686 
   5687     return BCM_E_NONE;
   5688 }
   5689 #endif /* BCM_KATANA_SUPPORT */
   5690 
   5691 #define BCM_TIME_SYNCE_CLK_SRC_VALID(x) \
   5692     (((x) == bcmTimeSynceClockSourcePrimary) || \
   5693      ((x) == bcmTimeSynceClockSourceSecondary) )
   5694 
   5695 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   5696 
   5697 /* Synchronous Ethernet(SyncE) */
   5698 /* static definition and functions */
   5699 
   5700 #define BCM_TIME_TD2P_PLL_VALID(x) (((x) >= 0) && ((x) <= 3))
   5701 #define BCM_TIME_TOMAHAWK_PLL_VALID(x) (((x) >= 0) && ((x) <= 3))
   5702 
   5703 
   5704 #define BCM_TIME_TD2P_PORT_VALID(x) ((x) >= 1 && (x) <= 105 )
   5705 #define BCM_TIME_TOMAHAWK_PORT_VALID(x) ((x) >= 1 && (x) <= 132 )
   5706 
   5707 STATIC int
   5708 _bcm_time_td2p_divctrl_reg_modify_primary(int unit,
   5709                             bcm_time_synce_divisor_setting_t *divisor)
   5710 {
   5711     uint32 rval;
   5712     SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_CTRLr(unit, &rval));
   5713     soc_reg_field_set(unit, TOP_L1_RCVD_CLK_CTRLr, &rval,
   5714                       STAGE0_MODEf, divisor->stage0_mode);
   5715     /* STAGE1_MODEf "DON'T CARE" in SDM mode. */
   5716     if (divisor->stage0_mode != bcmTimeSynceModeSDMFracDiv) {
   5717         soc_reg_field_set(unit, TOP_L1_RCVD_CLK_CTRLr, &rval,
   5718                           STAGE1_MODEf, divisor->stage1_div);
   5719     }
   5720     if ((divisor->stage0_mode == bcmTimeSynceModeBypass) ||
   5721         (divisor->stage0_mode == bcmTimeSynceModeSDMFracDiv)) {
   5722         uint16 sdm_val;
   5723         sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   5724                    (divisor->stage0_sdm_frac & 0xff));
   5725         soc_reg_field_set(unit, TOP_L1_RCVD_CLK_CTRLr, &rval,
   5726                           SDM_DIVISORf, sdm_val);
   5727     }
   5728     WRITE_TOP_L1_RCVD_CLK_CTRLr(unit, rval);
   5729     return BCM_E_NONE;
   5730 }
   5731 
   5732 STATIC int
   5733 _bcm_time_td2p_divctrl_reg_modify_secondary(int unit,
   5734                             bcm_time_synce_divisor_setting_t *divisor)
   5735 {
   5736     uint32 rval;
   5737     SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_BKUP_CTRLr(unit, &rval));
   5738     soc_reg_field_set(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, &rval,
   5739                       STAGE0_MODEf, divisor->stage0_mode);
   5740     /* STAGE1_MODEf "DON'T CARE" in SDM mode. */
   5741     if (divisor->stage0_mode != bcmTimeSynceModeSDMFracDiv) {
   5742         soc_reg_field_set(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, &rval,
   5743                           STAGE1_MODEf, divisor->stage1_div);
   5744     }
   5745     if ((divisor->stage0_mode == bcmTimeSynceModeBypass) ||
   5746         (divisor->stage0_mode == bcmTimeSynceModeSDMFracDiv)) {
   5747         uint16 sdm_val;
   5748         sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   5749                    (divisor->stage0_sdm_frac & 0xff));
   5750         soc_reg_field_set(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, &rval,
   5751                           SDM_DIVISORf, sdm_val);
   5752     }
   5753     WRITE_TOP_L1_RCVD_CLK_BKUP_CTRLr(unit, rval);
   5754     return BCM_E_NONE;
   5755 }
   5756 
   5757 #ifdef PORTMOD_SUPPORT
   5758 STATIC phymod_dispatch_type_t
   5759 _bcm_time_synce_tsc_phymod_dispatch_type_get(int unit, int port)
   5760 {
   5761     phymod_dispatch_type_t rv = phymodDispatchTypeInvalid;
   5762     int    nof_cores = 0;
   5763 
   5764     if (soc_feature(unit, soc_feature_portmod)) {
   5765         phymod_core_access_t core_acc;
   5766         phymod_core_access_t_init(&core_acc);
   5767         portmod_port_main_core_access_get(unit, port, 0, &core_acc, &nof_cores);
   5768         if (nof_cores <= 0) {
   5769             LOG_ERROR(BSL_LS_BCM_TIME,
   5770                       (BSL_META_U(unit,
   5771                                   "Cannot get phy address\n")));
   5772             return BCM_E_PARAM;
   5773         }
   5774 
   5775         rv= core_acc.type;
   5776 
   5777     } else
   5778     {
   5779         return phymodDispatchTypeInvalid;
   5780     }
   5781 
   5782     return rv;
   5783 }
   5784 #endif
   5785 
   5786 
   5787 STATIC int
   5788 _bcm_esw_time_synce_phy_port_lane_adjust(int unit,
   5789                                          int phy_port,
   5790                                          int *adjusted_lane,
   5791                                          int *adjusted_phy_port)
   5792 {
   5793     int first_phy_port, first_log_port, port, lane = 0;
   5794     uint32 flags = 0;
   5795     int num_lanes = 4;
   5796 
   5797     port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   5798 #ifdef PORTMOD_SUPPORT
   5799     if (soc_feature(unit, soc_feature_portmod)) {
   5800         phymod_dispatch_type_t dispatch_type = phymodDispatchTypeInvalid;
   5801         dispatch_type =  _bcm_time_synce_tsc_phymod_dispatch_type_get(unit, port);
   5802         if (dispatch_type == phymodDispatchTypeTscbh)
   5803         {
   5804             num_lanes = 8;
   5805         }
   5806     }
   5807 #endif
   5808 
   5809     if (SOC_IS_HELIX5(unit)) {
   5810         first_phy_port = HX5_PORT_BLOCK_FIRST_PORT(port);
   5811     } else if (SOC_IS_GREYHOUND2(unit)){
   5812         first_phy_port = gh2_tsc_phy_port[((phy_port - 58) / 4)]; /* Eagle and Falcon*/
   5813     } else {
   5814         first_phy_port = (SOC_INFO(unit).port_serdes[port] * num_lanes) + 1;
   5815     }
   5816 
   5817     first_log_port = SOC_INFO(unit).port_p2l_mapping[first_phy_port];
   5818 #ifdef PORTMOD_SUPPORT
   5819     if (soc_feature(unit, soc_feature_portmod)) {
   5820         phymod_lane_map_t lane_map;
   5821         if (!SOC_PORT_VALID(unit,first_log_port))
   5822         {
   5823             return BCM_E_PARAM;
   5824         }
   5825         SOC_IF_ERROR_RETURN(portmod_port_lane_map_get(unit, first_log_port, flags, &lane_map));
   5826         lane = lane_map.lane_map_rx[(phy_port - 1) % num_lanes];
   5827     } else
   5828 #endif
   5829     {
   5830         uint32_t lane_swap = 0;
   5831         BCM_IF_ERROR_RETURN(bcm_esw_port_phy_control_get(unit, first_log_port,
   5832                                 BCM_PORT_PHY_CONTROL_LANE_SWAP, &lane_swap));
   5833         if (SOC_IS_GREYHOUND2(unit)){
   5834             lane = (lane_swap >> (((phy_port - 2) % num_lanes) * num_lanes)) & 0xf;
   5835         } else {
   5836             lane = (lane_swap >> (((phy_port - 1) % num_lanes) * num_lanes)) & 0xf;
   5837         }
   5838     }
   5839 
   5840     phy_port = first_phy_port + lane;
   5841 
   5842     if (adjusted_lane) {
   5843         *adjusted_lane = lane;
   5844     }
   5845     if (adjusted_phy_port) {
   5846         *adjusted_phy_port = phy_port;
   5847     }
   5848 
   5849     return BCM_E_NONE;
   5850 }
   5851 
   5852 STATIC int
   5853 _bcm_esw_time_synce_phy_port_get(int unit,
   5854                                  int adjusted_phy_port,
   5855                                  uint32 *phy_port)
   5856 {
   5857     int first_phy_port, first_log_port, lane_indx = 0;
   5858     int adjusted_lane = 0;
   5859     int tmp_phy_port = adjusted_phy_port;
   5860     int num_lanes = 4;
   5861     uint32 flags = 0;
   5862 
   5863 #ifdef PORTMOD_SUPPORT
   5864     {
   5865         
   5866         if (SOC_IS_TOMAHAWK3(unit))
   5867             num_lanes = 8;
   5868     }
   5869 #endif
   5870     if (SOC_IS_GREYHOUND2(unit)) { /* Eagle and Falcon */
   5871         first_phy_port = gh2_tsc_phy_port[((adjusted_phy_port - 58) / 4)];
   5872     } else {
   5873         first_phy_port = (((adjusted_phy_port - 1)/num_lanes) * num_lanes) + 1;
   5874     }
   5875     adjusted_lane = adjusted_phy_port - first_phy_port;
   5876     first_log_port = SOC_INFO(unit).port_p2l_mapping[first_phy_port];
   5877 #ifdef PORTMOD_SUPPORT
   5878     if (soc_feature(unit, soc_feature_portmod)) {
   5879         phymod_lane_map_t lane_map;
   5880         if (!SOC_PORT_VALID(unit,first_log_port))
   5881         {
   5882             return BCM_E_PARAM;
   5883         }
   5884         SOC_IF_ERROR_RETURN(portmod_port_lane_map_get(unit, first_log_port, flags, &lane_map));
   5885         for (lane_indx = 0; lane_indx < num_lanes; lane_indx++) {
   5886             if (lane_map.lane_map_rx[lane_indx] == adjusted_lane) {
   5887                 break;
   5888             }
   5889         }
   5890     } else
   5891 #endif
   5892     {
   5893         uint32_t lane_swap = 0;
   5894         BCM_IF_ERROR_RETURN(bcm_esw_port_phy_control_get(unit, first_log_port,
   5895                                 BCM_PORT_PHY_CONTROL_LANE_SWAP, &lane_swap));
   5896         for (lane_indx = 0; lane_indx < num_lanes; lane_indx++) {
   5897             if ( ((lane_swap >> (lane_indx * num_lanes)) & 0xf) == adjusted_lane) {
   5898                 break;
   5899             }
   5900         }
   5901     }
   5902     tmp_phy_port = first_phy_port + lane_indx;
   5903     if (phy_port) {
   5904         *phy_port = (uint32)tmp_phy_port;
   5905     }
   5906     return BCM_E_NONE;
   5907 }
   5908 
   5909 /*
   5910  * Function:
   5911  *      _tsc_synce_phy_register_set
   5912  * Purpose:
   5913  *      SyncE mode register(0x9002:PCS register) set.
   5914  *      This function is equivalent with
   5915  *
   5916  *        phy raw sbus <phy_address> 0.<phy_lane> 0x9002 value
   5917  *
   5918  *      phy_address, phy_lane will be calculated based on input logical port.
   5919  * Parameters:
   5920  *      port  - (IN) logical port number
   5921  *      value - (IN) the value to be written to register.
   5922  * Returns:
   5923  *      BCM_E_xxx
   5924  * Notes:
   5925  */
   5926 /* TSC eagle phy registers address */
   5927 #define BCM_TIME_TSCE_MAIN0_SYNCE_CTL_STAGE0_REG        0x9002 /* TSC eagle synce mode register stage 0 */
   5928 
   5929 /* TSC falcon phy registers address */
   5930 #define BCM_TIME_TSCF_MAIN0_SYNCE_CTL_REG               0x9001 /* TSC falcon synce mode register stage 1 */
   5931 #define BCM_TIME_TSCF_MAIN0_SYNCE_CTL_STAGE0_REG        0x9002 /* TSC falcon synce mode register stage 0 */
   5932 #define BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG    0xc13d /* TSC falcon synce fractional divisor register */
   5933 
   5934 STATIC int
   5935 _bcm_time_synce_phy_register_set(int unit, int port, int value, uint32 phy_reg)
   5936 {
   5937     uint32 phy_devad = 0;    /* devad = 0 means PCS access */
   5938     uint32 phy_aer;
   5939     uint16 phy_addr;
   5940     int    phy_lane;
   5941     int    phy_port;
   5942     int    nof_cores = 0;
   5943     uint32 val;
   5944     /* get internal phy address */
   5945 #ifdef PORTMOD_SUPPORT
   5946     if (soc_feature(unit, soc_feature_portmod)) {
   5947         phymod_core_access_t core_acc;
   5948         phymod_core_access_t_init(&core_acc);
   5949         portmod_port_main_core_access_get(unit, port, 0, &core_acc, &nof_cores);
   5950         if (nof_cores <= 0) {
   5951             LOG_ERROR(BSL_LS_BCM_TIME,
   5952                       (BSL_META_U(unit,
   5953                                   "Cannot get phy address\n")));
   5954             return BCM_E_PARAM;
   5955         }
   5956         phy_addr = core_acc.access.addr;
   5957     } else
   5958 #endif
   5959     {
   5960         phy_addr = PORT_TO_PHY_ADDR(unit, port);
   5961         if (phy_addr ==  0xff) {
   5962             LOG_ERROR(BSL_LS_BCM_TIME,
   5963                       (BSL_META_U(unit,
   5964                                   "Cannot get phy address\n")));
   5965             return BCM_E_PARAM;
   5966         }
   5967     }
   5968 
   5969     /* calculate lane index based on logical port */
   5970     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   5971 
   5972     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   5973     &phy_lane, NULL));
   5974     phy_aer = (phy_devad << 11) | phy_lane;
   5975 
   5976     if (phy_reg != BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG) {
   5977         soc_sbus_mdio_read(unit, phy_addr, phy_reg, &val);
   5978         value = (val & ~(0x3 << (phy_lane *2))) | ((value & 0x3) << phy_lane * 2);
   5979     } else {
   5980         phy_reg = (phy_aer << 16) | phy_reg;
   5981     }
   5982 
   5983     SOC_IF_ERROR_RETURN(
   5984         soc_sbus_mdio_write(unit, phy_addr, phy_reg, value));
   5985 
   5986     LOG_VERBOSE(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   5987                 "logical  port (%d)\n"
   5988                 "physical port (%d)\n"
   5989                 "phy addr (%x) lane (%d)\n")
   5990                 , port, phy_port
   5991                 , phy_addr, phy_lane));
   5992     return BCM_E_NONE;
   5993 }
   5994 
   5995 STATIC int
   5996 _bcm_time_synce_phy_register_get(int unit, int port, uint32 phy_reg, uint32 *value)
   5997 {
   5998     uint32 phy_devad = 0;    /* devad = 0 means PCS access */
   5999     uint32 phy_aer;
   6000     uint16 phy_addr;
   6001     int    phy_lane;
   6002     int    phy_port;
   6003     int    nof_cores = 0;
   6004 
   6005     /* get internal phy address */
   6006 #ifdef PORTMOD_SUPPORT
   6007     if (soc_feature(unit, soc_feature_portmod)) {
   6008         phymod_core_access_t core_acc;
   6009         phymod_core_access_t_init(&core_acc);
   6010         portmod_port_main_core_access_get(unit, port, 0, &core_acc, &nof_cores);
   6011         if (nof_cores <= 0) {
   6012             LOG_ERROR(BSL_LS_BCM_TIME,
   6013                       (BSL_META_U(unit,
   6014                                   "Cannot get phy address\n")));
   6015             return BCM_E_PARAM;
   6016         }
   6017         phy_addr = core_acc.access.addr;
   6018     } else
   6019 #endif
   6020     {
   6021         phy_addr = PORT_TO_PHY_ADDR(unit, port);
   6022         if (phy_addr ==  0xff) {
   6023             LOG_ERROR(BSL_LS_BCM_TIME,
   6024                       (BSL_META_U(unit,
   6025                                   "Cannot get phy address\n")));
   6026             return BCM_E_PARAM;
   6027         }
   6028     }
   6029 
   6030     /* calculate lane index based on logical port */
   6031     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   6032 
   6033     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   6034     &phy_lane, NULL));
   6035 
   6036     phy_aer = (phy_devad << 11) | phy_lane;
   6037     if (phy_reg == BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG) {
   6038         phy_reg = (phy_aer << 16) | phy_reg;
   6039     }
   6040 
   6041 
   6042     SOC_IF_ERROR_RETURN(
   6043         soc_sbus_mdio_read(unit, phy_addr, phy_reg, value));
   6044 
   6045     if (phy_reg == BCM_TIME_TSCF_MAIN0_SYNCE_CTL_REG || phy_reg == BCM_TIME_TSCF_MAIN0_SYNCE_CTL_STAGE0_REG) {
   6046         soc_sbus_mdio_read(unit, phy_addr, phy_reg, value);
   6047         *value = (*value >> phy_lane *2) & 0x3;
   6048     }
   6049 
   6050     LOG_VERBOSE(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   6051                 "logical  port (%d)\n"
   6052                 "physical port (%d)\n"
   6053                 "phy addr (%x) lane (%d)\n")
   6054                 , port, phy_port
   6055                 , phy_addr, phy_lane));
   6056     return BCM_E_NONE;
   6057 }
   6058 
   6059 
   6060 
   6061 STATIC int
   6062 _bcm_time_synce_tsc_divisor_turn_off(int unit, int port)
   6063 {
   6064     int rv = BCM_E_NONE;
   6065     int    nof_cores = 0;
   6066 
   6067 #ifdef PORTMOD_SUPPORT
   6068     if (soc_feature(unit, soc_feature_portmod)) {
   6069         phymod_core_access_t core_acc;
   6070         phymod_core_access_t_init(&core_acc);
   6071         portmod_port_main_core_access_get(unit, port, 0, &core_acc, &nof_cores);
   6072         if (nof_cores <= 0) {
   6073             LOG_ERROR(BSL_LS_BCM_TIME,
   6074                       (BSL_META_U(unit,
   6075                                   "Cannot get phy address\n")));
   6076             return BCM_E_PARAM;
   6077         }
   6078 
   6079         if (core_acc.type == phymodDispatchTypeTsce) {
   6080             rv = _bcm_time_synce_phy_register_set(unit, port, 0x0, BCM_TIME_TSCE_MAIN0_SYNCE_CTL_STAGE0_REG);
   6081         }
   6082 
   6083     } else
   6084 #endif
   6085     {
   6086         return BCM_E_PARAM;
   6087     }
   6088 
   6089     return rv;
   6090 }
   6091 
   6092 
   6093 /* NOTES : this function takes care of TD2Plus only */
   6094 STATIC int
   6095 _bcm_esw_time_td2p_synce_clock_set_by_port(int unit,
   6096                                bcm_time_synce_clock_src_type_t clk_src,
   6097                                bcm_time_synce_divisor_setting_t *divisor)
   6098 {
   6099     /* Assumes input index is logical port number */
   6100     int lport = divisor->index;
   6101     int phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   6102     int port_sel;
   6103 
   6104     if (!BCM_TIME_TD2P_PORT_VALID(lport) ||
   6105         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   6106         (phy_port == -1)) {
   6107         return BCM_E_PARAM;
   6108     }
   6109 
   6110     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   6111     NULL, &phy_port));
   6112 
   6113 
   6114     port_sel = phy_port - 1;
   6115     if ( clk_src == bcmTimeSynceClockSourcePrimary ) {
   6116         /* TOP_MISC_CONTROL */
   6117         SOC_IF_ERROR_RETURN
   6118             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6119                                     L1_RCVD_CLK_RSTNf, 0));
   6120         /* TOP_MISC_CONTROL_2 */
   6121         SOC_IF_ERROR_RETURN
   6122             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6123                                     L1_RCVD_FREQ_DIV_SELf, 0));
   6124         /* _TOP_L1_RCVD_CLK_CTRL */
   6125         SOC_IF_ERROR_RETURN(_bcm_time_td2p_divctrl_reg_modify_primary(unit, divisor));
   6126         /* TOP_MISC_CONTROL_2 */
   6127         SOC_IF_ERROR_RETURN
   6128             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6129                                     XG_RCVD_PRI_SELf, 0));
   6130         /* EGR_L1_CLK_RECOVERY_CTRL */
   6131         SOC_IF_ERROR_RETURN
   6132             (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   6133                                     REG_PORT_ANY, PRI_PORT_SELf, port_sel));
   6134         /* Turn off TSC div11 */
   6135         BCM_IF_ERROR_RETURN(
   6136             _bcm_time_synce_tsc_divisor_turn_off(unit, lport));
   6137 
   6138         /* Enable SW L1 prim recov clk as valid,default it is invalid*/
   6139         SOC_IF_ERROR_RETURN
   6140             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6141                                     L1_RCVD_SW_OVWR_VALIDf, 1));
   6142         SOC_IF_ERROR_RETURN
   6143             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6144                                     L1_RCVD_SW_OVWR_ENf, 1));
   6145 
   6146         /* TOP_MISC_CONTROL */
   6147         SOC_IF_ERROR_RETURN
   6148             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6149                                     L1_RCVD_CLK_RSTNf, 1));
   6150     } else {
   6151         /* TOP_MISC_CONTROL */
   6152         SOC_IF_ERROR_RETURN
   6153             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6154                                     L1_RCVD_CLK_BKUP_RSTNf, 0));
   6155         /* TOP_MISC_CONTROL_2 */
   6156         SOC_IF_ERROR_RETURN
   6157             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6158                                     L1_RCVD_BKUP_FREQ_DIV_SELf, 0));
   6159         /* _TOP_L1_RCVD_CLK_BKUP_CTRL */
   6160         SOC_IF_ERROR_RETURN
   6161             (_bcm_time_td2p_divctrl_reg_modify_secondary(unit, divisor));
   6162         /* TOP_MISC_CONTROL_2 */
   6163         SOC_IF_ERROR_RETURN
   6164             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6165                                     XG_RCVD_BKUP_SELf, 0));
   6166         /* EGR_L1_CLK_RECOVERY_CTRL */
   6167         SOC_IF_ERROR_RETURN
   6168             (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   6169                                     REG_PORT_ANY, BKUP_PORT_SELf, port_sel));
   6170         /* Turn off TSC div11 */
   6171         BCM_IF_ERROR_RETURN(
   6172             _bcm_time_synce_tsc_divisor_turn_off(unit, lport));
   6173 
   6174         /* Enable SW L1 sec recov clk as valid,default it is invalid*/
   6175         SOC_IF_ERROR_RETURN
   6176             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6177                                     L1_RCVD_SW_OVWR_BKUP_VALIDf, 1));
   6178         SOC_IF_ERROR_RETURN
   6179             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6180                                     L1_RCVD_SW_OVWR_ENf, 1));
   6181 
   6182         /* TOP_MISC_CONTROL */
   6183         SOC_IF_ERROR_RETURN
   6184             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6185                                     L1_RCVD_CLK_BKUP_RSTNf, 1));
   6186     }
   6187     return BCM_E_NONE;
   6188 }
   6189 
   6190 /* NOTES : this function takes care of TD2Plus only */
   6191 STATIC int
   6192 _bcm_esw_time_td2p_synce_clock_set_by_pll(int unit,
   6193                                bcm_time_synce_clock_src_type_t clk_src,
   6194                                bcm_time_synce_divisor_setting_t *divisor)
   6195 {
   6196     uint32 pll_index = divisor->index;
   6197 
   6198     /* coverity[unsigned_compare] */
   6199     if (!BCM_TIME_TD2P_PLL_VALID(pll_index) ||
   6200         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src)) {
   6201         return BCM_E_PARAM;
   6202     }
   6203     if (clk_src == bcmTimeSynceClockSourcePrimary) {
   6204         /* TOP_MISC_CONTROL */
   6205         SOC_IF_ERROR_RETURN
   6206             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6207                                     L1_RCVD_CLK_RSTNf, 0));
   6208         /* TOP_MISC_CONTROL_2 */
   6209         SOC_IF_ERROR_RETURN
   6210             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6211                                     L1_RCVD_FREQ_DIV_SELf, 0));
   6212         /* _TOP_L1_RCVD_CLK_CTRL */
   6213         SOC_IF_ERROR_RETURN(_bcm_time_td2p_divctrl_reg_modify_primary(unit, divisor));
   6214         /* TOP_MISC_CONTROL_2 */
   6215         SOC_IF_ERROR_RETURN
   6216             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6217                                     XG_RCVD_PRI_SELf, pll_index+1));
   6218         /* EGR_L1_CLK_RECOVERY_CTRL */
   6219         SOC_IF_ERROR_RETURN
   6220             (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   6221                                     REG_PORT_ANY, PRI_PORT_SELf, 0));
   6222 
   6223         /* Enable SW L1 prim recov clk as valid,default it is invalid*/
   6224         SOC_IF_ERROR_RETURN
   6225             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6226                                     L1_RCVD_SW_OVWR_VALIDf, 1));
   6227         SOC_IF_ERROR_RETURN
   6228             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6229                                     L1_RCVD_SW_OVWR_ENf, 1));
   6230 
   6231         /* TOP_MISC_CONTROL */
   6232         SOC_IF_ERROR_RETURN
   6233             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6234                                     L1_RCVD_CLK_RSTNf, 1));
   6235     } else {
   6236         /* TOP_MISC_CONTROL */
   6237         SOC_IF_ERROR_RETURN
   6238             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6239                                     L1_RCVD_CLK_BKUP_RSTNf, 0));
   6240         /* TOP_MISC_CONTROL_2 */
   6241         SOC_IF_ERROR_RETURN
   6242             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6243                                     L1_RCVD_BKUP_FREQ_DIV_SELf, 0));
   6244         /* _TOP_L1_RCVD_CLK_BKUP_CTRL */
   6245         SOC_IF_ERROR_RETURN
   6246             (_bcm_time_td2p_divctrl_reg_modify_secondary(unit, divisor));
   6247         /* TOP_MISC_CONTROL_2 */
   6248         SOC_IF_ERROR_RETURN
   6249             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6250                                     XG_RCVD_BKUP_SELf, pll_index+1));
   6251         /* EGR_L1_CLK_RECOVERY_CTRL */
   6252         SOC_IF_ERROR_RETURN
   6253             (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   6254                                     REG_PORT_ANY, BKUP_PORT_SELf, 0));
   6255 
   6256         /* Enable SW L1 sec recov clk as valid,default it is invalid*/
   6257         SOC_IF_ERROR_RETURN
   6258             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6259                                     L1_RCVD_SW_OVWR_BKUP_VALIDf, 1));
   6260         SOC_IF_ERROR_RETURN
   6261             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6262                                     L1_RCVD_SW_OVWR_ENf, 1));
   6263 
   6264         /* TOP_MISC_CONTROL */
   6265         SOC_IF_ERROR_RETURN
   6266             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6267                                     L1_RCVD_CLK_BKUP_RSTNf, 1));
   6268     }
   6269     return BCM_E_NONE;
   6270 }
   6271 
   6272 /*
   6273  * Function:
   6274  *      _bcm_esw_time_td2p_synce_clock_set
   6275  * Purpose:
   6276  *      Set syncE divisor setting
   6277  * Parameters:
   6278  *      unit      - (IN) Unit number.
   6279  *      clk_src   - (IN) clock source type (Primary, Secondary)
   6280  *      input_src - (IN) input source type (PORT, PLL)
   6281  *      index     - (IN) if input_src is PORT, specify logical port number 0..105
   6282  *                       if input_src is PLL, specify PLL index 0..3
   6283  *      divisor   - (IN) divisor setting.
   6284  * Returns:
   6285  *      BCM_E_xxx
   6286  * Notes: This function only configures for td2plus
   6287  */
   6288 STATIC int
   6289 _bcm_esw_time_td2p_synce_clock_set(int unit,
   6290                               bcm_time_synce_clock_src_type_t clk_src,
   6291                               bcm_time_synce_divisor_setting_t *divisor)
   6292 {
   6293     int rv;
   6294 
   6295     switch(divisor->input_src) {
   6296     case bcmTimeSynceInputSourceTypePort:
   6297         rv = _bcm_esw_time_td2p_synce_clock_set_by_port(unit, clk_src, divisor);
   6298         break;
   6299     case bcmTimeSynceInputSourceTypePLL:
   6300         rv = _bcm_esw_time_td2p_synce_clock_set_by_pll(unit, clk_src, divisor);
   6301         break;
   6302     default:
   6303         rv = BCM_E_PARAM;
   6304         break;
   6305     }
   6306 
   6307     return rv;
   6308 }
   6309 
   6310 /*
   6311  * Function:
   6312  *      _bcm_esw_time_td2p_synce_clock_get
   6313  * Purpose:
   6314  *      Get current setting of syncE clock divisor
   6315  * Parameters:
   6316  *      unit    - (IN)  Unit number.
   6317         divisor - (OUT) Divisor setting
   6318  * Returns:
   6319  *      BCM_E_xxx
   6320  * Notes: This function takes care of TD2Plus only
   6321  */
   6322 STATIC int
   6323 _bcm_esw_time_td2p_synce_clock_get(int unit,
   6324                               bcm_time_synce_clock_src_type_t clk_src,
   6325                               bcm_time_synce_divisor_setting_t *divisor)
   6326 {
   6327     uint32 val, val2, rval;
   6328     uint16 sdm_val;
   6329 
   6330     switch(clk_src) {
   6331     case bcmTimeSynceClockSourcePrimary:
   6332         /* input source */
   6333         SOC_IF_ERROR_RETURN(
   6334              READ_TOP_MISC_CONTROL_2r(unit, &rval));
   6335         val = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval,
   6336                                 XG_RCVD_PRI_SELf);
   6337         SOC_IF_ERROR_RETURN(
   6338              READ_EGR_L1_CLK_RECOVERY_CTRLr(unit, &rval));
   6339         val2 = soc_reg_field_get(unit, EGR_L1_CLK_RECOVERY_CTRLr, rval,
   6340                                      PRI_PORT_SELf);
   6341         if (val == 0) { /* source is Port */
   6342             uint32 phy_port;
   6343             phy_port = val2 + 1;
   6344             _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   6345             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   6346             divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   6347         } else { /* source is PLL */
   6348             /* EGR_L1_CLK_RECOVERY_CTRLr.PRI_PORT_SELf needs to be 0
   6349              * Otherwise, there's no clock output */
   6350             if (val2 != 0) {
   6351                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   6352                             "No clock output\n")));
   6353                 return BCM_E_FAIL;
   6354             }
   6355             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   6356             divisor->index = val - 1;
   6357         }
   6358 
   6359         SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_CTRLr(unit, &rval));
   6360         /* stage0_mode */
   6361         divisor->stage0_mode = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr,
   6362                                                  rval, STAGE0_MODEf);
   6363         sdm_val = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr, rval,
   6364                                     SDM_DIVISORf);
   6365         /* stage0_whole */
   6366         divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   6367         /* stage0_frac */
   6368         divisor->stage0_sdm_frac = sdm_val & 0xff ;
   6369         /* stage1_div  */
   6370         divisor->stage1_div = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr,
   6371                                                 rval, STAGE1_MODEf);
   6372         break;
   6373     case bcmTimeSynceClockSourceSecondary:
   6374         /* input source */
   6375         SOC_IF_ERROR_RETURN(
   6376              READ_TOP_MISC_CONTROL_2r(unit, &rval));
   6377         val = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval,
   6378                                 XG_RCVD_BKUP_SELf);
   6379         SOC_IF_ERROR_RETURN(
   6380              READ_EGR_L1_CLK_RECOVERY_CTRLr(unit, &rval));
   6381         val2 = soc_reg_field_get(unit, EGR_L1_CLK_RECOVERY_CTRLr, rval,
   6382                                      BKUP_PORT_SELf);
   6383         if (val == 0) { /* source is Port */
   6384             uint32 phy_port;
   6385             phy_port = val2 + 1;
   6386             _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   6387             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   6388             divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   6389         } else { /* source is PLL */
   6390             /* EGR_L1_CLK_RECOVERY_CTRLr.BKUP_PORT_SELf needs to be 0
   6391              * Otherwise, there's no clock output */
   6392             if (val2 != 0) {
   6393                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   6394                             "No clock output\n")));
   6395                 return BCM_E_FAIL;
   6396             }
   6397             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   6398             divisor->index = val - 1;
   6399         }
   6400 
   6401         SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_BKUP_CTRLr(unit, &rval));
   6402         /* stage0_mode */
   6403         divisor->stage0_mode = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr,
   6404                                                  rval, STAGE0_MODEf);
   6405         sdm_val = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, rval,
   6406                                     SDM_DIVISORf);
   6407         /* stage0_whole */
   6408         divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   6409         /* stage0_frac */
   6410         divisor->stage0_sdm_frac = sdm_val & 0xff ;
   6411         /* stage1_div  */
   6412         divisor->stage1_div = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr,
   6413                                                 rval, STAGE1_MODEf);
   6414         break;
   6415     default:
   6416         return BCM_E_PARAM;
   6417     }
   6418 
   6419 
   6420 
   6421     return BCM_E_NONE;
   6422 }
   6423 
   6424 STATIC int
   6425 _bcm_esw_time_tomahawkx_synce_clock_set_by_port(int unit,
   6426                                bcm_time_synce_clock_src_type_t clk_src,
   6427                                bcm_time_synce_divisor_setting_t *divisor)
   6428 {
   6429     soc_reg_t synce_ctrl = TOP_MISC_CONTROLr;
   6430     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   6431     /* Assumes input index is logical port number */
   6432     int lport = divisor->index;
   6433     int phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   6434     int port_sel;
   6435     uint16 sdm_val;
   6436     portmod_port_synce_clk_ctrl_t config;
   6437     soc_field_t xg_rcvd_sel = XG_RCVD_SELf;
   6438     soc_field_t l1_rcvd_port_sel = L1_RCVD_PORT_SELf;
   6439     soc_field_t l1_rcvd_clk_rstn = L1_RCVD_CLK_RSTNf;
   6440     soc_field_t l1_rcvd_freq_sel = L1_RCVD_FREQ_SELf;
   6441 
   6442     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   6443         l1_rcvd_port_sel = L1_RCVD_BKUP_PORT_SELf;
   6444         xg_rcvd_sel = XG_RCVD_BKUP_SELf;
   6445         l1_rcvd_clk_rstn = L1_RCVD_CLK_BKUP_RSTNf;
   6446         l1_rcvd_freq_sel = L1_RCVD_BKUP_FREQ_SELf;
   6447     }
   6448     /* Set Registers for TOMAHAWK3 */
   6449     if (SOC_IS_TOMAHAWK3(unit)) {
   6450         synce_ctrl = TOP_SYNCE_CTRLr;
   6451         synce_ctrl_2 = TOP_SYNCE_CTRLr;
   6452     }
   6453 
   6454     if (!BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   6455         !BCM_TIME_TOMAHAWK_PORT_VALID(lport) ||
   6456         (phy_port == -1)) {
   6457         return BCM_E_PARAM;
   6458     }
   6459 
   6460     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   6461         NULL, &phy_port));
   6462     port_sel = phy_port - 1;
   6463 
   6464     /* TOP_MISC_CONTROL */
   6465     SOC_IF_ERROR_RETURN
   6466         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   6467                                 l1_rcvd_clk_rstn, 0));
   6468 
   6469     /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   6470     SOC_IF_ERROR_RETURN
   6471         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   6472                                 l1_rcvd_freq_sel, 0));
   6473     sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   6474                     (divisor->stage0_sdm_frac & 0xff));
   6475 #ifdef PORTMOD_SUPPORT
   6476     if (soc_feature(unit, soc_feature_portmod)) {
   6477         portmod_port_synce_clk_ctrl_t_init(unit, &config);
   6478         config.stg0_mode = divisor->stage0_mode;
   6479         config.stg1_mode = 0x0;
   6480         config.sdm_val = sdm_val;
   6481         if (!SOC_PORT_VALID(unit,lport))
   6482         {
   6483             return BCM_E_PARAM;
   6484         }
   6485         SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_set(unit, lport, &config));
   6486     } else
   6487 #endif
   6488     {
   6489         /* Set TSCF SDM divisors */
   6490         /* Set SDM stage 1 mode to bypass */
   6491         BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport, divisor->stage1_div,
   6492                             BCM_TIME_TSCF_MAIN0_SYNCE_CTL_REG));
   6493 
   6494         /* Set stage 0 mode to SDM mode */
   6495         BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport,
   6496                                 divisor->stage0_mode, BCM_TIME_TSCF_MAIN0_SYNCE_CTL_STAGE0_REG));
   6497 
   6498         BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport, sdm_val,
   6499                             BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG));
   6500     }
   6501     /* TOP_MISC_CONTROL_2  - set sg pll port sel 0 */
   6502     if (!SOC_IS_TOMAHAWK3(unit)) {
   6503         SOC_IF_ERROR_RETURN
   6504             (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   6505                                 xg_rcvd_sel, 0));
   6506     }
   6507     /* serdes port configuration */
   6508     SOC_IF_ERROR_RETURN
   6509         (soc_reg_field32_modify(unit, synce_ctrl_2,
   6510                                REG_PORT_ANY, l1_rcvd_port_sel, port_sel));
   6511     /* TOP_MISC_CONTROL */
   6512     SOC_IF_ERROR_RETURN
   6513         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   6514                                 l1_rcvd_clk_rstn, 1));
   6515 
   6516     return BCM_E_NONE;
   6517 }
   6518 
   6519 /*
   6520  * Function:
   6521  *      _bcm_esw_time_tomahawkx_synce_clock_get
   6522  * Purpose:
   6523  *      Get current setting of syncE clock divisor
   6524  * Parameters:
   6525  *      unit    - (IN)  Unit number.
   6526         divisor - (OUT) Divisor setting
   6527  * Returns:
   6528  *      BCM_E_xxx
   6529  * Notes: This function takes care of tomahawk only
   6530  */
   6531 STATIC int
   6532 _bcm_esw_time_tomahawkx_synce_clock_get(int unit,
   6533                               bcm_time_synce_clock_src_type_t clk_src,
   6534                               bcm_time_synce_divisor_setting_t *divisor)
   6535 {
   6536     uint32 val, val2, rval;
   6537     int lport;
   6538     uint32 sdm_val;
   6539     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   6540     soc_field_t xg_rcvd_sel = XG_RCVD_SELf;
   6541     soc_field_t l1_rcvd_port_sel = L1_RCVD_PORT_SELf;
   6542     portmod_port_synce_clk_ctrl_t config;
   6543 
   6544     if (SOC_IS_TOMAHAWK3(unit)) {
   6545         synce_ctrl_2 = TOP_SYNCE_CTRLr;
   6546     }
   6547 
   6548     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   6549 
   6550     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   6551         l1_rcvd_port_sel = L1_RCVD_BKUP_PORT_SELf;
   6552         xg_rcvd_sel = XG_RCVD_BKUP_SELf;
   6553     }
   6554     /* input source port */
   6555     val = 0;
   6556     soc_reg32_get(unit, synce_ctrl_2, REG_PORT_ANY, 0, &rval);
   6557 
   6558     if (!SOC_IS_TOMAHAWK3(unit)) {
   6559         val = soc_reg_field_get(unit, synce_ctrl_2, rval, xg_rcvd_sel);
   6560     }
   6561     val2 = soc_reg_field_get(unit, synce_ctrl_2, rval, l1_rcvd_port_sel);
   6562    if (val == 0) { /* source is Port */
   6563         uint32 phy_port;
   6564         phy_port = val2 + 1;
   6565         _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   6566         divisor->input_src = bcmTimeSynceInputSourceTypePort;
   6567         divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   6568     } else { /* source is PLL */
   6569         /* TOP_MISC_CONTROL_2.L1_RCVD_PORT_SELf needs to be 0
   6570          * Otherwise, there's no clock output */
   6571         if (val2 != 0) {
   6572             LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   6573                         "No clock output\n")));
   6574             return BCM_E_FAIL;
   6575         }
   6576         divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   6577         divisor->index = val - 1;
   6578     }
   6579 
   6580     /* READ the SDM divisors from TSC */
   6581     lport = divisor->index;
   6582 
   6583     if (!SOC_PORT_VALID(unit,lport))
   6584     {
   6585         return BCM_E_PARAM;
   6586     }
   6587 
   6588 #ifdef PORTMOD_SUPPORT
   6589     if (soc_feature(unit, soc_feature_portmod)) {
   6590         SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_get(unit, lport, &config));
   6591         /* stage0_mode */
   6592         divisor->stage0_mode = config.stg0_mode;
   6593         sdm_val = config.sdm_val;
   6594         /* stage0_whole */
   6595         divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   6596         /* stage0_frac */
   6597         divisor->stage0_sdm_frac = sdm_val & 0xff ;
   6598         /* stage1_div  */
   6599         divisor->stage1_div = config.stg1_mode;
   6600     } else
   6601 #endif
   6602     {
   6603         /* stage0_mode */
   6604         BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   6605         BCM_TIME_TSCF_MAIN0_SYNCE_CTL_STAGE0_REG,  &divisor->stage0_mode));
   6606         BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   6607         BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG, &sdm_val));
   6608         /* stage0_whole */
   6609         divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   6610         /* stage0_frac */
   6611         divisor->stage0_sdm_frac = sdm_val & 0xff ;
   6612         /* stage1_div  */
   6613         BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   6614         BCM_TIME_TSCF_MAIN0_SYNCE_CTL_REG, &divisor->stage1_div));
   6615     }
   6616 
   6617      return BCM_E_NONE;
   6618 }
   6619 
   6620 #define BCM_TIME_APACHEX_PLL_VALID(x) (((x) >= 0) && ((x) <= 3))
   6621 #define BCM_TIME_APACHEX_PORT_VALID(x) ((x) >= 1 && (x) <= 72 )
   6622 #define BCM_TIME_APACHEX_LCPLL_PORT_BASE (73)
   6623 
   6624 STATIC int
   6625 _bcm_esw_time_apachex_synce_clock_set_by_port(int unit,
   6626                                bcm_time_synce_clock_src_type_t clk_src,
   6627                                bcm_time_synce_divisor_setting_t *divisor)
   6628 {
   6629     /* Assumes input index is logical port number */
   6630     int lport = divisor->index;
   6631     int phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   6632     int port_sel;
   6633     uint16 sdm_val;
   6634     uint32 rval;
   6635     phymod_dispatch_type_t dispatch_type = phymodDispatchTypeInvalid;
   6636 
   6637     if (!BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   6638         !BCM_TIME_APACHEX_PORT_VALID(lport) ||
   6639         (phy_port == -1)) {
   6640         return BCM_E_PARAM;
   6641     }
   6642 
   6643     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   6644         NULL, &phy_port));
   6645 
   6646     port_sel = phy_port - 1;
   6647     switch (clk_src) {
   6648     case bcmTimeSynceClockSourcePrimary:
   6649             /* TOP_MISC_CONTROL */
   6650             SOC_IF_ERROR_RETURN
   6651                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6652                                         L1_RCVD_CLK_RSTNf, 0));
   6653 
   6654             /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   6655             SOC_IF_ERROR_RETURN
   6656                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6657                                         L1_RCVD_FREQ_SELf, 0));
   6658 
   6659             dispatch_type = _bcm_time_synce_tsc_phymod_dispatch_type_get(unit, lport);
   6660 
   6661             if (dispatch_type == phymodDispatchTypeTsce) {
   6662 
   6663                 /* register is similar to TD2+ */
   6664                 _bcm_time_td2p_divctrl_reg_modify_primary(unit, divisor);
   6665 
   6666                 /* Turn off TSC div11 */
   6667                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport, 0x0, 
   6668                     BCM_TIME_TSCE_MAIN0_SYNCE_CTL_STAGE0_REG));
   6669 
   6670 
   6671             } else if (dispatch_type == phymodDispatchTypeTscf) {
   6672                 /* reset chip level SDM config before phy SDM config*/
   6673                 SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_CTRLr(unit, &rval));
   6674                 soc_reg_field_set(unit, TOP_L1_RCVD_CLK_CTRLr, &rval,
   6675                                   STAGE0_MODEf, 0x0);
   6676                 soc_reg_field_set(unit, TOP_L1_RCVD_CLK_CTRLr, &rval,
   6677                                   STAGE1_MODEf, 0x0);
   6678                 soc_reg_field_set(unit, TOP_L1_RCVD_CLK_CTRLr, &rval,
   6679                                   SDM_DIVISORf, 0x0);
   6680                 WRITE_TOP_L1_RCVD_CLK_CTRLr(unit, rval);
   6681 
   6682 
   6683                 /* Set TSCF SDM divisors */
   6684                 /* Set SDM stage 1 mode to bypass */
   6685                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport, 0x0,
   6686                     BCM_TIME_TSCF_MAIN0_SYNCE_CTL_REG));
   6687 
   6688                 /* Set stage 0 mode to SDM mode */
   6689                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport,
   6690                     divisor->stage0_mode, BCM_TIME_TSCF_MAIN0_SYNCE_CTL_STAGE0_REG));
   6691 
   6692                 sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   6693                            (divisor->stage0_sdm_frac & 0xff));
   6694 
   6695                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport, sdm_val,
   6696                     BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG));
   6697             }
   6698 
   6699             /* TOP_MISC_CONTROL_2 */
   6700             SOC_IF_ERROR_RETURN
   6701                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6702                                         XG_RCVD_PRI_SELf, 0));
   6703             /* EGR_L1_CLK_RECOVERY_CTRL */
   6704             SOC_IF_ERROR_RETURN
   6705                 (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   6706                                         REG_PORT_ANY, PRI_PORT_SELf, port_sel));
   6707 
   6708             /* TOP_MISC_CONTROL */
   6709             SOC_IF_ERROR_RETURN
   6710                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6711                                         L1_RCVD_CLK_RSTNf, 1));
   6712             break;
   6713     case bcmTimeSynceClockSourceSecondary:
   6714             /* TOP_MISC_CONTROL */
   6715             SOC_IF_ERROR_RETURN
   6716                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6717                                         L1_RCVD_CLK_BKUP_RSTNf, 0));
   6718 
   6719             /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   6720             SOC_IF_ERROR_RETURN
   6721                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6722                                         L1_RCVD_BKUP_FREQ_SELf, 0));
   6723 
   6724             dispatch_type = _bcm_time_synce_tsc_phymod_dispatch_type_get(unit, lport);
   6725 
   6726             if (dispatch_type == phymodDispatchTypeTsce) {
   6727                 /* register is similar to TD2+ */
   6728                 _bcm_time_td2p_divctrl_reg_modify_secondary(unit, divisor);
   6729 
   6730                 /* Turn off TSC div11 */
   6731                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport, 0x0,
   6732                     BCM_TIME_TSCE_MAIN0_SYNCE_CTL_STAGE0_REG));
   6733 
   6734             } else if (dispatch_type == phymodDispatchTypeTscf) {
   6735                 /* reset chip level SDM config before phy SDM config*/
   6736                 SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_BKUP_CTRLr(unit, &rval));
   6737                 soc_reg_field_set(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, &rval,
   6738                                   STAGE0_MODEf, 0x0);
   6739                 soc_reg_field_set(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, &rval,
   6740                                   STAGE1_MODEf, 0x0);
   6741                 soc_reg_field_set(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, &rval,
   6742                                   SDM_DIVISORf, 0x0);
   6743                 WRITE_TOP_L1_RCVD_CLK_BKUP_CTRLr(unit, rval);
   6744 
   6745 
   6746                 /* Set TSCF SDM divisors */
   6747                 /* Set SDM stage 1 mode to bypass */
   6748                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport, 0x0,
   6749                     BCM_TIME_TSCF_MAIN0_SYNCE_CTL_REG));
   6750 
   6751                 /* Set stage 0 mode to SDM mode */
   6752                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport,
   6753                     divisor->stage0_mode, BCM_TIME_TSCF_MAIN0_SYNCE_CTL_STAGE0_REG));
   6754 
   6755                 sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   6756                            (divisor->stage0_sdm_frac & 0xff));
   6757 
   6758                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_set(unit, lport, sdm_val,
   6759                     BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG));
   6760             }
   6761 
   6762             /* TOP_MISC_CONTROL_2 */
   6763             SOC_IF_ERROR_RETURN
   6764                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6765                                         XG_RCVD_BKUP_SELf, 0));
   6766             /* EGR_L1_CLK_RECOVERY_CTRL */
   6767             SOC_IF_ERROR_RETURN
   6768                 (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   6769                                         REG_PORT_ANY, BKUP_PORT_SELf, port_sel));
   6770 
   6771             /* TOP_MISC_CONTROL */
   6772             SOC_IF_ERROR_RETURN
   6773                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6774                                         L1_RCVD_CLK_BKUP_RSTNf, 1));
   6775         break;
   6776     /* coverity[dead_error_begin:FALSE] */
   6777     default:
   6778         return BCM_E_PARAM;
   6779 
   6780     }
   6781     return BCM_E_NONE;
   6782 }
   6783 
   6784 /* NOTES : this function takes care of Apache/ Maverick only */
   6785 STATIC int
   6786 _bcm_esw_time_apachex_synce_clock_set_by_pll(int unit,
   6787                                bcm_time_synce_clock_src_type_t clk_src,
   6788                                bcm_time_synce_divisor_setting_t *divisor)
   6789 {
   6790     uint32 pll_index = divisor->index;
   6791 
   6792     /* coverity[unsigned_compare] */
   6793     if (!BCM_TIME_APACHEX_PLL_VALID(pll_index) ||
   6794         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src)) {
   6795         return BCM_E_PARAM;
   6796     }
   6797     pll_index = pll_index + BCM_TIME_APACHEX_LCPLL_PORT_BASE; /* serdes LCPLL base */
   6798     if (clk_src == bcmTimeSynceClockSourcePrimary) {
   6799         /* TOP_MISC_CONTROL */
   6800         SOC_IF_ERROR_RETURN
   6801             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6802                                     L1_RCVD_CLK_RSTNf, 0));
   6803         /* TOP_MISC_CONTROL_2 */
   6804         SOC_IF_ERROR_RETURN
   6805             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6806                                     L1_RCVD_FREQ_DIV_SELf, 0));
   6807         /* _TOP_L1_RCVD_CLK_CTRL */
   6808         SOC_IF_ERROR_RETURN(_bcm_time_td2p_divctrl_reg_modify_primary(unit, divisor));
   6809         /* TOP_MISC_CONTROL_2 */
   6810         SOC_IF_ERROR_RETURN
   6811             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6812                                     XG_RCVD_PRI_SELf, pll_index));
   6813         /* EGR_L1_CLK_RECOVERY_CTRL */
   6814         SOC_IF_ERROR_RETURN
   6815             (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   6816                                     REG_PORT_ANY, PRI_PORT_SELf, 0));
   6817         /* TOP_MISC_CONTROL */
   6818         SOC_IF_ERROR_RETURN
   6819             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6820                                     L1_RCVD_CLK_RSTNf, 1));
   6821     } else {
   6822         /* TOP_MISC_CONTROL */
   6823         SOC_IF_ERROR_RETURN
   6824             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6825                                     L1_RCVD_CLK_BKUP_RSTNf, 0));
   6826         /* TOP_MISC_CONTROL_2 */
   6827         SOC_IF_ERROR_RETURN
   6828             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6829                                     L1_RCVD_BKUP_FREQ_DIV_SELf, 0));
   6830         /* _TOP_L1_RCVD_CLK_BKUP_CTRL */
   6831         SOC_IF_ERROR_RETURN
   6832             (_bcm_time_td2p_divctrl_reg_modify_secondary(unit, divisor));
   6833         /* TOP_MISC_CONTROL_2 */
   6834         SOC_IF_ERROR_RETURN
   6835             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   6836                                     XG_RCVD_BKUP_SELf, pll_index));
   6837         /* EGR_L1_CLK_RECOVERY_CTRL */
   6838         SOC_IF_ERROR_RETURN
   6839             (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   6840                                     REG_PORT_ANY, BKUP_PORT_SELf, 0));
   6841         /* TOP_MISC_CONTROL */
   6842         SOC_IF_ERROR_RETURN
   6843             (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   6844                                     L1_RCVD_CLK_BKUP_RSTNf, 1));
   6845     }
   6846     return BCM_E_NONE;
   6847 }
   6848 
   6849 
   6850 
   6851 /*
   6852  * Function:
   6853  *      _bcm_esw_time_apachex_synce_clock_set
   6854  * Purpose:
   6855  *      Set syncE divisor setting
   6856  * Parameters:
   6857  *      unit      - (IN) Unit number.
   6858  *      clk_src   - (IN) clock source type (Primary, Secondary)
   6859  *      input_src - (IN) input source type (PORT, PLL)
   6860  *      index     - (IN) if input_src is PORT, specify logical port number 0..30
   6861  *                       if input_src is PLL, specify PLL index 0..2
   6862  *      divisor   - (IN) divisor setting.
   6863  * Returns:
   6864  *      BCM_E_xxx
   6865  * Notes: This function only configures for SB2
   6866  */
   6867 STATIC int
   6868 _bcm_esw_time_apachex_synce_clock_set(int unit,
   6869                               bcm_time_synce_clock_src_type_t clk_src,
   6870                               bcm_time_synce_divisor_setting_t *divisor)
   6871 {
   6872     int rv;
   6873     switch(divisor->input_src) {
   6874     case bcmTimeSynceInputSourceTypePort:
   6875         rv = _bcm_esw_time_apachex_synce_clock_set_by_port(unit, clk_src, divisor);
   6876         break;
   6877     case bcmTimeSynceInputSourceTypePLL:
   6878         rv = _bcm_esw_time_apachex_synce_clock_set_by_pll(unit, clk_src, divisor);
   6879         break;
   6880     default:
   6881         rv = BCM_E_PARAM;
   6882         break;
   6883     }
   6884 
   6885     return rv;
   6886 }
   6887 
   6888 
   6889 /*
   6890  * Function:
   6891  *      _bcm_esw_time_apachex_synce_clock_get
   6892  * Purpose:
   6893  *      Get current setting of syncE clock divisor
   6894  * Parameters:
   6895  *      unit    - (IN)  Unit number.
   6896         divisor - (OUT) Divisor setting
   6897  * Returns:
   6898  *      BCM_E_xxx
   6899  * Notes: This function takes care of tomahawk only
   6900  */
   6901 STATIC int
   6902 _bcm_esw_time_apachex_synce_clock_get(int unit,
   6903                               bcm_time_synce_clock_src_type_t clk_src,
   6904                               bcm_time_synce_divisor_setting_t *divisor)
   6905 {
   6906     uint32 val, val2, rval, lport;
   6907     uint32 sdm_val;
   6908     phymod_dispatch_type_t dispatch_type = phymodDispatchTypeInvalid;
   6909 
   6910     switch(clk_src) {
   6911     case bcmTimeSynceClockSourcePrimary:
   6912         /* input source port */
   6913         SOC_IF_ERROR_RETURN(
   6914              READ_TOP_MISC_CONTROL_2r(unit, &rval));
   6915         val = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval,
   6916                                 XG_RCVD_PRI_SELf);
   6917         SOC_IF_ERROR_RETURN(
   6918              READ_EGR_L1_CLK_RECOVERY_CTRLr(unit, &rval));
   6919         val2 = soc_reg_field_get(unit, EGR_L1_CLK_RECOVERY_CTRLr, rval,
   6920                                      PRI_PORT_SELf);
   6921 
   6922         if (val == 0) { /* source is Port */
   6923             uint32 phy_port;
   6924             phy_port = val2 + 1;
   6925             _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   6926             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   6927             divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   6928         } else { /* source is PLL */
   6929             /* TOP_MISC_CONTROL_2.L1_RCVD_PORT_SELf needs to be 0
   6930              * Otherwise, there's no clock output */
   6931             if (val2 != 0) {
   6932                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   6933                             "No clock output\n")));
   6934                 return BCM_E_FAIL;
   6935             }
   6936             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   6937             divisor->index = BCM_TIME_APACHEX_LCPLL_PORT_BASE - val;
   6938         }
   6939 
   6940         /* READ the SDM divisors from TSC */
   6941         if (divisor->input_src == bcmTimeSynceInputSourceTypePort) {
   6942 
   6943             /* input source type port */
   6944             lport = divisor->index;
   6945 
   6946             dispatch_type = _bcm_time_synce_tsc_phymod_dispatch_type_get(unit, lport);
   6947 
   6948             if (dispatch_type == phymodDispatchTypeTsce) {
   6949                 SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_CTRLr(unit, &rval));
   6950                 /* stage0_mode */
   6951                 divisor->stage0_mode = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr,
   6952                                                          rval, STAGE0_MODEf);
   6953                 sdm_val = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr, rval,
   6954                                             SDM_DIVISORf);
   6955                 /* stage0_whole */
   6956                 divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   6957                 /* stage0_frac */
   6958                 divisor->stage0_sdm_frac = sdm_val & 0xff ;
   6959                 /* stage1_div  */
   6960                 divisor->stage1_div = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr,
   6961                                                         rval, STAGE1_MODEf);
   6962 
   6963             } else if (dispatch_type == phymodDispatchTypeTscf) {
   6964                 /* stage0_mode */
   6965                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   6966                      BCM_TIME_TSCF_MAIN0_SYNCE_CTL_STAGE0_REG,  &divisor->stage0_mode));
   6967 
   6968                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   6969                     BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG, &sdm_val));
   6970 
   6971                 /* stage0_whole */
   6972                 divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   6973                 /* stage0_frac */
   6974                 divisor->stage0_sdm_frac = sdm_val & 0xff ;
   6975 
   6976                 /* stage1_div  */
   6977                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   6978                     BCM_TIME_TSCF_MAIN0_SYNCE_CTL_REG, &divisor->stage1_div));
   6979 
   6980             }
   6981         } else {
   6982             /* input source type pll */
   6983              SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_CTRLr(unit, &rval));
   6984             /* stage0_mode */
   6985             divisor->stage0_mode = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr,
   6986                                                      rval, STAGE0_MODEf);
   6987             sdm_val = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr, rval,
   6988                                         SDM_DIVISORf);
   6989             /* stage0_whole */
   6990             divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   6991             /* stage0_frac */
   6992             divisor->stage0_sdm_frac = sdm_val & 0xff ;
   6993             /* stage1_div  */
   6994             divisor->stage1_div = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CTRLr,
   6995                                                     rval, STAGE1_MODEf);
   6996         }
   6997 
   6998         break;
   6999     case bcmTimeSynceClockSourceSecondary:
   7000         /* input source port */
   7001         SOC_IF_ERROR_RETURN(
   7002              READ_TOP_MISC_CONTROL_2r(unit, &rval));
   7003         val = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval,
   7004                                 XG_RCVD_BKUP_SELf);
   7005         SOC_IF_ERROR_RETURN(
   7006              READ_EGR_L1_CLK_RECOVERY_CTRLr(unit, &rval));
   7007         val2 = soc_reg_field_get(unit, EGR_L1_CLK_RECOVERY_CTRLr, rval,
   7008                                      BKUP_PORT_SELf);
   7009 
   7010         if (val == 0) { /* source is Port */
   7011             uint32 phy_port;
   7012             phy_port = val2 + 1;
   7013             _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   7014             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   7015             divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   7016         } else { /* source is PLL */
   7017             /* TOP_MISC_CONTROL_2.L1_RCVD_BKUP_PORT_SELf needs to be 0
   7018              * Otherwise, there's no clock output */
   7019             if (val2 != 0) {
   7020                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   7021                             "No clock output\n")));
   7022                 return BCM_E_FAIL;
   7023             }
   7024             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   7025             divisor->index = BCM_TIME_APACHEX_LCPLL_PORT_BASE- val;
   7026         }
   7027 
   7028         /* READ the SDM divisors from TSC */
   7029         if (divisor->input_src == bcmTimeSynceInputSourceTypePort) {
   7030             lport = divisor->index;
   7031 
   7032             dispatch_type = _bcm_time_synce_tsc_phymod_dispatch_type_get(unit, lport);
   7033 
   7034             if (dispatch_type == phymodDispatchTypeTsce) {
   7035                 SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_BKUP_CTRLr(unit, &rval));
   7036                 /* stage0_mode */
   7037                 divisor->stage0_mode = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr,
   7038                                                          rval, STAGE0_MODEf);
   7039                 sdm_val = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, rval,
   7040                                             SDM_DIVISORf);
   7041                 /* stage0_whole */
   7042                 divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   7043                 /* stage0_frac */
   7044                 divisor->stage0_sdm_frac = sdm_val & 0xff ;
   7045                 /* stage1_div  */
   7046                 divisor->stage1_div = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr,
   7047                                                         rval, STAGE1_MODEf);
   7048             } else if (dispatch_type == phymodDispatchTypeTscf) {
   7049                 /* stage0_mode */
   7050                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   7051                      BCM_TIME_TSCF_MAIN0_SYNCE_CTL_STAGE0_REG,  &divisor->stage0_mode));
   7052 
   7053                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   7054                     BCM_TIME_TSCF_RX_X4_SYNCE_FRACTIONAL_DIV_REG, &sdm_val));
   7055 
   7056                 /* stage0_whole */
   7057                 divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   7058                 /* stage0_frac */
   7059                 divisor->stage0_sdm_frac = sdm_val & 0xff ;
   7060 
   7061                 /* stage1_div  */
   7062                 BCM_IF_ERROR_RETURN(_bcm_time_synce_phy_register_get(unit, lport,
   7063                     BCM_TIME_TSCF_MAIN0_SYNCE_CTL_REG, &divisor->stage1_div));
   7064             }
   7065         } else {
   7066             SOC_IF_ERROR_RETURN(READ_TOP_L1_RCVD_CLK_BKUP_CTRLr(unit, &rval));
   7067             /* stage0_mode */
   7068             divisor->stage0_mode = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr,
   7069                                                      rval, STAGE0_MODEf);
   7070             sdm_val = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr, rval,
   7071                                         SDM_DIVISORf);
   7072             /* stage0_whole */
   7073             divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   7074             /* stage0_frac */
   7075             divisor->stage0_sdm_frac = sdm_val & 0xff ;
   7076             /* stage1_div  */
   7077             divisor->stage1_div = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_BKUP_CTRLr,
   7078                                                     rval, STAGE1_MODEf);
   7079         }
   7080         break;
   7081     /* coverity[dead_error_begin:FALSE] */
   7082     default:
   7083         return BCM_E_PARAM;
   7084     }
   7085 
   7086     return BCM_E_NONE;
   7087 }
   7088 
   7089 
   7090 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT)  || defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT)*/
   7091 
   7092 #if defined(BCM_SABER2_SUPPORT)
   7093 
   7094 #define BCM_TIME_SB2_PORT_VALID(x) ((x) >= 1 && (x) <= 28)
   7095 #define BCM_TIME_SB2_PLL_VALID(x) (((x) >= 0) && ((x) <= 2))
   7096 
   7097 /* NOTES : this function takes care of Saber2 only */
   7098 STATIC int
   7099 _bcm_esw_time_saber2_synce_clock_set_by_port(int unit,
   7100                                bcm_time_synce_clock_src_type_t clk_src,
   7101                                bcm_time_synce_divisor_setting_t *divisor)
   7102 {
   7103     /* Assumes input index is logical port number */
   7104     int lport = divisor->index;
   7105     int phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   7106     int mux_index;
   7107     uint32 phy_reg = 0x9002;
   7108     if (!BCM_TIME_SB2_PORT_VALID(lport) ||
   7109         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   7110         (phy_port == -1)) {
   7111         return BCM_E_PARAM;
   7112     }
   7113 
   7114     mux_index = lport - 1;
   7115 
   7116     if ((mux_index >= 24  &&  mux_index <= 27) &&
   7117             divisor->stage0_mode  == bcmTimeSynceModeBypass) {
   7118         return BCM_E_PARAM;
   7119     }
   7120 
   7121 
   7122     if ( clk_src == bcmTimeSynceClockSourcePrimary ) {
   7123         /* TOP_MISC_CONTROL */
   7124         SOC_IF_ERROR_RETURN
   7125                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7126                                         L1_CLK0_RECOVERY_DIV_CTRLf, 0x0));
   7127         SOC_IF_ERROR_RETURN
   7128                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7129                                         L1_CLK0_RECOVERY_MUX_SELf, mux_index));
   7130         if ((mux_index >= 24  &&  mux_index <= 27) ) {
   7131             /* Egal Ports */
   7132             SOC_IF_ERROR_RETURN
   7133                 (soc_reg_field32_modify(unit, TOP_TSCE_CONFIGr, REG_PORT_ANY,
   7134                                         SYNCE_STAGE0_MODEf, 0x2));
   7135             SOC_IF_ERROR_RETURN
   7136                 (soc_reg_field32_modify(unit, TOP_TSCE_CONFIGr, REG_PORT_ANY,
   7137                                         SDM_DIVISORf, 0x14a0));
   7138             SOC_IF_ERROR_RETURN
   7139                 (soc_reg_field32_modify(unit, TOP_TSCE_CONFIGr, REG_PORT_ANY,
   7140                                         SYNCE_MODEf, 0x0));
   7141             phy_port  = _bcm_switch_port_to_phyaddr(unit, lport);
   7142             if (phy_port == 0xff) {
   7143                 /* no phy address assigned */
   7144                 return BCM_E_PARAM;
   7145             }
   7146             /* all lanes divisor configured 0
   7147              * by default, eagle phy does /11, setting this configuration is
   7148              * mandatory to get correct frequency...
   7149              * Q: do we need to implement per lane reset .. not seen any
   7150              * scenerio though currently
   7151              */
   7152             BCM_IF_ERROR_RETURN(
   7153                 soc_sbus_mdio_write(unit, phy_port, phy_reg, 0));
   7154         } else {
   7155             if (divisor->stage0_mode  == bcmTimeSynceModeSDMFracDiv) {
   7156                 SOC_IF_ERROR_RETURN
   7157                     (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7158                                             L1_CLK0_RECOVERY_DIV_CTRLf, 0x3));
   7159             }
   7160         }
   7161 
   7162         /* enable prim recov clk as VALID indication from invalid status */
   7163         SOC_IF_ERROR_RETURN
   7164             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7165                                     L1_RCVD_CLK0_SW_OVWR_VALIDf, 1));
   7166         SOC_IF_ERROR_RETURN
   7167              (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7168                                      L1_RCVD_SW_OVWR_ENf, 1 ));
   7169 
   7170     } else {
   7171         /* TOP_MISC_CONTROL */
   7172         SOC_IF_ERROR_RETURN
   7173                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7174                                         L1_CLK1_RECOVERY_DIV_CTRLf, 0x0));
   7175         SOC_IF_ERROR_RETURN
   7176                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7177                                         L1_CLK1_RECOVERY_MUX_SELf, mux_index));
   7178         if ((mux_index >= 24  &&  mux_index <= 27) ) {
   7179             /* Egal Ports */
   7180             SOC_IF_ERROR_RETURN
   7181                 (soc_reg_field32_modify(unit, TOP_TSCE_CONFIGr, REG_PORT_ANY,
   7182                                         SYNCE_STAGE0_MODEf, 0x2));
   7183             SOC_IF_ERROR_RETURN
   7184                 (soc_reg_field32_modify(unit, TOP_TSCE_CONFIGr, REG_PORT_ANY,
   7185                                         SDM_DIVISORf, 0x14a0));
   7186             SOC_IF_ERROR_RETURN
   7187                 (soc_reg_field32_modify(unit, TOP_TSCE_CONFIGr, REG_PORT_ANY,
   7188                                         SYNCE_MODEf, 0x0));
   7189             phy_port  = _bcm_switch_port_to_phyaddr(unit, lport);
   7190             if (phy_port == 0xff) {
   7191                 /* no phy address assigned */
   7192                 return BCM_E_PARAM;
   7193             }
   7194             /* all lanes divisor configured 0
   7195              * by default, eagle phy does /11, setting this configuration is
   7196              * mandatory to get correct frequency...
   7197              * Q: do we need to implement per lane reset .. not seen any
   7198              * scenerio though currently
   7199              */
   7200             BCM_IF_ERROR_RETURN(
   7201                 soc_sbus_mdio_write(unit, phy_port, phy_reg, 0));
   7202         } else {
   7203             if (divisor->stage0_mode  == bcmTimeSynceModeSDMFracDiv) {
   7204                 SOC_IF_ERROR_RETURN
   7205                     (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7206                                             L1_CLK1_RECOVERY_DIV_CTRLf, 0x3));
   7207             }
   7208         }
   7209 
   7210         /* enable secondary recov clk as VALID indication from invalid status */
   7211         SOC_IF_ERROR_RETURN
   7212             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7213                                     L1_RCVD_CLK1_SW_OVWR_VALIDf, 1));
   7214         SOC_IF_ERROR_RETURN
   7215              (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7216                                      L1_RCVD_SW_OVWR_ENf, 1 ));
   7217 
   7218 
   7219     }
   7220     return BCM_E_NONE;
   7221 }
   7222 
   7223 /* NOTES : this function takes care of Saber2 only */
   7224 STATIC int
   7225 _bcm_esw_time_saber2_synce_clock_set_by_pll(int unit,
   7226                                bcm_time_synce_clock_src_type_t clk_src,
   7227                                bcm_time_synce_divisor_setting_t *divisor)
   7228 {
   7229     uint32 pll_index = divisor->index;
   7230     uint32 mux_index;
   7231     /* coverity[unsigned_compare] */
   7232     if (!BCM_TIME_SB2_PLL_VALID(pll_index) ||
   7233         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src)) {
   7234         return BCM_E_PARAM;
   7235     }
   7236 
   7237     /* PLL we support only 125MHz */
   7238     if (pll_index < 2 && divisor->stage0_mode == bcmTimeSynceModeSDMFracDiv) {
   7239         return BCM_E_PARAM;
   7240     }
   7241 
   7242     mux_index = pll_index + 28; /* SERDES LCPLL Base for Mux */
   7243 
   7244     if (clk_src == bcmTimeSynceClockSourcePrimary) {
   7245         /* TOP_MISC_CONTROL */
   7246         SOC_IF_ERROR_RETURN
   7247                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7248                                         L1_CLK0_RECOVERY_DIV_CTRLf, 0x0));
   7249         SOC_IF_ERROR_RETURN
   7250                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7251                                         L1_CLK0_RECOVERY_MUX_SELf, mux_index));
   7252 
   7253         /* enable prim recov clk as VALID indication from invalid status */
   7254         SOC_IF_ERROR_RETURN
   7255             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7256                                     L1_RCVD_CLK0_SW_OVWR_VALIDf, 1));
   7257         SOC_IF_ERROR_RETURN
   7258              (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7259                                      L1_RCVD_SW_OVWR_ENf, 1 ));
   7260 
   7261     } else {
   7262         /* TOP_MISC_CONTROL */
   7263         SOC_IF_ERROR_RETURN
   7264                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7265                                         L1_CLK1_RECOVERY_DIV_CTRLf, 0x0));
   7266         SOC_IF_ERROR_RETURN
   7267                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7268                                         L1_CLK1_RECOVERY_MUX_SELf, mux_index));
   7269 
   7270         /* enable secondary recov clk as VALID indication from invalid status */
   7271         SOC_IF_ERROR_RETURN
   7272             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7273                                     L1_RCVD_CLK1_SW_OVWR_VALIDf, 1));
   7274         SOC_IF_ERROR_RETURN
   7275              (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7276                                      L1_RCVD_SW_OVWR_ENf, 1 ));
   7277 
   7278     }
   7279     return BCM_E_NONE;
   7280 }
   7281 
   7282 /*
   7283  * Function:
   7284  *      _bcm_esw_time_saber2_synce_clock_set
   7285  * Purpose:
   7286  *      Set syncE divisor setting
   7287  * Parameters:
   7288  *      unit      - (IN) Unit number.
   7289  *      clk_src   - (IN) clock source type (Primary, Secondary)
   7290  *      input_src - (IN) input source type (PORT, PLL)
   7291  *      index     - (IN) if input_src is PORT, specify logical port number 0..30
   7292  *                       if input_src is PLL, specify PLL index 0..2
   7293  *      divisor   - (IN) divisor setting.
   7294  * Returns:
   7295  *      BCM_E_xxx
   7296  * Notes: This function only configures for SB2
   7297  */
   7298 STATIC int
   7299 _bcm_esw_time_saber2_synce_clock_set(int unit,
   7300                               bcm_time_synce_clock_src_type_t clk_src,
   7301                               bcm_time_synce_divisor_setting_t *divisor)
   7302 {
   7303     int rv;
   7304     switch(divisor->input_src) {
   7305     case bcmTimeSynceInputSourceTypePort:
   7306         rv = _bcm_esw_time_saber2_synce_clock_set_by_port(unit, clk_src, divisor);
   7307         break;
   7308     case bcmTimeSynceInputSourceTypePLL:
   7309         rv = _bcm_esw_time_saber2_synce_clock_set_by_pll(unit, clk_src, divisor);
   7310         break;
   7311     default:
   7312         rv = BCM_E_PARAM;
   7313         break;
   7314     }
   7315 
   7316     return rv;
   7317 }
   7318 
   7319 /*
   7320  * Function:
   7321  *      _bcm_esw_time_saber2_synce_clock_get
   7322  * Purpose:
   7323  *      Get current setting of syncE clock divisor
   7324  * Parameters:
   7325  *      unit    - (IN)  Unit number.
   7326         divisor - (OUT) Divisor setting
   7327  * Returns:
   7328  *      BCM_E_xxx
   7329  * Notes: This function takes care of Saber2 only
   7330  */
   7331 STATIC int
   7332 _bcm_esw_time_saber2_synce_clock_get(int unit,
   7333                               bcm_time_synce_clock_src_type_t clk_src,
   7334                               bcm_time_synce_divisor_setting_t *divisor)
   7335 {
   7336     uint32 mux_val, div_val, rval;
   7337     uint16 phy_port;
   7338 
   7339     switch(clk_src) {
   7340     case bcmTimeSynceClockSourcePrimary:
   7341         /* input source */
   7342         SOC_IF_ERROR_RETURN(
   7343              READ_TOP_MISC_CONTROL_0r(unit, &rval));
   7344         mux_val = soc_reg_field_get(unit, TOP_MISC_CONTROL_0r, rval,
   7345                                 L1_CLK0_RECOVERY_MUX_SELf);
   7346         div_val = soc_reg_field_get(unit, TOP_MISC_CONTROL_0r, rval,
   7347                                 L1_CLK0_RECOVERY_DIV_CTRLf);
   7348         if (mux_val <= 27) { /* source is Port */
   7349             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   7350             phy_port = mux_val + 1;
   7351             divisor->index = phy_port;
   7352             /* stage0_mode */
   7353             if ((div_val & 0x3) && (mux_val <=23))
   7354                 divisor->stage0_mode = bcmTimeSynceModeSDMFracDiv;
   7355             else if (mux_val >= 24 && mux_val <=27)
   7356                 divisor->stage0_mode = bcmTimeSynceModeSDMFracDiv;
   7357             else
   7358                 divisor->stage0_mode = bcmTimeSynceModeBypass;
   7359 
   7360         } else { /* source is PLL */
   7361             if (mux_val > 30) {
   7362                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   7363                             "No clock output\n")));
   7364                 return BCM_E_FAIL;
   7365             }
   7366             divisor->stage0_mode = bcmTimeSynceModeBypass;
   7367             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   7368             divisor->index = mux_val - 28;
   7369         }
   7370 
   7371         break;
   7372     case bcmTimeSynceClockSourceSecondary:
   7373         /* input source */
   7374         SOC_IF_ERROR_RETURN(
   7375              READ_TOP_MISC_CONTROL_0r(unit, &rval));
   7376         mux_val = soc_reg_field_get(unit, TOP_MISC_CONTROL_0r, rval,
   7377                                 L1_CLK1_RECOVERY_MUX_SELf);
   7378         div_val = soc_reg_field_get(unit, TOP_MISC_CONTROL_0r, rval,
   7379                                 L1_CLK1_RECOVERY_DIV_CTRLf);
   7380         if (mux_val <= 27) {
   7381             /* source is Port */
   7382             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   7383             phy_port = mux_val + 1;
   7384             divisor->index = phy_port;
   7385             /* stage0_mode */
   7386             if ((div_val & 0x3) && (mux_val <=23))
   7387                 divisor->stage0_mode = bcmTimeSynceModeSDMFracDiv;
   7388             else if (mux_val >= 24 && mux_val <=27)
   7389                 divisor->stage0_mode = bcmTimeSynceModeSDMFracDiv;
   7390             else
   7391                 divisor->stage0_mode = bcmTimeSynceModeBypass;
   7392         } else {
   7393             /* source is PLL */
   7394             if (mux_val > 30) {
   7395                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   7396                             "No clock output\n")));
   7397                 return BCM_E_FAIL;
   7398             }
   7399             divisor->stage0_mode = bcmTimeSynceModeBypass;
   7400             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   7401             divisor->index = mux_val - 28;
   7402         }
   7403         break;
   7404     default:
   7405         return BCM_E_PARAM;
   7406     }
   7407     return BCM_E_NONE;
   7408 }
   7409 #endif
   7410 
   7411 #if defined(BCM_METROLITE_SUPPORT)
   7412 
   7413 #define BCM_TIME_ML_PORT_VALID(x) ((x) >= 1 && (x) <= 12) /* Table23, ML top spec(ver0p1) */
   7414 #define BCM_TIME_ML_PLL_VALID(x) ((x) <= 1) /* Table23, ML top spec(verop1) */
   7415 
   7416 STATIC int
   7417 _bcm_esw_time_metrolite_synce_clock_set_by_port(int unit,
   7418                                bcm_time_synce_clock_src_type_t clk_src,
   7419                                bcm_time_synce_divisor_setting_t *divisor)
   7420 {
   7421     /* Assumes input index is logical port number */
   7422     int lport = divisor->index;
   7423     int phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   7424     int mux_index;
   7425     uint32 phy_reg = 0x9002;
   7426     if (!BCM_TIME_ML_PORT_VALID(lport) ||
   7427         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   7428         (phy_port == -1)) {
   7429         return BCM_E_PARAM;
   7430     }
   7431 
   7432     mux_index = lport - 1;
   7433 
   7434     /* For eagle TSCE synce div logic handled by portmacro */
   7435     if ((mux_index >= 4  &&  mux_index <= 11) &&
   7436             divisor->stage0_mode  == bcmTimeSynceModeBypass) {
   7437         return BCM_E_PARAM;
   7438     }
   7439 
   7440 
   7441     if ( clk_src == bcmTimeSynceClockSourcePrimary ) {
   7442         /* TOP_MISC_CONTROL */
   7443         SOC_IF_ERROR_RETURN
   7444                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7445                                         L1_CLK0_RECOVERY_DIV_CTRLf, 0x5)); /* Table25 ML top spec ::enable active_reset
   7446                                                                             * and TSCE synce div logic
   7447                                                                             */
   7448         SOC_IF_ERROR_RETURN
   7449                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7450                                         L1_CLK0_RECOVERY_MUX_SELf, mux_index));
   7451         if ((mux_index >= 4  &&  mux_index <= 11) ) {
   7452             /* Eagle Ports */
   7453             SOC_IF_ERROR_RETURN
   7454                 (soc_reg_field32_modify(unit, TOP_TSC_SYNCE_DIV_CONFIG_0r, REG_PORT_ANY,
   7455                                         SYNCE_STAGE0_MODEf, 0x2)); /* TSCE stage0 divisor(SDM mode choosen) */
   7456             SOC_IF_ERROR_RETURN
   7457                 (soc_reg_field32_modify(unit, TOP_TSC_SYNCE_DIV_CONFIG_0r, REG_PORT_ANY,
   7458                                         SDM_DIVISORf, 0x14a0)); /* TSCE SDM divisor */
   7459             SOC_IF_ERROR_RETURN
   7460                 (soc_reg_field32_modify(unit, TOP_TSC_SYNCE_DIV_CONFIG_0r, REG_PORT_ANY,
   7461                                         SYNCE_MODEf, 0x0)); /* TSCE stage1 divisor(div1 choosen) */
   7462             phy_port  = _bcm_switch_port_to_phyaddr(unit, lport);
   7463             if (phy_port == 0xff) {
   7464                 /* no phy address assigned */
   7465                 return BCM_E_PARAM;
   7466             }
   7467             /* all lanes divisor configured 0
   7468              * by default, eagle phy does /11, setting this configuration is
   7469              * mandatory to get correct frequency...
   7470              * Q: do we need to implement per lane reset .. not seen any
   7471              * scenerio though currently
   7472              */
   7473             BCM_IF_ERROR_RETURN(
   7474                 soc_sbus_mdio_write(unit, phy_port, phy_reg, 0));
   7475         } else { /* for viper ports : 25MHz/125MHz L1 recovery */
   7476             if (divisor->stage0_mode  == bcmTimeSynceModeSDMFracDiv) { /* 25MHz L1 recovery from viper ports */
   7477                 SOC_IF_ERROR_RETURN
   7478                     (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7479                                             L1_CLK0_RECOVERY_DIV_CTRLf, 0x3)); /* enable active_reset and default div5 logic */
   7480             } else { /* 125MHz L1 recovery from viper ports*/
   7481                 SOC_IF_ERROR_RETURN
   7482                     (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7483                                             L1_CLK0_RECOVERY_DIV_CTRLf, 0x1));
   7484             }
   7485         }
   7486 
   7487         /* enable prim recov clk as VALID indication from invalid status */
   7488         SOC_IF_ERROR_RETURN
   7489             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7490                                     L1_RCVD_CLK0_SW_OVWR_VALIDf, 1));
   7491         SOC_IF_ERROR_RETURN
   7492              (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7493                                      L1_RCVD_SW_OVWR_ENf, 1 ));
   7494 
   7495     } else {
   7496         /* TOP_MISC_CONTROL */
   7497         SOC_IF_ERROR_RETURN
   7498                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7499                                         L1_CLK1_RECOVERY_DIV_CTRLf, 0x5));/* Table25 ML top spec ::enable active_reset
   7500                                                                             * and TSCE synce div logic
   7501                                                                             */
   7502         SOC_IF_ERROR_RETURN
   7503                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7504                                         L1_CLK1_RECOVERY_MUX_SELf, mux_index));
   7505         if ((mux_index >= 4  &&  mux_index <= 11) ) {
   7506             /* Eagle Ports */
   7507             SOC_IF_ERROR_RETURN
   7508                 (soc_reg_field32_modify(unit, TOP_TSC_SYNCE_DIV_CONFIG_1r, REG_PORT_ANY,
   7509                                         SYNCE_STAGE0_MODEf, 0x2)); /* TSCE stage0 divisor(SDM mode choosen) */
   7510             SOC_IF_ERROR_RETURN
   7511                 (soc_reg_field32_modify(unit, TOP_TSC_SYNCE_DIV_CONFIG_1r, REG_PORT_ANY,
   7512                                         SDM_DIVISORf, 0x14a0)); /* TSCE SDM divisor */
   7513             SOC_IF_ERROR_RETURN
   7514                 (soc_reg_field32_modify(unit, TOP_TSC_SYNCE_DIV_CONFIG_1r, REG_PORT_ANY,
   7515                                         SYNCE_MODEf, 0x0)); /* TSCE stage1 divisor(div1 choosen) */
   7516 
   7517             phy_port  = _bcm_switch_port_to_phyaddr(unit, lport);
   7518             if (phy_port == 0xff) {
   7519                 /* no phy address assigned */
   7520                 return BCM_E_PARAM;
   7521             }
   7522             /* all lanes divisor configured 0
   7523              * by default, eagle phy does /11, setting this configuration is
   7524              * mandatory to get correct frequency...
   7525              * Q: do we need to implement per lane reset .. not seen any
   7526              * scenerio though currently
   7527              */
   7528             BCM_IF_ERROR_RETURN(
   7529                 soc_sbus_mdio_write(unit, phy_port, phy_reg, 0));
   7530         } else { /* for viper ports : 25MHz/125MHz L1 recovery */
   7531             if (divisor->stage0_mode  == bcmTimeSynceModeSDMFracDiv) { /* 25MHz L1 recovery from viper ports */
   7532                 SOC_IF_ERROR_RETURN
   7533                     (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7534                                             L1_CLK1_RECOVERY_DIV_CTRLf, 0x3)); /* enable active_reset and default div5 logic */
   7535             } else { /* 125MHz L1 recovery from viper ports */
   7536                 SOC_IF_ERROR_RETURN
   7537                     (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7538                                             L1_CLK1_RECOVERY_DIV_CTRLf, 0x1)); /* enable only active_reset */
   7539             }
   7540         }
   7541         /* enable secondary recov clk as VALID indication from invalid status */
   7542         SOC_IF_ERROR_RETURN
   7543             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7544                                     L1_RCVD_CLK1_SW_OVWR_VALIDf, 1));
   7545         SOC_IF_ERROR_RETURN
   7546              (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7547                                      L1_RCVD_SW_OVWR_ENf, 1 ));
   7548 
   7549     }
   7550     return BCM_E_NONE;
   7551 }
   7552 
   7553 STATIC int
   7554 _bcm_esw_time_metrolite_synce_clock_set_by_pll(int unit,
   7555                                bcm_time_synce_clock_src_type_t clk_src,
   7556                                bcm_time_synce_divisor_setting_t *divisor)
   7557 {
   7558     uint32 pll_index = divisor->index;
   7559     uint32 mux_index;
   7560 
   7561     if (!BCM_TIME_ML_PLL_VALID(pll_index) ||
   7562         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src)) {
   7563         return BCM_E_PARAM;
   7564     }
   7565 
   7566     /* MasterLCPLL we support only 125MHz */
   7567     if (pll_index < 1 && divisor->stage0_mode == bcmTimeSynceModeSDMFracDiv) {
   7568         return BCM_E_PARAM;
   7569     }
   7570 
   7571     mux_index = pll_index + 12; /* Master LCPLL Base for Mux */
   7572 
   7573     if (clk_src == bcmTimeSynceClockSourcePrimary) {
   7574         /* TOP_MISC_CONTROL */
   7575         SOC_IF_ERROR_RETURN
   7576                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7577                                         L1_CLK0_RECOVERY_DIV_CTRLf, 0x1)); /*Table22, ML top spec::enable active_reset only*/
   7578         SOC_IF_ERROR_RETURN
   7579                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7580                                         L1_CLK0_RECOVERY_MUX_SELf, mux_index));
   7581 
   7582         /* enable prim recov clk as VALID indication from invalid status */
   7583         SOC_IF_ERROR_RETURN
   7584             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7585                                     L1_RCVD_CLK0_SW_OVWR_VALIDf, 1));
   7586         SOC_IF_ERROR_RETURN
   7587              (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7588                                      L1_RCVD_SW_OVWR_ENf, 1 ));
   7589 
   7590     } else {
   7591         /* TOP_MISC_CONTROL */
   7592         SOC_IF_ERROR_RETURN
   7593                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7594                                         L1_CLK1_RECOVERY_DIV_CTRLf, 0x1));/*Table22, ML top spec::enable active_reset only*/
   7595         SOC_IF_ERROR_RETURN
   7596                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_0r, REG_PORT_ANY,
   7597                                         L1_CLK1_RECOVERY_MUX_SELf, mux_index));
   7598 
   7599         /* enable secondary recov clk as VALID indication from invalid status */
   7600         SOC_IF_ERROR_RETURN
   7601             (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7602                                     L1_RCVD_CLK1_SW_OVWR_VALIDf, 1));
   7603         SOC_IF_ERROR_RETURN
   7604              (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   7605                                      L1_RCVD_SW_OVWR_ENf, 1 ));
   7606 
   7607     }
   7608     return BCM_E_NONE;
   7609 }
   7610 
   7611 /*
   7612  * Function:
   7613  *      _bcm_esw_time_metrolite_synce_clock_set
   7614  * Purpose:
   7615  *      Set syncE divisor setting
   7616  * Parameters:
   7617  *      unit      - (IN) Unit number.
   7618  *      clk_src   - (IN) clock source type (Primary, Secondary)
   7619  *      input_src - (IN) input source type (PORT, PLL)
   7620  *      index     - (IN) if input_src is PORT, specify logical port number 0..30
   7621  *                       if input_src is PLL, specify PLL index 0..2
   7622  *      divisor   - (IN) divisor setting.
   7623  * Returns:
   7624  *      BCM_E_xxx
   7625  * Notes: ML specific function
   7626  */
   7627 STATIC int
   7628 _bcm_esw_time_metrolite_synce_clock_set(int unit,
   7629                               bcm_time_synce_clock_src_type_t clk_src,
   7630                               bcm_time_synce_divisor_setting_t *divisor)
   7631 {
   7632     int rv;
   7633     switch(divisor->input_src) {
   7634     case bcmTimeSynceInputSourceTypePort:
   7635         rv = _bcm_esw_time_metrolite_synce_clock_set_by_port(unit, clk_src, divisor);
   7636         break;
   7637     case bcmTimeSynceInputSourceTypePLL:
   7638         rv = _bcm_esw_time_metrolite_synce_clock_set_by_pll(unit, clk_src, divisor);
   7639         break;
   7640     default:
   7641         rv = BCM_E_PARAM;
   7642         break;
   7643     }
   7644 
   7645     return rv;
   7646 }
   7647 
   7648 /*
   7649  * Function:
   7650  *      _bcm_esw_time_metrolite_synce_clock_get
   7651  * Purpose:
   7652  *      Get current setting of syncE clock divisor
   7653  * Parameters:
   7654  *      unit    - (IN)  Unit number.
   7655         divisor - (OUT) Divisor setting
   7656  * Returns:
   7657  *      BCM_E_xxx
   7658  * Notes: This function takes care of Saber2 only
   7659  */
   7660 STATIC int
   7661 _bcm_esw_time_metrolite_synce_clock_get(int unit,
   7662                               bcm_time_synce_clock_src_type_t clk_src,
   7663                               bcm_time_synce_divisor_setting_t *divisor)
   7664 {
   7665     uint32 mux_val, div_val, rval;
   7666     uint16 phy_port;
   7667 
   7668     switch(clk_src) {
   7669     case bcmTimeSynceClockSourcePrimary:
   7670         /* input source */
   7671         SOC_IF_ERROR_RETURN(
   7672              READ_TOP_MISC_CONTROL_0r(unit, &rval));
   7673         mux_val = soc_reg_field_get(unit, TOP_MISC_CONTROL_0r, rval,
   7674                                 L1_CLK0_RECOVERY_MUX_SELf);
   7675         div_val = soc_reg_field_get(unit, TOP_MISC_CONTROL_0r, rval,
   7676                                 L1_CLK0_RECOVERY_DIV_CTRLf);
   7677         if (mux_val <= 11) { /* source is Port */
   7678             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   7679             phy_port = mux_val + 1;
   7680             divisor->index = phy_port;
   7681             /* stage0_mode */
   7682             if ((div_val & 0x3) && (mux_val <=3))
   7683                 divisor->stage0_mode = bcmTimeSynceModeSDMFracDiv;
   7684             else if ((div_val & 0x5) && (mux_val >= 4 && mux_val <=11))
   7685                 divisor->stage0_mode = bcmTimeSynceModeSDMFracDiv;
   7686             else
   7687                 divisor->stage0_mode = bcmTimeSynceModeBypass;
   7688 
   7689         } else { /* source is PLL */
   7690             if (mux_val > 13) {
   7691                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   7692                             "No clock output\n")));
   7693                 return BCM_E_FAIL;
   7694             }
   7695             divisor->stage0_mode = bcmTimeSynceModeBypass;
   7696             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   7697             divisor->index = mux_val - 12;
   7698         }
   7699 
   7700         break;
   7701     case bcmTimeSynceClockSourceSecondary:
   7702         /* input source */
   7703         SOC_IF_ERROR_RETURN(
   7704              READ_TOP_MISC_CONTROL_0r(unit, &rval));
   7705         mux_val = soc_reg_field_get(unit, TOP_MISC_CONTROL_0r, rval,
   7706                                 L1_CLK1_RECOVERY_MUX_SELf);
   7707         div_val = soc_reg_field_get(unit, TOP_MISC_CONTROL_0r, rval,
   7708                                 L1_CLK1_RECOVERY_DIV_CTRLf);
   7709         if (mux_val <= 11) {
   7710             /* source is Port */
   7711             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   7712             phy_port = mux_val + 1;
   7713             divisor->index = phy_port;
   7714             /* stage0_mode */
   7715             if ((div_val & 0x3) && (mux_val <=3))
   7716                 divisor->stage0_mode = bcmTimeSynceModeSDMFracDiv;
   7717             else if ((div_val & 0x5) && (mux_val >= 4 && mux_val <=11))
   7718                 divisor->stage0_mode = bcmTimeSynceModeSDMFracDiv;
   7719             else
   7720                 divisor->stage0_mode = bcmTimeSynceModeBypass;
   7721         } else {
   7722             /* source is PLL */
   7723             if (mux_val > 13) {
   7724                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   7725                             "No clock output\n")));
   7726                 return BCM_E_FAIL;
   7727             }
   7728             divisor->stage0_mode = bcmTimeSynceModeBypass;
   7729             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   7730             divisor->index = mux_val - 12;
   7731         }
   7732         break;
   7733     default:
   7734         return BCM_E_PARAM;
   7735     }
   7736     return BCM_E_NONE;
   7737 }
   7738 #endif /* defined(BCM_METROLITE_SUPPORT) */
   7739 
   7740 #if defined(BCM_TRIDENT3_SUPPORT)
   7741 
   7742 #define BCM_TIME_TD3_PHY_PORT_VALID(x) ((x) >= 1 && (x) <= 128) /* Section 10.2.4, TD3 top spec */
   7743 #define BCM_TIME_TD3_PLL_VALID(x) ((x) <= 3) /* Section 10.2.4 Top spec  */
   7744 
   7745 STATIC int
   7746 _bcm_esw_time_trident3_synce_clock_set_by_port(int unit,
   7747                                bcm_time_synce_clock_src_type_t clk_src,
   7748                                bcm_time_synce_divisor_setting_t *divisor)
   7749 {
   7750     /* Assumes input index is logical port number */
   7751     int lport = divisor->index;
   7752     int phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   7753     int port_sel;
   7754     uint16 sdm_val;
   7755     portmod_port_synce_clk_ctrl_t config;
   7756     if(!IS_CL_PORT(unit, lport))
   7757         return BCM_E_PARAM;
   7758 
   7759     if (!BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   7760         !BCM_TIME_TD3_PHY_PORT_VALID(phy_port)) {
   7761         return BCM_E_PARAM;
   7762     }
   7763 
   7764     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   7765         NULL, &phy_port));
   7766 
   7767     port_sel = phy_port - 1;
   7768 
   7769     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   7770 
   7771     switch (clk_src) {
   7772     case bcmTimeSynceClockSourcePrimary:
   7773             /* TOP_MISC_CONTROL */
   7774             SOC_IF_ERROR_RETURN
   7775                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   7776                                         L1_RCVD_CLK_RSTNf, 0));
   7777 
   7778             /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   7779             SOC_IF_ERROR_RETURN
   7780                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   7781                                         L1_RCVD_FREQ_SELf, 0));
   7782 
   7783             /* Set TSCF SDM divisors */
   7784             /* Set SDM stage 1 mode to bypass */
   7785 
   7786             sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   7787                        (divisor->stage0_sdm_frac & 0xff));
   7788 
   7789             config.stg0_mode = divisor->stage0_mode;
   7790             config.stg1_mode = 0x0;
   7791             config.sdm_val = sdm_val;
   7792             if (!SOC_PORT_VALID(unit,lport)) 
   7793             {
   7794                 return BCM_E_PARAM;
   7795             }
   7796             SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_set(unit, lport, &config));
   7797 
   7798             /* TOP_MISC_CONTROL_2  - set sg pll port sel 0 */
   7799             SOC_IF_ERROR_RETURN
   7800                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   7801                                         XG_RCVD_SELf, 0));
   7802 
   7803             /* serdes port configuration */
   7804             SOC_IF_ERROR_RETURN
   7805                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r,
   7806                                         REG_PORT_ANY, L1_RCVD_PORT_SELf, port_sel));
   7807 
   7808             /* TOP_MISC_CONTROL */
   7809             SOC_IF_ERROR_RETURN
   7810                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   7811                                         L1_RCVD_CLK_RSTNf, 1));
   7812             break;
   7813     case bcmTimeSynceClockSourceSecondary:
   7814             /* TOP_MISC_CONTROL */
   7815             SOC_IF_ERROR_RETURN
   7816                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   7817                                         L1_RCVD_CLK_BKUP_RSTNf, 0));
   7818 
   7819             /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   7820             SOC_IF_ERROR_RETURN
   7821                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   7822                                         L1_RCVD_BKUP_FREQ_SELf, 0));
   7823 
   7824             /* Set TSCF SDM divisors */
   7825             /* Set SDM stage 1 mode to bypass */
   7826             sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   7827                        (divisor->stage0_sdm_frac & 0xff));
   7828 
   7829             config.stg0_mode = divisor->stage0_mode;
   7830             config.stg1_mode = 0x0;
   7831             config.sdm_val = sdm_val;
   7832             if (!SOC_PORT_VALID(unit,lport)) 
   7833             {
   7834                 return BCM_E_PARAM;
   7835             }
   7836             SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_set(unit, lport, &config));
   7837 
   7838             /* TOP_MISC_CONTROL_2 - set sg pll port sel 0*/
   7839             SOC_IF_ERROR_RETURN
   7840                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   7841                                         XG_RCVD_BKUP_SELf, 0));
   7842 
   7843             /* serdes port configuration */
   7844             SOC_IF_ERROR_RETURN
   7845                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r,
   7846                                         REG_PORT_ANY, L1_RCVD_BKUP_PORT_SELf, port_sel));
   7847 
   7848             /* TOP_MISC_CONTROL */
   7849             SOC_IF_ERROR_RETURN
   7850                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   7851                                         L1_RCVD_CLK_BKUP_RSTNf, 1));
   7852         break;
   7853     /* coverity[dead_error_begin:FALSE] */
   7854     default:
   7855         return BCM_E_PARAM;
   7856 
   7857     }
   7858     return BCM_E_NONE;
   7859 }
   7860 
   7861 /*
   7862  * Function:
   7863  *      _bcm_esw_time_trident3_synce_clock_get
   7864  * Purpose:
   7865  *      Get current setting of syncE clock divisor
   7866  * Parameters:
   7867  *      unit    - (IN)  Unit number.
   7868         divisor - (OUT) Divisor setting
   7869  * Returns:
   7870  *      BCM_E_xxx
   7871  * Notes: This function takes care of trident3 only
   7872  */
   7873 STATIC int
   7874 _bcm_esw_time_trident3_synce_clock_get(int unit,
   7875                               bcm_time_synce_clock_src_type_t clk_src,
   7876                               bcm_time_synce_divisor_setting_t *divisor)
   7877 {
   7878     uint32 val, val2, rval;
   7879     int lport;
   7880     uint32 sdm_val;
   7881     portmod_port_synce_clk_ctrl_t config;
   7882     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   7883 
   7884     switch(clk_src) {
   7885     case bcmTimeSynceClockSourcePrimary:
   7886         /* input source port */
   7887         SOC_IF_ERROR_RETURN( READ_TOP_MISC_CONTROL_2r(unit, &rval));
   7888 
   7889         val = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval, XG_RCVD_SELf);
   7890         val2 = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval, L1_RCVD_PORT_SELf);
   7891 
   7892         if (val == 0) { /* source is Port */
   7893             uint32 phy_port;
   7894             phy_port = val2 + 1;
   7895             _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   7896             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   7897             divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   7898         } else { /* source is PLL */
   7899             /* TOP_MISC_CONTROL_2.L1_RCVD_PORT_SELf needs to be 0
   7900              * Otherwise, there's no clock output */
   7901             if (val2 != 0) {
   7902                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   7903                             "No clock output\n")));
   7904                 return BCM_E_FAIL;
   7905             }
   7906             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   7907             divisor->index = val - 1;
   7908         }
   7909 
   7910         /* READ the SDM divisors from TSC */
   7911         lport = divisor->index;
   7912         if (!SOC_PORT_VALID(unit,lport)) 
   7913         {
   7914             return BCM_E_PARAM;
   7915         }
   7916         SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_get(unit, lport, &config));
   7917 
   7918         /* stage0_mode */
   7919         divisor->stage0_mode = config.stg0_mode;
   7920 
   7921         sdm_val = config.sdm_val;
   7922 
   7923         /* stage0_whole */
   7924         divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   7925         /* stage0_frac */
   7926         divisor->stage0_sdm_frac = sdm_val & 0xff ;
   7927 
   7928         /* stage1_div  */
   7929         divisor->stage1_div = config.stg1_mode;
   7930 
   7931         break;
   7932     case bcmTimeSynceClockSourceSecondary:
   7933         /* input source port */
   7934         SOC_IF_ERROR_RETURN( READ_TOP_MISC_CONTROL_2r(unit, &rval));
   7935 
   7936         val = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval, XG_RCVD_BKUP_SELf);
   7937         val2 = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, rval, L1_RCVD_BKUP_PORT_SELf);
   7938 
   7939         if (val == 0) { /* source is Port */
   7940             uint32 phy_port;
   7941             phy_port = val2 + 1;
   7942             _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   7943             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   7944             divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   7945         } else { /* source is PLL */
   7946             /* TOP_MISC_CONTROL_2.L1_RCVD_BKUP_PORT_SELf needs to be 0
   7947              * Otherwise, there's no clock output */
   7948             if (val2 != 0) {
   7949                 LOG_ERROR(BSL_LS_BCM_TIME, (BSL_META_U(unit,
   7950                             "No clock output\n")));
   7951                 return BCM_E_FAIL;
   7952             }
   7953             divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   7954             divisor->index = val - 1;
   7955         }
   7956 
   7957         /* READ the SDM divisors from TSC */
   7958         lport = divisor->index;
   7959         if (!SOC_PORT_VALID(unit,lport)) 
   7960         {
   7961             return BCM_E_PARAM;
   7962         }
   7963 
   7964         SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_get(unit, lport, &config));
   7965 
   7966         /* stage0_mode */
   7967         divisor->stage0_mode = config.stg0_mode;
   7968 
   7969         sdm_val = config.sdm_val;
   7970 
   7971         /* stage0_whole */
   7972         divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   7973         /* stage0_frac */
   7974         divisor->stage0_sdm_frac = sdm_val & 0xff ;
   7975 
   7976         /* stage1_div  */
   7977         divisor->stage1_div = config.stg1_mode;
   7978 
   7979 
   7980         break;
   7981     /* coverity[dead_error_begin:FALSE] */
   7982     default:
   7983         return BCM_E_PARAM;
   7984     }
   7985 
   7986     return BCM_E_NONE;
   7987 }
   7988 
   7989 
   7990 STATIC int
   7991 _bcm_esw_time_trident3_synce_clock_set_by_pll(int unit,
   7992                                bcm_time_synce_clock_src_type_t clk_src,
   7993                                bcm_time_synce_divisor_setting_t *divisor)
   7994 {
   7995     uint32 pll_index = divisor->index;
   7996 
   7997     if (!BCM_TIME_TD3_PLL_VALID(pll_index) ||
   7998         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src)) {
   7999         return BCM_E_PARAM;
   8000     }
   8001     switch (clk_src) {
   8002         case bcmTimeSynceClockSourcePrimary:
   8003             /* TOP_MISC_CONTROL */
   8004             SOC_IF_ERROR_RETURN
   8005                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   8006                                         L1_RCVD_CLK_RSTNf, 0));
   8007 
   8008             /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   8009             SOC_IF_ERROR_RETURN
   8010                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   8011                                         L1_RCVD_FREQ_SELf, 0));
   8012 
   8013             /* TOP_MISC_CONTROL_2  - set sg pll port sel 0 */
   8014             SOC_IF_ERROR_RETURN
   8015                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   8016                                         XG_RCVD_SELf, pll_index));
   8017 
   8018             /* TOP_MISC_CONTROL */
   8019             SOC_IF_ERROR_RETURN
   8020                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   8021                                         L1_RCVD_CLK_RSTNf, 1));
   8022             break;
   8023 
   8024     case bcmTimeSynceClockSourceSecondary:
   8025             /* TOP_MISC_CONTROL */
   8026             SOC_IF_ERROR_RETURN
   8027                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   8028                                         L1_RCVD_CLK_BKUP_RSTNf, 0));
   8029 
   8030             /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   8031             SOC_IF_ERROR_RETURN
   8032                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   8033                                         L1_RCVD_BKUP_FREQ_SELf, 0));
   8034 
   8035             /* TOP_MISC_CONTROL_2 - set sg pll port sel 0*/
   8036             SOC_IF_ERROR_RETURN
   8037                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   8038                                         XG_RCVD_BKUP_SELf, pll_index));
   8039 
   8040             /* TOP_MISC_CONTROL */
   8041             SOC_IF_ERROR_RETURN
   8042                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   8043                                         L1_RCVD_CLK_BKUP_RSTNf, 1));
   8044             break;
   8045     }
   8046     return BCM_E_NONE;
   8047 }
   8048 
   8049 /*
   8050  * Function:
   8051  *      _bcm_esw_time_trident3_synce_clock_set
   8052  * Purpose:
   8053  *      Set syncE divisor setting
   8054  * Parameters:
   8055  *      unit      - (IN) Unit number.
   8056  *      clk_src   - (IN) clock source type (Primary, Secondary)
   8057  *      input_src - (IN) input source type (PORT, PLL)
   8058  *      index     - (IN) if input_src is PORT, specify logical port number 0..105
   8059  *                       if input_src is PLL, specify PLL index 0..3
   8060  *      divisor   - (IN) divisor setting.
   8061  * Returns:
   8062  *      BCM_E_xxx
   8063  * Notes: This function only configures for td2plus
   8064  */
   8065 STATIC int
   8066 _bcm_esw_time_trident3_synce_clock_set(int unit,
   8067                               bcm_time_synce_clock_src_type_t clk_src,
   8068                               bcm_time_synce_divisor_setting_t *divisor)
   8069 {
   8070     int rv;
   8071 
   8072     switch(divisor->input_src) {
   8073     case bcmTimeSynceInputSourceTypePort:
   8074         rv = _bcm_esw_time_trident3_synce_clock_set_by_port(unit, clk_src, divisor);
   8075         break;
   8076     case bcmTimeSynceInputSourceTypePLL:
   8077         rv = _bcm_esw_time_trident3_synce_clock_set_by_pll(unit, clk_src, divisor);
   8078         break;
   8079     default:
   8080         rv = BCM_E_PARAM;
   8081         break;
   8082     }
   8083 
   8084     return rv;
   8085 }
   8086 
   8087 
   8088 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   8089 
   8090 #if defined(BCM_MAVERICK2_SUPPORT)
   8091 
   8092 #define BCM_TIME_MV2_PHY_PORT_VALID(x) ((x) >= 0 && (x) <= 80) /* Section 10.2.2 and 5.2, MV2 top spec */
   8093 STATIC int
   8094 _bcm_esw_time_maverick2_synce_clock_set_by_port(int unit,
   8095                                bcm_time_synce_clock_src_type_t clk_src,
   8096                                bcm_time_synce_divisor_setting_t *divisor)
   8097 {   
   8098     /* Assumes input index is logical port number */
   8099     int lport = divisor->index;
   8100     int phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   8101     int port_sel;
   8102     uint16 sdm_val;
   8103     portmod_port_synce_clk_ctrl_t config;
   8104     
   8105     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8106     soc_field_t l1_rcvd_clk_rstn = L1_RCVD_CLK_RSTNf;
   8107     soc_field_t l1_rcvd_freq_sel = L1_RCVD_FREQ_SELf;
   8108     soc_field_t l1_rcvd_port_sel = L1_RCVD_PORT_SELf;
   8109     
   8110     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8111         l1_rcvd_clk_rstn = L1_RCVD_CLK_BKUP_RSTNf;
   8112         l1_rcvd_freq_sel = L1_RCVD_BKUP_FREQ_SELf;
   8113         l1_rcvd_port_sel = L1_RCVD_BKUP_PORT_SELf;
   8114     }
   8115     
   8116     if(!IS_CL_PORT(unit, lport))
   8117         return BCM_E_PARAM;
   8118 
   8119     if (!BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   8120         !BCM_TIME_MV2_PHY_PORT_VALID(phy_port)) {
   8121         return BCM_E_PARAM;
   8122     }
   8123 
   8124     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   8125         NULL, &phy_port));
   8126 
   8127     port_sel = phy_port - 1;
   8128 
   8129     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   8130 
   8131     /* TOP_MISC_CONTROL_2 */
   8132     SOC_IF_ERROR_RETURN
   8133         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8134                                 l1_rcvd_clk_rstn, 0));
   8135 
   8136     /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   8137     SOC_IF_ERROR_RETURN
   8138         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8139                                 l1_rcvd_freq_sel, 0));
   8140 
   8141     /* Set TSCF SDM divisors */
   8142     /* Set SDM stage 1 mode to bypass */
   8143 
   8144     sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   8145                (divisor->stage0_sdm_frac & 0xff));
   8146 
   8147     config.stg0_mode = divisor->stage0_mode;
   8148     config.stg1_mode = 0x0;
   8149     config.sdm_val = sdm_val;
   8150     if (!SOC_PORT_VALID(unit,lport))
   8151     {
   8152         return BCM_E_PARAM;
   8153     }
   8154     SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_set(unit, lport, &config));
   8155 
   8156     /* serdes port configuration */
   8157     SOC_IF_ERROR_RETURN
   8158         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8159                                 REG_PORT_ANY, l1_rcvd_port_sel, port_sel));
   8160 
   8161     /* TOP_MISC_CONTROL_2 */
   8162     SOC_IF_ERROR_RETURN
   8163         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8164                                 l1_rcvd_clk_rstn, 1));
   8165     return BCM_E_NONE;
   8166 }
   8167 
   8168 /*
   8169  * Function:
   8170  *      _bcm_esw_time_maverick2_synce_clock_get
   8171  * Purpose:
   8172  *      Get current setting of syncE clock divisor
   8173  * Parameters:
   8174  *      unit    - (IN)  Unit number.
   8175         divisor - (OUT) Divisor setting
   8176  * Returns:
   8177  *      BCM_E_xxx
   8178  * Notes: This function takes care of maverick2 only
   8179  */
   8180 STATIC int
   8181 _bcm_esw_time_maverick2_synce_clock_get(int unit,
   8182                               bcm_time_synce_clock_src_type_t clk_src,
   8183                               bcm_time_synce_divisor_setting_t *divisor)
   8184 {
   8185     uint32 val, rval;
   8186     int lport;
   8187     uint32 sdm_val;
   8188     uint32 phy_port;
   8189 
   8190     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8191     soc_field_t l1_rcvd_port_sel = L1_RCVD_PORT_SELf;
   8192 
   8193     portmod_port_synce_clk_ctrl_t config;
   8194     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   8195     
   8196     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8197         l1_rcvd_port_sel = L1_RCVD_BKUP_PORT_SELf;
   8198     }
   8199 
   8200     /* input source port */
   8201     SOC_IF_ERROR_RETURN( READ_TOP_MISC_CONTROL_2r(unit, &rval));
   8202 
   8203     val = soc_reg_field_get(unit, synce_ctrl_2, rval, l1_rcvd_port_sel);
   8204 
   8205     phy_port = val + 1;
   8206     _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   8207     divisor->input_src = bcmTimeSynceInputSourceTypePort;
   8208     divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   8209 
   8210     /* READ the SDM divisors from TSC */
   8211     lport = divisor->index;
   8212     if (!SOC_PORT_VALID(unit,lport))
   8213     {
   8214         return BCM_E_PARAM;
   8215     }
   8216 
   8217     SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_get(unit, lport, &config));
   8218     /* stage0_mode */
   8219     divisor->stage0_mode = config.stg0_mode;
   8220     sdm_val = config.sdm_val;
   8221     /* stage0_whole */
   8222     divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   8223     /* stage0_frac */
   8224     divisor->stage0_sdm_frac = sdm_val & 0xff ;
   8225     /* stage1_div  */
   8226     divisor->stage1_div = config.stg1_mode;         
   8227     return BCM_E_NONE;
   8228 }
   8229 
   8230 /*
   8231  * Function:
   8232  *      _bcm_esw_time_maverick2_synce_clock_set
   8233  * Purpose:
   8234  *      Set syncE divisor setting
   8235  * Parameters:
   8236  *      unit      - (IN) Unit number.
   8237  *      clk_src   - (IN) clock source type (Primary, Secondary)
   8238  *      input_src - (IN) input source type (PORT, PLL)
   8239  *      index     - (IN) if input_src is PORT, specify logical port number 0..105
   8240  *                       if input_src is PLL, specify PLL index 0..3
   8241  *      divisor   - (IN) divisor setting.
   8242  * Returns:
   8243  *      BCM_E_xxx
   8244  * Notes: This function only configures for maverick2 
   8245  */
   8246 STATIC int
   8247 _bcm_esw_time_maverick2_synce_clock_set(int unit,
   8248                               bcm_time_synce_clock_src_type_t clk_src,
   8249                               bcm_time_synce_divisor_setting_t *divisor)
   8250 {
   8251     int rv;
   8252 
   8253     switch(divisor->input_src) {
   8254     case bcmTimeSynceInputSourceTypePort:
   8255         rv = _bcm_esw_time_maverick2_synce_clock_set_by_port(unit, clk_src, divisor);
   8256         break;
   8257     default:
   8258         rv = BCM_E_PARAM;
   8259         break;
   8260     }
   8261     return rv;
   8262 }
   8263 
   8264 #endif /* defined(BCM_MAVERICK2_SUPPORT) */
   8265 
   8266 #if defined(BCM_HELIX5_SUPPORT)
   8267 #define BCM_TIME_HX5_PHY_PORT_VALID(x) ((x) >= 1 && (x) <= 76) /* Section 9.2, HX5 top spec */
   8268 
   8269 STATIC int
   8270 _bcm_esw_time_hx5_synce_L1_rcvd_clk_port_get(int phy_port)
   8271 {
   8272     if (phy_port >=1 && phy_port <= 4) {
   8273         return (phy_port - 1);
   8274     }
   8275     else if (phy_port >= 17 && phy_port <=20) {
   8276         return (phy_port - 12 - 1);
   8277     }
   8278     else if (phy_port >= 33 && phy_port <=36) {
   8279         return (phy_port - 24 - 1);
   8280     }
   8281     else if (phy_port >= 49 && phy_port <=76) {
   8282         return (phy_port - 36 - 1);
   8283     }
   8284     else {
   8285         return BCM_E_PARAM;
   8286     }
   8287 }
   8288 
   8289 STATIC int
   8290 _bcm_esw_time_hx5_phy_port_get(int port_sel)
   8291 {
   8292     if (port_sel < 4) {
   8293         return (port_sel + 1);
   8294     }
   8295     else if (port_sel < 8) {
   8296         return (port_sel + 1 + 12);
   8297     }
   8298     else if (port_sel < 12) {
   8299         return (port_sel + 1 + 24);
   8300     }
   8301     else if (port_sel < 40){
   8302         return (port_sel + 1 + 36);
   8303     }
   8304     else {
   8305         return BCM_E_PARAM;
   8306     }
   8307 }
   8308 
   8309 STATIC int
   8310 _bcm_esw_time_hx5_synce_clock_set_by_port(int unit,
   8311                                bcm_time_synce_clock_src_type_t clk_src,
   8312                                bcm_time_synce_divisor_setting_t *divisor)
   8313 {   
   8314     /* Assumes input index is logical port number */
   8315     int lport = divisor->index;
   8316     int phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   8317     int port_sel;
   8318     uint16 sdm_val;
   8319     portmod_port_synce_clk_ctrl_t config;
   8320     
   8321     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8322     soc_field_t l1_rcvd_clk_rstn = L1_RCVD_CLK_RSTNf;
   8323     soc_field_t l1_rcvd_freq_sel = L1_RCVD_FREQ_SELf;
   8324     soc_field_t l1_rcvd_port_sel = L1_RCVD_PORT_SELf;
   8325     
   8326     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8327         l1_rcvd_clk_rstn = L1_RCVD_CLK_BKUP_RSTNf;
   8328         l1_rcvd_freq_sel = L1_RCVD_BKUP_FREQ_SELf;
   8329         l1_rcvd_port_sel = L1_RCVD_BKUP_PORT_SELf;
   8330     }
   8331     
   8332     if (!BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   8333         !BCM_TIME_HX5_PHY_PORT_VALID(phy_port)) {
   8334         return BCM_E_PARAM;
   8335     }
   8336 
   8337     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   8338         NULL, &phy_port));
   8339 
   8340     
   8341     port_sel = _bcm_esw_time_hx5_synce_L1_rcvd_clk_port_get(phy_port);
   8342 
   8343     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   8344 
   8345     /* TOP_MISC_CONTROL_2 */
   8346     SOC_IF_ERROR_RETURN
   8347         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8348                                 l1_rcvd_clk_rstn, 0));
   8349 
   8350     /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   8351     SOC_IF_ERROR_RETURN
   8352         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8353                                 l1_rcvd_freq_sel, 0));
   8354 
   8355     /* Set TSCF SDM divisors */
   8356     /* Set SDM stage 1 mode to bypass */
   8357 
   8358     sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   8359                (divisor->stage0_sdm_frac & 0xff));
   8360 
   8361     config.stg0_mode = divisor->stage0_mode;
   8362     config.stg1_mode = 0x0;
   8363     config.sdm_val = sdm_val;
   8364     if (!SOC_PORT_VALID(unit,lport))
   8365     {
   8366         return BCM_E_PARAM;
   8367     }
   8368     SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_set(unit, lport, &config));
   8369 
   8370     /* serdes port configuration */
   8371     SOC_IF_ERROR_RETURN
   8372         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8373                                 REG_PORT_ANY, l1_rcvd_port_sel, port_sel));
   8374 
   8375     /* TOP_MISC_CONTROL_2 */
   8376     SOC_IF_ERROR_RETURN
   8377         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8378                                 l1_rcvd_clk_rstn, 1));
   8379     return BCM_E_NONE;
   8380 }
   8381 
   8382 #define BCM_TIME_HX5_PLL_VALID(x) ((x) < 2)
   8383 STATIC int
   8384 _bcm_esw_time_hx5_synce_clock_set_by_pll(int unit,
   8385                                bcm_time_synce_clock_src_type_t clk_src,
   8386                                bcm_time_synce_divisor_setting_t *divisor)
   8387 {
   8388     uint32 pll_index = divisor->index;
   8389     int port_sel;
   8390 
   8391     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8392     soc_field_t l1_rcvd_clk_rstn = L1_RCVD_CLK_RSTNf;
   8393     soc_field_t l1_rcvd_freq_sel = L1_RCVD_FREQ_SELf;
   8394     soc_field_t l1_rcvd_port_sel = L1_RCVD_PORT_SELf;
   8395     
   8396     if (!BCM_TIME_HX5_PLL_VALID(pll_index) ||
   8397         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src)) {
   8398         return BCM_E_PARAM;
   8399     }
   8400 
   8401     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8402         l1_rcvd_clk_rstn = L1_RCVD_CLK_BKUP_RSTNf;
   8403         l1_rcvd_freq_sel = L1_RCVD_BKUP_FREQ_SELf;
   8404         l1_rcvd_port_sel = L1_RCVD_BKUP_PORT_SELf;
   8405     }
   8406 
   8407     /* TOP_MISC_CONTROL */
   8408     SOC_IF_ERROR_RETURN
   8409         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8410                                 l1_rcvd_clk_rstn, 0));
   8411 
   8412     /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   8413     SOC_IF_ERROR_RETURN
   8414         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8415                                         l1_rcvd_freq_sel, 0));
   8416     port_sel = pll_index + 40;
   8417     /* TOP_MISC_CONTROL_2  - set pll port sel */
   8418     SOC_IF_ERROR_RETURN
   8419         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8420                         REG_PORT_ANY, l1_rcvd_port_sel, port_sel));
   8421 
   8422     /* TOP_MISC_CONTROL */
   8423     SOC_IF_ERROR_RETURN
   8424         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8425                                 l1_rcvd_clk_rstn, 1));
   8426 
   8427     return BCM_E_NONE;
   8428 }
   8429 
   8430 /*
   8431  * Function:
   8432  *      _bcm_esw_time_hx5_synce_clock_get
   8433  * Purpose:
   8434  *      Get current setting of syncE clock divisor
   8435  * Parameters:
   8436  *      unit    - (IN)  Unit number.
   8437         divisor - (OUT) Divisor setting
   8438  * Returns:
   8439  *      BCM_E_xxx
   8440  * Notes: This function takes care of helix5 only
   8441  */
   8442 STATIC int
   8443 _bcm_esw_time_hx5_synce_clock_get(int unit,
   8444                               bcm_time_synce_clock_src_type_t clk_src,
   8445                               bcm_time_synce_divisor_setting_t *divisor)
   8446 {
   8447     uint32 val, rval;
   8448     int lport;
   8449     uint32 sdm_val;
   8450     uint32 phy_port;
   8451 
   8452     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8453     soc_field_t l1_rcvd_port_sel = L1_RCVD_PORT_SELf;
   8454 
   8455     portmod_port_synce_clk_ctrl_t config;
   8456     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   8457     
   8458     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8459         l1_rcvd_port_sel = L1_RCVD_BKUP_PORT_SELf;
   8460     }
   8461 
   8462     /* input source port */
   8463     SOC_IF_ERROR_RETURN( READ_TOP_MISC_CONTROL_2r(unit, &rval));
   8464 
   8465     val = soc_reg_field_get(unit, synce_ctrl_2, rval, l1_rcvd_port_sel);
   8466 
   8467     if (val < 40) {
   8468         
   8469         phy_port = _bcm_esw_time_hx5_phy_port_get(val);
   8470         _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   8471         divisor->input_src = bcmTimeSynceInputSourceTypePort;
   8472         divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   8473     } else {
   8474         divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   8475         divisor->index = val - 40;
   8476     }
   8477 
   8478     if (divisor->input_src == bcmTimeSynceInputSourceTypePort) {
   8479         /* READ the SDM divisors from TSC */
   8480         lport = divisor->index;
   8481         if (!SOC_PORT_VALID(unit,lport))
   8482         {
   8483             return BCM_E_PARAM;
   8484         }
   8485 
   8486         SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_get(unit, lport, &config));
   8487         /* stage0_mode */
   8488         divisor->stage0_mode = config.stg0_mode;
   8489         sdm_val = config.sdm_val;
   8490         /* stage0_whole */
   8491         divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   8492         /* stage0_frac */
   8493         divisor->stage0_sdm_frac = sdm_val & 0xff ;
   8494         /* stage1_div  */
   8495         divisor->stage1_div = config.stg1_mode;
   8496    }
   8497     return BCM_E_NONE;
   8498 }
   8499 
   8500 /*
   8501  * Function:
   8502  *      _bcm_esw_time_hx5_synce_clock_set
   8503  * Purpose:
   8504  *      Set syncE divisor setting
   8505  * Parameters:
   8506  *      unit      - (IN) Unit number.
   8507  *      clk_src   - (IN) clock source type (Primary, Secondary)
   8508  *      input_src - (IN) input source type (PORT, PLL)
   8509  *      index     - (IN) if input_src is PORT, specify logical port number 0..105
   8510  *                       if input_src is PLL, specify PLL index 0..3
   8511  *      divisor   - (IN) divisor setting.
   8512  * Returns:
   8513  *      BCM_E_xxx
   8514  * Notes: This function only configures for helix5 
   8515  */
   8516 STATIC int
   8517 _bcm_esw_time_hx5_synce_clock_set(int unit,
   8518                               bcm_time_synce_clock_src_type_t clk_src,
   8519                               bcm_time_synce_divisor_setting_t *divisor)
   8520 {
   8521     int rv;
   8522 
   8523     switch(divisor->input_src) {
   8524     case bcmTimeSynceInputSourceTypePort:
   8525         rv = _bcm_esw_time_hx5_synce_clock_set_by_port(unit, clk_src, divisor);
   8526         break;
   8527     default:
   8528         rv = _bcm_esw_time_hx5_synce_clock_set_by_pll(unit, clk_src, divisor);
   8529         break;
   8530     }
   8531     return rv;
   8532 }
   8533 
   8534 #endif /* defined(BCM_HELIX5_SUPPORT) */
   8535 
   8536 #if defined(BCM_GREYHOUND2_SUPPORT)
   8537 #define BCM_TIME_GH2_PHY_PORT_VALID(x) ((x) >= 2 && (x) <= 89) /* Section 7.1.3, GH2 top design spec */
   8538 
   8539 STATIC int
   8540 _bcm_esw_time_gh2_synce_clock_set_by_port(int unit,
   8541                                bcm_time_synce_clock_src_type_t clk_src,
   8542                                bcm_time_synce_divisor_setting_t *divisor)
   8543 {
   8544     /* Assumes input index is logical port number */
   8545     int lport = divisor->index;
   8546     int phy_port;
   8547     int port_sel;
   8548     uint16 sdm_val;
   8549     
   8550     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8551     soc_field_t l1_rcvd_port_sel = L1_RCVD_PRI_CLK_PORT_SELf;
   8552     soc_field_t l1_rcvd_lnksts_sel = L1_RCVD_PRI_LNKSTS_PORT_SELf;
   8553 
   8554     soc_reg_t l1_rcvd_clk_ctrl = TOP_L1_RCVD_CLK_CONTROLr;
   8555     soc_field_t l1_rcvd_clk_rstn = L1_RCVD_CLK_RSTNf;
   8556 
   8557     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8558         l1_rcvd_port_sel = L1_RCVD_BKUP_CLK_PORT_SELf;
   8559         l1_rcvd_clk_rstn = L1_RCVD_CLK_BKUP_RSTNf;
   8560         l1_rcvd_lnksts_sel = L1_RCVD_BKUP_LNKSTS_PORT_SELf;
   8561     }
   8562 
   8563     if (!SOC_PORT_VALID(unit,lport))
   8564     {
   8565         return BCM_E_PARAM;
   8566     }
   8567     phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   8568 
   8569     if (!BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   8570         !BCM_TIME_GH2_PHY_PORT_VALID(phy_port)) {
   8571         return BCM_E_PARAM;
   8572     }
   8573 
   8574     /* lane adjust for eagle and falcon */
   8575     if (phy_port >= 58) {
   8576         BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   8577             NULL, &phy_port));
   8578     }
   8579 
   8580     /* Section 7.1.3, table 19, GH2 top design spec */
   8581     if (phy_port > 1 && phy_port < 26) {  /* Viper */
   8582         port_sel = phy_port + 6;
   8583     } else if (phy_port >= 58) { /*Eagle and Falcon */
   8584         port_sel = phy_port - 18;
   8585     } else {
   8586         return BCM_E_PARAM;
   8587     }
   8588 
   8589     if (phy_port >= 58) { /*Eagle and Falcon */
   8590         /* Set TSCF SDM divisors */
   8591         /* Set SDM stage 1 mode to bypass */
   8592 
   8593         sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   8594                    (divisor->stage0_sdm_frac & 0xff));
   8595 
   8596         SOC_IF_ERROR_RETURN(soc_phyctrl_synce_clock_set(unit, divisor->index, divisor->stage0_mode, 0, sdm_val));
   8597     }
   8598     /* serdes port configuration */
   8599     SOC_IF_ERROR_RETURN
   8600         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8601                                 REG_PORT_ANY, l1_rcvd_port_sel, port_sel));
   8602     SOC_IF_ERROR_RETURN
   8603         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8604                                 REG_PORT_ANY, l1_rcvd_lnksts_sel, port_sel));
   8605 
   8606     SOC_IF_ERROR_RETURN
   8607         (soc_reg_field32_modify(unit, l1_rcvd_clk_ctrl, REG_PORT_ANY,
   8608                                 l1_rcvd_clk_rstn, 1));
   8609     return BCM_E_NONE;
   8610 }
   8611 
   8612 #define BCM_TIME_GH2_PLL_VALID(x) ((x) < 2)
   8613 STATIC int
   8614 _bcm_esw_time_gh2_synce_clock_set_by_pll(int unit,
   8615                                bcm_time_synce_clock_src_type_t clk_src,
   8616                                bcm_time_synce_divisor_setting_t *divisor)
   8617 {
   8618     return BCM_E_PARAM;
   8619 #if 0
   8620     
   8621 
   8622     uint32 pll_index = divisor->index;
   8623     int port_sel;
   8624 
   8625     if (!BCM_TIME_GH2_PLL_VALID(pll_index) ||
   8626         !BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src)) {
   8627         return BCM_E_PARAM;
   8628     }
   8629 
   8630     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8631     soc_field_t l1_rcvd_port_sel = L1_RCVD_PRI_CLK_PORT_SELf;
   8632 
   8633     soc_reg_t l1_rcvd_clk_ctrl = TOP_L1_RCVD_CLK_CONTROLr;
   8634     soc_field_t l1_rcvd_clk_rstn = L1_RCVD_CLK_RSTNf;
   8635     soc_field_t l1_rcvd_freq_sel = L1_RCVD_FREQ_SELf;
   8636     
   8637     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8638         l1_rcvd_port_sel = L1_RCVD_BKUP_CLK_PORT_SELf;
   8639         l1_rcvd_clk_rstn = L1_RCVD_CLK_BKUP_RSTNf;
   8640         l1_rcvd_freq_sel = L1_RCVD_BKUP_FREQ_SELf;
   8641     }
   8642 
   8643     /* TOP_MISC_CONTROL */
   8644     SOC_IF_ERROR_RETURN
   8645         (soc_reg_field32_modify(unit, l1_rcvd_clk_ctrl, REG_PORT_ANY,
   8646                                 l1_rcvd_clk_rstn, 0));
   8647 
   8648     /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   8649     SOC_IF_ERROR_RETURN
   8650         (soc_reg_field32_modify(unit, l1_rcvd_clk_ctrl, REG_PORT_ANY,
   8651                                         l1_rcvd_freq_sel, 0));
   8652     port_sel = pll_index;
   8653     /* TOP_MISC_CONTROL_2  - set pll port sel */
   8654     SOC_IF_ERROR_RETURN
   8655         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8656                         REG_PORT_ANY, l1_rcvd_port_sel, port_sel));
   8657 
   8658     /* TOP_MISC_CONTROL */
   8659     SOC_IF_ERROR_RETURN
   8660         (soc_reg_field32_modify(unit, l1_rcvd_clk_ctrl, REG_PORT_ANY,
   8661                                 l1_rcvd_clk_rstn, 1));
   8662 
   8663     return BCM_E_NONE;
   8664 #endif
   8665 }
   8666 
   8667 STATIC int
   8668 _bcm_esw_time_gh2_synce_clock_get(int unit,
   8669                               bcm_time_synce_clock_src_type_t clk_src,
   8670                               bcm_time_synce_divisor_setting_t *divisor)
   8671 {
   8672     uint32 val, rval;
   8673     int lport;
   8674     uint32 sdm_val;
   8675     uint32 phy_port;
   8676     uint32 mode0, mode1;
   8677 
   8678     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8679     soc_field_t l1_rcvd_port_sel = L1_RCVD_PRI_CLK_PORT_SELf;
   8680 
   8681     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8682         l1_rcvd_port_sel = L1_RCVD_BKUP_CLK_PORT_SELf;
   8683     }
   8684 
   8685     /* input source port */
   8686     SOC_IF_ERROR_RETURN( READ_TOP_MISC_CONTROL_2r(unit, &rval));
   8687 
   8688     val = soc_reg_field_get(unit, synce_ctrl_2, rval, l1_rcvd_port_sel);
   8689 
   8690     if (val >= 8 && val <= 31) { /* viper */
   8691         phy_port = val - 6;
   8692     } else if (val >= 40) { /*Eagle or Falcon */
   8693         phy_port = val + 18;
   8694         _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   8695     }
   8696 
   8697     divisor->input_src = bcmTimeSynceInputSourceTypePort;
   8698     divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   8699 
   8700     if (divisor->input_src == bcmTimeSynceInputSourceTypePort) {
   8701         /* READ the SDM divisors from TSC */
   8702         lport = divisor->index;
   8703         if (!SOC_PORT_VALID(unit,lport)) {
   8704             return BCM_E_PARAM;
   8705         }
   8706         if (phy_port >= 58) {
   8707             SOC_IF_ERROR_RETURN(soc_phyctrl_synce_clock_get(unit, divisor->index, &mode0, &mode1, &sdm_val));
   8708             /* stage0_whole */
   8709             divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   8710             /* stage0_frac */
   8711             divisor->stage0_sdm_frac = sdm_val & 0xff ;
   8712             /* stage0_mode */
   8713             divisor->stage0_mode = mode0;
   8714             /* stage1_div  */
   8715             divisor->stage1_div = mode1;
   8716         }
   8717     }
   8718     return BCM_E_NONE;
   8719 }
   8720 
   8721 STATIC int
   8722 _bcm_esw_time_gh2_synce_clock_set(int unit, 
   8723                               bcm_time_synce_clock_src_type_t clk_src,
   8724                               bcm_time_synce_divisor_setting_t *divisor)
   8725 {
   8726     int rv;
   8727 
   8728     switch(divisor->input_src) {
   8729     case bcmTimeSynceInputSourceTypePort:
   8730         rv = _bcm_esw_time_gh2_synce_clock_set_by_port(unit, clk_src, divisor);
   8731         break;
   8732     default:
   8733         rv = _bcm_esw_time_gh2_synce_clock_set_by_pll(unit, clk_src, divisor);
   8734         break;
   8735     }
   8736     return rv;
   8737 }
   8738 #endif /* defined(BCM_GREYHOUND2_SUPPORT) */
   8739 
   8740 #if defined(BCM_MONTEREY_SUPPORT)
   8741 #define BCM_TIME_MO_PHY_PORT_VALID(x) ((x) >= 1 && (x) <= 64) /* Section 7, MO top design spec */
   8742 
   8743 STATIC int
   8744 _bcm_esw_time_monterey_synce_clock_set_by_port(int unit,
   8745                                bcm_time_synce_clock_src_type_t clk_src,
   8746                                bcm_time_synce_divisor_setting_t *divisor)
   8747 {
   8748     /* Assumes input index is logical port number */
   8749     int lport = divisor->index;
   8750     int phy_port;
   8751     int port_sel;
   8752     uint16 sdm_val;
   8753     portmod_port_synce_clk_ctrl_t config;
   8754 
   8755     soc_reg_t synce_ctrl = TOP_MISC_CONTROLr;
   8756     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8757     soc_field_t l1_rcvd_clk_rstn = L1_RCVD_CLK_RSTNf;
   8758     soc_field_t l1_rcvd_freq_sel_2 = L1_RCVD_FREQ_SELf;
   8759     soc_field_t l1_rcvd_port_sel_2 = L1_CLK_RECOVERY_PRI_PORT_SELf;
   8760     soc_field_t l1_rcvd_sw_ovwr_valid = L1_RCVD_SW_OVWR_VALIDf;
   8761     soc_field_t l1_rcvd_sw_ovwr_enable = L1_RCVD_SW_OVWR_ENf;
   8762 
   8763     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8764         l1_rcvd_clk_rstn = L1_RCVD_CLK_BKUP_RSTNf;
   8765         l1_rcvd_freq_sel_2 = L1_RCVD_BKUP_FREQ_SELf;
   8766         l1_rcvd_port_sel_2 = L1_CLK_RECOVERY_BKUP_PORT_SELf;
   8767         l1_rcvd_sw_ovwr_valid = L1_RCVD_SW_OVWR_BKUP_VALIDf;
   8768     }
   8769 
   8770     if (!SOC_PORT_VALID(unit,lport)) {
   8771         return BCM_E_PARAM;
   8772     }
   8773     phy_port = SOC_INFO(unit).port_l2p_mapping[lport];
   8774 
   8775     if (!BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   8776         !BCM_TIME_MO_PHY_PORT_VALID(phy_port)) {
   8777         return BCM_E_PARAM;
   8778     }
   8779 
   8780     BCM_IF_ERROR_RETURN(_bcm_esw_time_synce_phy_port_lane_adjust(unit, phy_port,
   8781         NULL, &phy_port));
   8782 
   8783     port_sel = phy_port - 1;
   8784 
   8785     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   8786 
   8787     /* TOP_MISC_CONTROL_2 */
   8788     SOC_IF_ERROR_RETURN
   8789         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   8790                                 l1_rcvd_clk_rstn, 0));
   8791 
   8792     /* TOP_MISC_CONTROL_2  - post divisors set to 0 */
   8793     SOC_IF_ERROR_RETURN
   8794         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8795                                 l1_rcvd_freq_sel_2, 1));
   8796 
   8797     /* Set SDM stage 1 mode to bypass */
   8798     sdm_val = ((divisor->stage0_sdm_whole & 0xff) << 8 |
   8799                (divisor->stage0_sdm_frac & 0xff));
   8800 
   8801     config.stg0_mode = divisor->stage0_mode;
   8802     config.stg1_mode = 0x0;
   8803     config.sdm_val = sdm_val;
   8804     SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_set(unit, lport, &config));
   8805 
   8806     /* serdes port configuration */
   8807     SOC_IF_ERROR_RETURN
   8808         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8809                                 REG_PORT_ANY, l1_rcvd_port_sel_2, port_sel));
   8810 
   8811     SOC_IF_ERROR_RETURN
   8812         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   8813                                     l1_rcvd_sw_ovwr_valid, 1));
   8814     SOC_IF_ERROR_RETURN
   8815         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   8816                                      l1_rcvd_sw_ovwr_enable, 1 ));
   8817     /* TOP_MISC_CONTROL_2 */
   8818     SOC_IF_ERROR_RETURN
   8819         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   8820                                 l1_rcvd_clk_rstn, 1));
   8821     return BCM_E_NONE;
   8822 }
   8823 
   8824 #define BCM_TIME_MO_PLL_VALID(x) ((x) < 4)
   8825 STATIC int
   8826 _bcm_esw_time_monterey_synce_clock_set_by_pll(int unit,
   8827                                bcm_time_synce_clock_src_type_t clk_src,
   8828                                bcm_time_synce_divisor_setting_t *divisor)
   8829 {
   8830     uint32 pll_index = divisor->index;
   8831     int port_sel;
   8832 
   8833     soc_reg_t synce_ctrl = TOP_MISC_CONTROLr;
   8834     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8835 
   8836     soc_field_t l1_rcvd_clk_rstn = L1_RCVD_CLK_RSTNf;
   8837     soc_field_t l1_rcvd_freq_sel_2 = L1_RCVD_FREQ_SELf;
   8838     soc_field_t l1_rcvd_port_sel_2 = L1_CLK_RECOVERY_PRI_PORT_SELf;
   8839     soc_field_t xg_rcvd_pri_sel_2 = XG_RCVD_PRI_SELf;
   8840     soc_field_t l1_rcvd_sw_ovwr_valid = L1_RCVD_SW_OVWR_VALIDf;
   8841     soc_field_t l1_rcvd_sw_ovwr_enable = L1_RCVD_SW_OVWR_ENf;
   8842 
   8843     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8844         l1_rcvd_clk_rstn = L1_RCVD_CLK_BKUP_RSTNf;
   8845         l1_rcvd_freq_sel_2 = L1_RCVD_BKUP_FREQ_SELf;
   8846         l1_rcvd_port_sel_2 = L1_CLK_RECOVERY_BKUP_PORT_SELf;
   8847         xg_rcvd_pri_sel_2 = XG_RCVD_BKUP_SELf;
   8848         l1_rcvd_sw_ovwr_valid = L1_RCVD_SW_OVWR_BKUP_VALIDf;
   8849     }
   8850 
   8851     if (!BCM_TIME_SYNCE_CLK_SRC_VALID(clk_src) ||
   8852         !BCM_TIME_MO_PLL_VALID(pll_index)) {
   8853         return BCM_E_PARAM;
   8854     }
   8855 
   8856     port_sel = pll_index + 64;
   8857 
   8858     /* TOP_MISC_CONTROL_2 */
   8859     SOC_IF_ERROR_RETURN
   8860         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   8861                                 l1_rcvd_clk_rstn, 0));
   8862 
   8863     /* TOP_MISC_CONTROL_2  - post divisors set to 1 */
   8864     SOC_IF_ERROR_RETURN
   8865         (soc_reg_field32_modify(unit, synce_ctrl_2, REG_PORT_ANY,
   8866                                 l1_rcvd_freq_sel_2, 1));
   8867 
   8868     /* pll index-mux configuration */
   8869     SOC_IF_ERROR_RETURN
   8870         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8871                                 REG_PORT_ANY, l1_rcvd_port_sel_2, port_sel));
   8872     SOC_IF_ERROR_RETURN
   8873         (soc_reg_field32_modify(unit, synce_ctrl_2,
   8874                                 REG_PORT_ANY, xg_rcvd_pri_sel_2, pll_index+1));
   8875     /* EGR_L1_CLK_RECOVERY_CTRL */
   8876     SOC_IF_ERROR_RETURN
   8877         (soc_reg_field32_modify(unit, EGR_L1_CLK_RECOVERY_CTRLr,
   8878                                 REG_PORT_ANY, PRI_PORT_SELf, 0));
   8879 
   8880     SOC_IF_ERROR_RETURN
   8881         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   8882                                     l1_rcvd_sw_ovwr_valid, 1));
   8883     SOC_IF_ERROR_RETURN
   8884         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   8885                                      l1_rcvd_sw_ovwr_enable, 1 ));
   8886 
   8887     /* TOP_MISC_CONTROL_2 */
   8888     SOC_IF_ERROR_RETURN
   8889         (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   8890                                 l1_rcvd_clk_rstn, 1));
   8891 
   8892     return BCM_E_NONE;
   8893 }
   8894 /*
   8895  * Function:
   8896  *      _bcm_esw_time_monterey_synce_clock_get
   8897  * Purpose:
   8898  *      Get current setting of syncE clock divisor
   8899  * Parameters:
   8900  *      unit    - (IN)  Unit number.
   8901         divisor - (OUT) Divisor setting
   8902  * Returns:
   8903  *      BCM_E_xxx
   8904  * Notes: This function takes care of monterey only
   8905  */
   8906 STATIC int
   8907 _bcm_esw_time_monterey_synce_clock_get(int unit,
   8908                               bcm_time_synce_clock_src_type_t clk_src,
   8909                               bcm_time_synce_divisor_setting_t *divisor)
   8910 {
   8911     uint32 val, val2, rval;
   8912     int lport;
   8913     uint32 sdm_val;
   8914     uint32 phy_port;
   8915     portmod_port_synce_clk_ctrl_t config;
   8916 
   8917     soc_reg_t synce_ctrl_2 = TOP_MISC_CONTROL_2r;
   8918     soc_field_t l1_rcvd_port_sel_2 = L1_CLK_RECOVERY_PRI_PORT_SELf;
   8919     soc_field_t xg_rcvd_pri_sel_2 = XG_RCVD_PRI_SELf;
   8920 
   8921     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   8922 
   8923     if (clk_src == bcmTimeSynceClockSourceSecondary) {
   8924         l1_rcvd_port_sel_2 = L1_CLK_RECOVERY_BKUP_PORT_SELf;
   8925     }
   8926 
   8927     /* input source port */
   8928     SOC_IF_ERROR_RETURN( READ_TOP_MISC_CONTROL_2r(unit, &rval));
   8929 
   8930     val = soc_reg_field_get(unit, synce_ctrl_2, rval, l1_rcvd_port_sel_2);
   8931     val2 = soc_reg_field_get(unit, synce_ctrl_2, rval, xg_rcvd_pri_sel_2);
   8932 
   8933     if (val2 == 0) {
   8934         if (val < 64) {
   8935             phy_port = val + 1;
   8936             _bcm_esw_time_synce_phy_port_get(unit, phy_port, &phy_port);
   8937             divisor->input_src = bcmTimeSynceInputSourceTypePort;
   8938             divisor->index = SOC_INFO(unit).port_p2l_mapping[phy_port];
   8939 
   8940             lport = divisor->index;
   8941             if (!SOC_PORT_VALID(unit,lport)) {
   8942                 return BCM_E_PARAM;
   8943             }
   8944 
   8945             /* READ the SDM divisors from TSC */
   8946             SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_get(unit, lport, &config));
   8947             /* stage0_mode */
   8948             divisor->stage0_mode = config.stg0_mode;
   8949             sdm_val = config.sdm_val;
   8950             /* stage0_whole */
   8951             divisor->stage0_sdm_whole  = ((sdm_val & 0xff00) >> 8);
   8952             /* stage0_frac */
   8953             divisor->stage0_sdm_frac = sdm_val & 0xff;
   8954             /* stage1_div  */
   8955             divisor->stage1_div = config.stg1_mode;
   8956         } else {
   8957             return BCM_E_FAIL;
   8958         }
   8959     } else {
   8960         divisor->input_src = bcmTimeSynceInputSourceTypePLL;
   8961         divisor->index = val2 - 1;
   8962     }
   8963     return BCM_E_NONE;
   8964 }
   8965 
   8966 STATIC int
   8967 _bcm_esw_time_monterey_synce_clock_set(int unit,
   8968                               bcm_time_synce_clock_src_type_t clk_src,
   8969                               bcm_time_synce_divisor_setting_t *divisor)
   8970 {
   8971     int rv;
   8972 
   8973     switch(divisor->input_src) {
   8974     case bcmTimeSynceInputSourceTypePort:
   8975         rv = _bcm_esw_time_monterey_synce_clock_set_by_port(unit, clk_src, divisor);
   8976         break;
   8977     case bcmTimeSynceInputSourceTypePLL:
   8978         rv = _bcm_esw_time_monterey_synce_clock_set_by_pll(unit, clk_src, divisor);
   8979         break;
   8980     default:
   8981         return BCM_E_PARAM;
   8982     }
   8983     return rv;
   8984 }
   8985 
   8986 #endif /*defined(BCM_MONTEREY_SUPPORT)*/
   8987 /*
   8988  * Function:
   8989  *      bcm_esw_time_synce_clock_get
   8990  * Purpose:
   8991  *      Get current setting of syncE clock divisor
   8992  * Parameters:
   8993  *      unit    - (IN)  Unit number.
   8994  *      clk_src - (IN) clock source type (Primary, Secondary)
   8995  *      divisor - (OUT) Divisor setting
   8996  * Returns:
   8997  *      BCM_E_xxx
   8998  * Notes:
   8999  */
   9000 int
   9001 bcm_esw_time_synce_clock_get(int unit,
   9002                              bcm_time_synce_clock_src_type_t clk_src,
   9003                              bcm_time_synce_divisor_setting_t *divisor)
   9004 {
   9005     int rv = BCM_E_UNAVAIL;
   9006 
   9007     if (soc_feature(unit, soc_feature_time_synce_divisor_setting)) {
   9008 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9009         if (SOC_IS_TD2P_TT2P(unit) && !SOC_IS_TOMAHAWKX(unit) && !SOC_IS_APACHE(unit)) {
   9010             rv = _bcm_esw_time_td2p_synce_clock_get(unit, clk_src, divisor);
   9011         }
   9012 #endif
   9013 
   9014 #ifdef BCM_HELIX4_SUPPORT
   9015         if (SOC_IS_HELIX4(unit)) {
   9016             rv = _bcm_esw_time_hx4_synce_clock_get(unit, clk_src, divisor);
   9017         }
   9018 #endif
   9019 
   9020 #ifdef BCM_GREYHOUND_SUPPORT
   9021         if (SOC_IS_GREYHOUND(unit)) {
   9022             rv = _bcm_esw_time_gh_synce_clock_get(unit, clk_src, divisor);
   9023         }
   9024 #endif
   9025 
   9026     }
   9027 
   9028 #ifdef BCM_KATANA_SUPPORT
   9029     if (SOC_IS_KATANA(unit)) {
   9030       rv = _bcm_esw_time_katana_synce_clock_get(unit, clk_src, divisor);
   9031     }
   9032 #endif
   9033 
   9034 #ifdef BCM_TOMAHAWK_SUPPORT
   9035     if (SOC_IS_TOMAHAWKX(unit)) {
   9036         rv = _bcm_esw_time_tomahawkx_synce_clock_get(unit, clk_src, divisor);
   9037     }
   9038 #endif
   9039 
   9040 #ifdef  BCM_METROLITE_SUPPORT
   9041     if (SOC_IS_METROLITE(unit)) {
   9042       rv = _bcm_esw_time_metrolite_synce_clock_get(unit, clk_src, divisor);
   9043     }
   9044 #endif
   9045 
   9046 #ifdef  BCM_TRIDENT3_SUPPORT
   9047     if (SOC_IS_TRIDENT3(unit)) {
   9048       rv = _bcm_esw_time_trident3_synce_clock_get(unit, clk_src, divisor);
   9049     }
   9050 #endif
   9051 
   9052 #ifdef BCM_APACHE_SUPPORT
   9053     if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
   9054         rv = _bcm_esw_time_apachex_synce_clock_get(unit, clk_src, divisor);
   9055     }
   9056 #endif
   9057 
   9058 #ifdef  BCM_MAVERICK2_SUPPORT
   9059     if (SOC_IS_MAVERICK2(unit)) {
   9060         rv = _bcm_esw_time_maverick2_synce_clock_get(unit, clk_src, divisor);
   9061     }
   9062 #endif
   9063 
   9064 #ifdef BCM_HELIX5_SUPPORT
   9065     if (SOC_IS_HELIX5(unit)) {
   9066         rv = _bcm_esw_time_hx5_synce_clock_get(unit, clk_src, divisor);
   9067     }
   9068 #endif
   9069 
   9070 #ifdef BCM_GREYHOUND2_SUPPORT
   9071     if (SOC_IS_GREYHOUND2(unit)) {
   9072         rv = _bcm_esw_time_gh2_synce_clock_get(unit, clk_src, divisor);
   9073     }
   9074 #endif
   9075 
   9076 #ifdef BCM_MONTEREY_SUPPORT
   9077     if (SOC_IS_MONTEREY(unit)) {
   9078         rv = _bcm_esw_time_monterey_synce_clock_get(unit, clk_src, divisor);
   9079     }
   9080 #endif
   9081     return rv;
   9082 }
   9083 
   9084 /*
   9085  * Function:
   9086  *      bcm_esw_time_synce_clock_set
   9087  * Purpose:
   9088  *      Set syncE divisor setting
   9089  * Parameters:
   9090  *      unit      - (IN) Unit number.
   9091  *      clk_src   - (IN) clock source type (Primary, Secondary)
   9092  *      divisor   - (IN) divisor setting.
   9093  * Returns:
   9094  *      BCM_E_xxx
   9095  * Notes:
   9096  */
   9097 int
   9098 bcm_esw_time_synce_clock_set(int unit,
   9099                              bcm_time_synce_clock_src_type_t clk_src,
   9100                              bcm_time_synce_divisor_setting_t *divisor)
   9101 {
   9102     int rv = BCM_E_UNAVAIL;
   9103 
   9104     if (soc_feature(unit, soc_feature_time_synce_divisor_setting)) {
   9105 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9106         if (SOC_IS_TD2P_TT2P(unit) && !SOC_IS_TOMAHAWKX(unit) && !SOC_IS_APACHE(unit)) {
   9107             rv = _bcm_esw_time_td2p_synce_clock_set(unit, clk_src, divisor);
   9108         }
   9109 #endif
   9110 
   9111 #ifdef BCM_GREYHOUND_SUPPORT
   9112         if (SOC_IS_GREYHOUND(unit)) {
   9113             rv = _bcm_esw_time_gh_synce_clock_set(unit, clk_src, divisor);
   9114         }
   9115 #endif
   9116 
   9117 #ifdef BCM_HELIX4_SUPPORT
   9118         if (SOC_IS_HELIX4(unit)) {
   9119             rv = _bcm_esw_time_hx4_synce_clock_set(unit, clk_src, divisor);
   9120         }
   9121 #endif
   9122 
   9123     }
   9124 #ifdef  BCM_KATANA_SUPPORT
   9125     if (SOC_IS_KATANA(unit)) {
   9126       rv = _bcm_esw_time_katana_synce_clock_set(unit, clk_src, divisor);
   9127     }
   9128 #endif
   9129 
   9130 #ifdef BCM_TOMAHAWK_SUPPORT
   9131     if (SOC_IS_TOMAHAWKX(unit)) {
   9132       rv = _bcm_esw_time_tomahawkx_synce_clock_set_by_port(unit, clk_src, divisor);
   9133     }
   9134 #endif
   9135 
   9136 #ifdef  BCM_SABER2_SUPPORT
   9137     if (SOC_IS_SABER2(unit)) {
   9138       rv = _bcm_esw_time_saber2_synce_clock_set(unit, clk_src, divisor);
   9139     }
   9140 #endif
   9141 
   9142 #ifdef  BCM_METROLITE_SUPPORT
   9143     if (SOC_IS_METROLITE(unit)) {
   9144       rv = _bcm_esw_time_metrolite_synce_clock_set(unit, clk_src, divisor);
   9145     }
   9146 #endif
   9147 
   9148 #ifdef  BCM_TRIDENT3_SUPPORT
   9149     if (SOC_IS_TRIDENT3(unit)) {
   9150       rv = _bcm_esw_time_trident3_synce_clock_set(unit, clk_src, divisor);
   9151     }
   9152 #endif
   9153 
   9154 #ifdef BCM_APACHE_SUPPORT
   9155     if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
   9156         rv = _bcm_esw_time_apachex_synce_clock_set(unit, clk_src, divisor);
   9157     }
   9158 #endif /* BCM_APACHE_SUPPORT */
   9159 
   9160 #ifdef  BCM_MAVERICK2_SUPPORT
   9161     if (SOC_IS_MAVERICK2(unit)) {
   9162       rv = _bcm_esw_time_maverick2_synce_clock_set(unit, clk_src, divisor);
   9163     }
   9164 #endif
   9165 
   9166 #ifdef BCM_HELIX5_SUPPORT
   9167         if (SOC_IS_HELIX5(unit)) {
   9168             rv = _bcm_esw_time_hx5_synce_clock_set(unit, clk_src, divisor);
   9169         }
   9170 #endif
   9171 
   9172 #ifdef BCM_GREYHOUND2_SUPPORT
   9173     if (SOC_IS_GREYHOUND2(unit)) {
   9174         rv = _bcm_esw_time_gh2_synce_clock_set(unit, clk_src, divisor);
   9175     }
   9176 #endif
   9177 
   9178 #ifdef BCM_MONTEREY_SUPPORT
   9179     if (SOC_IS_MONTEREY(unit)) {
   9180       rv = _bcm_esw_time_monterey_synce_clock_set(unit, clk_src, divisor);
   9181     }
   9182 #endif
   9183 
   9184 #ifdef BCM_ESMC_EXTDPLL_SUPPORT
   9185     if (rv == BCM_E_NONE) {
   9186         rv = bcm_extdpll_esmc_select_port_set(unit, divisor->index, clk_src);
   9187         /* Unsquelch the CDR MUX output, if it was squelched earlier */
   9188         rv = _bcm_esw_time_synce_clock_source_squelch_set(unit, clk_src, 0);
   9189     }
   9190 #endif /* BCM_ESMC_EXTDPLL_SUPPORT */
   9191 
   9192     return rv;
   9193 }
   9194 
   9195 /*
   9196  * Function:
   9197  *      _bcm_esw_time_synce_clock_source_control_get
   9198  * Purpose:
   9199  *      Get syncE clock source control option
   9200  * Parameters:
   9201  *      unit    - (IN)  Unit number.
   9202  *      clk_src - (IN) clock source
   9203  *      squelch - (OUT) squelch value
   9204  * Returns:
   9205  *      BCM_E_xxx
   9206  * Notes:
   9207  */
   9208 STATIC int
   9209 _bcm_esw_time_synce_clock_source_squelch_get(int unit,
   9210                             bcm_time_synce_clock_src_type_t clk_src,
   9211                             int *squelch)
   9212 {
   9213     int rv = BCM_E_NONE;
   9214     uint32 regval;
   9215 
   9216     COMPILER_REFERENCE(regval);
   9217     COMPILER_REFERENCE(rv);
   9218 
   9219     if (!squelch) return rv;
   9220 #if defined(BCM_TOMAHAWK3_SUPPORT)
   9221     if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_TOMAHAWK(unit)) {
   9222         soc_reg_t synce_ctrl = TOP_SYNCE_CTRLr;
   9223         soc_field_t l1_rcvd_sw_ovwr_valid = L1_RCVD_SW_OVWR_VALIDf;
   9224         soc_field_t l1_rcvd_sw_ovwr_enable = L1_RCVD_SW_OVWR_ENf;
   9225 
   9226         if (SOC_IS_TOMAHAWK(unit)) {
   9227             synce_ctrl = TOP_MISC_CONTROLr;
   9228         }
   9229 
   9230         if (clk_src == bcmTimeSynceClockSourceSecondary) {
   9231             l1_rcvd_sw_ovwr_valid = L1_RCVD_SW_OVWR_BKUP_VALIDf;
   9232             l1_rcvd_sw_ovwr_enable = L1_RCVD_SW_OVWR_ENf;
   9233         }
   9234         soc_reg32_get(unit, synce_ctrl, REG_PORT_ANY, 0, &regval);
   9235 
   9236         /* check if software overwrite enabled or not */
   9237         if(soc_reg_field_get(unit, synce_ctrl, regval, l1_rcvd_sw_ovwr_enable)) {
   9238             /* check if we have squelch or supressed */
   9239             *squelch = soc_reg_field_get(unit, synce_ctrl, regval, l1_rcvd_sw_ovwr_valid) ? 0 : 1;
   9240         } else {
   9241             *squelch = 0;
   9242         }
   9243         return rv;
   9244     }
   9245 #endif
   9246 
   9247     switch(clk_src) {
   9248     case bcmTimeSynceClockSourcePrimary:
   9249 #if defined(BCM_SABER2_SUPPORT)
   9250         if (SOC_IS_SABER2(unit)) {
   9251             READ_TOP_MISC_CONTROL_1r(unit, &regval);
   9252             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, regval,
   9253                                             L1_RCVD_SW_OVWR_ENf);
   9254         }
   9255 #endif /* defined(BCM_SABER2_SUPPORT) */
   9256 
   9257 #if defined(BCM_METROLITE_SUPPORT)
   9258         if (SOC_IS_METROLITE(unit)) {
   9259             READ_TOP_MISC_CONTROL_1r(unit, &regval);
   9260             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, regval,
   9261                                             L1_RCVD_SW_OVWR_ENf);
   9262         }
   9263 #endif /* defined(BCM_METROLITE_SUPPORT) */
   9264 
   9265 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   9266         if (SOC_IS_TD2P_TT2P(unit)) {
   9267             READ_TOP_MISC_CONTROLr(unit, &regval);
   9268             *squelch = !soc_reg_field_get(unit, TOP_MISC_CONTROLr, regval,
   9269                                             L1_RCVD_CLK_RSTNf);
   9270         }
   9271 #endif
   9272 
   9273 #if defined(BCM_GREYHOUND_SUPPORT)
   9274         if (SOC_IS_GREYHOUND(unit)) {
   9275             READ_TOP_MISC_CONTROL_2r(unit, &regval);
   9276             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, regval,
   9277                                             L1_RCVD_SW_OVWR_ENf);
   9278         }
   9279 #endif /* defined(BCM_GREYHOUND_SUPPORT) */
   9280 
   9281 
   9282 #if defined(BCM_HELIX4_SUPPORT)
   9283         if (SOC_IS_HELIX4(unit)) {
   9284             READ_TOP_MISC_CONTROL_1r(unit, &regval);
   9285             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, regval,
   9286                                             L1_RCVD_SW_OVWR_ENf);
   9287         }
   9288 #endif /* defined(BCM_HELIX4_SUPPORT) */
   9289 
   9290 #if defined(BCM_TRIDENT3_SUPPORT)
   9291         if (SOC_IS_TRIDENT3(unit)) {
   9292             READ_TOP_MISC_CONTROL_2r(unit, &regval);
   9293             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, regval,
   9294                                             L1_RCVD_SW_OVWR_ENf);
   9295         }
   9296 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   9297 
   9298 #if defined(BCM_APACHE_SUPPORT)
   9299         if (SOC_IS_APACHE(unit)) { /* Apache and Monterey */
   9300             READ_TOP_MISC_CONTROLr(unit, &regval);
   9301             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROLr, regval,
   9302                                             L1_RCVD_SW_OVWR_ENf);
   9303         }
   9304 #endif /* defined(BCM_APACHE_SUPPORT) */
   9305 
   9306 
   9307 #if defined(BCM_TOMAHAWK2_SUPPORT)
   9308         if (SOC_IS_TOMAHAWK2(unit)) {
   9309             READ_TOP_MISC_CONTROLr(unit, &regval);
   9310             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROLr, regval,
   9311                                             L1_RCVD_SW_OVWR_ENf);
   9312         }
   9313 #endif /* defined(BCM_TOMAHAWK2_SUPPORT) */
   9314 
   9315 #if defined(BCM_MAVERICK2_SUPPORT)
   9316         if (SOC_IS_MAVERICK2(unit)) {
   9317             READ_TOP_MISC_CONTROL_2r(unit, &regval);
   9318             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, regval,
   9319                                             L1_RCVD_SW_OVWR_ENf);
   9320         }
   9321 #endif /* defined(BCM_MAVERICK2_SUPPORT) */
   9322 
   9323 #if defined(BCM_HELIX5_SUPPORT)
   9324         if (SOC_IS_HELIX5(unit)) {
   9325             READ_TOP_MISC_CONTROL_2r(unit, &regval);
   9326             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, regval,
   9327                                             L1_RCVD_SW_OVWR_ENf);
   9328         }
   9329 #endif /* defined(BCM_HELIX5_SUPPORT) */
   9330 
   9331 #if defined(BCM_GREYHOUND2_SUPPORT)
   9332     if (SOC_IS_GREYHOUND2(unit)) {
   9333         READ_TOP_L1_RCVD_CLK_CONTROLr(unit, &regval);
   9334         *squelch = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CONTROLr, regval,
   9335                                            L1_RCVD_SW_OVWR_ENf);
   9336     }
   9337 #endif /* defined(BCM_GREYHOUND2_SUPPORT) */
   9338         break;
   9339 
   9340     case bcmTimeSynceClockSourceSecondary:
   9341 #if defined(BCM_SABER2_SUPPORT)
   9342         if (SOC_IS_SABER2(unit)) {
   9343             READ_TOP_MISC_CONTROL_1r(unit, &regval);
   9344             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, regval,
   9345                                             L1_RCVD_SW_OVWR_ENf);
   9346         }
   9347 #endif /* defined(BCM_SABER2_SUPPORT) */
   9348 
   9349 #if defined(BCM_METROLITE_SUPPORT)
   9350         if (SOC_IS_METROLITE(unit)) {
   9351             READ_TOP_MISC_CONTROL_1r(unit, &regval);
   9352             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, regval,
   9353                                             L1_RCVD_SW_OVWR_ENf);
   9354         }
   9355 #endif /* defined(BCM_METROLITE_SUPPORT) */
   9356 
   9357 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   9358         if (SOC_IS_TD2P_TT2P(unit) && !SOC_IS_APACHE(unit)) {
   9359             READ_TOP_MISC_CONTROLr(unit, &regval);
   9360             *squelch = !soc_reg_field_get(unit, TOP_MISC_CONTROLr, regval,
   9361                                             L1_RCVD_CLK_BKUP_RSTNf);
   9362         }
   9363 #endif
   9364 
   9365 #if defined(BCM_GREYHOUND_SUPPORT)
   9366         if (SOC_IS_GREYHOUND(unit)) {
   9367             READ_TOP_MISC_CONTROL_2r(unit, &regval);
   9368             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, regval,
   9369                                             L1_RCVD_SW_OVWR_ENf);
   9370         }
   9371 #endif /* defined(BCM_HELIX4_SUPPORT) */
   9372 
   9373 #if defined(BCM_HELIX4_SUPPORT)
   9374         if (SOC_IS_HELIX4(unit)) {
   9375             READ_TOP_MISC_CONTROL_1r(unit, &regval);
   9376             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, regval,
   9377                                             L1_RCVD_SW_OVWR_ENf);
   9378         }
   9379 #endif /* defined(BCM_HELIX4_SUPPORT) */
   9380 
   9381 #if defined(BCM_TRIDENT3_SUPPORT)
   9382         if (SOC_IS_TRIDENT3(unit)) {
   9383             READ_TOP_MISC_CONTROL_2r(unit, &regval);
   9384             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, regval,
   9385                                             L1_RCVD_SW_OVWR_ENf);
   9386         }
   9387 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   9388 
   9389 #if defined(BCM_APACHE_SUPPORT)
   9390         if (SOC_IS_APACHE(unit)) {
   9391             READ_TOP_MISC_CONTROLr(unit, &regval);
   9392             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROLr, regval,
   9393                                             L1_RCVD_SW_OVWR_ENf);
   9394         }
   9395 #endif /* defined(BCM_APACHE_SUPPORT) */
   9396 
   9397 #if defined(BCM_TOMAHAWK2_SUPPORT)
   9398         if (SOC_IS_TOMAHAWK2(unit)) {
   9399             READ_TOP_MISC_CONTROLr(unit, &regval);
   9400             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROLr, regval,
   9401                                             L1_RCVD_SW_OVWR_ENf);
   9402         }
   9403 #endif /* defined(BCM_TOMAHAWK2_SUPPORT) */
   9404 
   9405 #if defined(BCM_MAVERICK2_SUPPORT)
   9406         if (SOC_IS_MAVERICK2(unit)) {
   9407             READ_TOP_MISC_CONTROL_2r(unit, &regval);
   9408             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, regval,
   9409                                             L1_RCVD_SW_OVWR_ENf);
   9410         }
   9411 #endif /* defined(BCM_MAVERICK2_SUPPORT) */
   9412 
   9413 #if defined(BCM_HELIX5_SUPPORT)
   9414         if (SOC_IS_HELIX5(unit)) {
   9415             READ_TOP_MISC_CONTROL_2r(unit, &regval);
   9416             *squelch = soc_reg_field_get(unit, TOP_MISC_CONTROL_2r, regval,
   9417                                             L1_RCVD_SW_OVWR_ENf);
   9418         }
   9419 #endif /* defined(BCM_HELIX5_SUPPORT) */
   9420 
   9421 #if defined(BCM_GREYHOUND2_SUPPORT)
   9422     if (SOC_IS_GREYHOUND2(unit)) {
   9423         READ_TOP_L1_RCVD_CLK_CONTROLr(unit, &regval);
   9424         *squelch = soc_reg_field_get(unit, TOP_L1_RCVD_CLK_CONTROLr, regval,
   9425                                            L1_RCVD_SW_OVWR_ENf);
   9426     }
   9427 #endif /* defined(BCM_GREYHOUND2_SUPPORT) */
   9428         break;
   9429     default:
   9430         return BCM_E_PARAM;
   9431     }
   9432 
   9433     return rv;
   9434 }
   9435 
   9436 
   9437 /*
   9438  * Function:
   9439  *      _bcm_esw_time_synce_clock_source_frequency_get
   9440  * Purpose:
   9441  *      Get syncE clock source squelch option
   9442  * Parameters:
   9443  *      unit      - (IN) Unit number.
   9444  *      clk_src   - (IN) clock source type (Primary, Secondary)
   9445  *      frequency - (OUT) synce clock source frequency.
   9446  * Returns:
   9447  *      BCM_E_xxx
   9448  * Notes:
   9449  */
   9450 STATIC int
   9451 _bcm_esw_time_synce_clock_source_frequency_get(int unit,
   9452                              bcm_time_synce_clock_source_config_t *clk_src_config,
   9453                              int *frequency)
   9454 
   9455 {
   9456     int rv = BCM_E_NONE;
   9457     bcm_time_synce_divisor_setting_t div_out;
   9458     bcm_time_synce_divisor_setting_t_init(&div_out);
   9459 
   9460     COMPILER_REFERENCE(rv);
   9461     rv = bcm_esw_time_synce_clock_get(unit, clk_src_config->clk_src, &div_out);
   9462     if (div_out.input_src == bcmTimeSynceInputSourceTypePort) {
   9463         clk_src_config->port = div_out.index;
   9464     } else {
   9465         clk_src_config->pll_index = div_out.index;
   9466     }
   9467 
   9468     if (IS_MANAGEMENT_PORT(unit,  clk_src_config->port) && clk_src_config->input_src == bcmTimeSynceInputSourceTypePort) {
   9469         return BCM_E_PARAM;
   9470     }
   9471 
   9472 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   9473     if(SOC_IS_TD2P_TT2P(unit) && !SOC_IS_TOMAHAWK(unit) && !SOC_IS_APACHE(unit)) {
   9474         if(div_out.stage0_mode == bcmTimeSynceModeSDMFracDiv && div_out.stage0_sdm_whole == 20 &&
   9475             div_out.stage0_sdm_frac  == 160) {
   9476                *frequency = bcmTimeSyncE25MHz;
   9477         } else if  (div_out.stage0_mode == bcmTimeSynceModeBypass && div_out.stage1_div == bcmTimeSynceStage1Div11) {
   9478             if (div_out.stage0_sdm_whole == 23) {
   9479                 *frequency = bcmTimeSyncE23MHz;
   9480             } else if (div_out.stage0_sdm_whole == 28) {
   9481                 *frequency = bcmTimeSyncE28MHz;
   9482             } else if (div_out.stage0_sdm_whole == 46) {
   9483                 *frequency = bcmTimeSyncE46MHz;
   9484             } else {
   9485                 return BCM_E_PARAM;
   9486             }
   9487        } else {
   9488            return BCM_E_PARAM;
   9489        }
   9490     }
   9491 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   9492 
   9493 #if defined(BCM_GREYHOUND_SUPPORT)
   9494     if (SOC_IS_GREYHOUND(unit)) {
   9495          /* Helix4 :
   9496                     stage0_mode=0 -> pass-through mode
   9497                     stage0_mode=1 -> Div_by_5(25MHz) mode
   9498                     stage0_mode=2 -> Div_by_10(31.25MHz) mode
   9499                     stage0_mode=3 -> Div_by_2(156.25MHz) mode
   9500                 */
   9501          *frequency = div_out.stage0_mode;
   9502     }
   9503 #endif /* BCM_GREYHOUND_SUPPORT */
   9504 
   9505 #if defined(BCM_HELIX4_SUPPORT)
   9506     if (SOC_IS_HELIX4(unit)) {
   9507          /* Helix4 :
   9508                     stage0_mode=0 -> pass-through mode
   9509                     stage0_mode=1 -> Div_by_5(25MHz) mode
   9510                     stage0_mode=2 -> Div_by_10(31.25MHz) mode
   9511                     stage0_mode=3 -> Div_by_2(156.25MHz) mode
   9512                 */
   9513          *frequency = div_out.stage0_mode;
   9514     }
   9515 #endif /* BCM_HELIX4_SUPPORT */
   9516 
   9517 #if defined(BCM_KATANA_SUPPORT)
   9518     if (SOC_IS_KATANA(unit)) {
   9519       /* Katana */
   9520       *frequency = bcmTimeSyncE125MHz;
   9521     }
   9522 #endif /* BCM_KATANA_SUPPORT */
   9523 
   9524 #if defined(BCM_GREYHOUND2_SUPPORT)
   9525     if (SOC_IS_GREYHOUND2(unit)) {
   9526       /* GH2 */
   9527         if (div_out.input_src == bcmTimeSynceInputSourceTypePort) {
   9528             phy_ctrl_t *pc;
   9529             phymod_dispatch_type_t dispatch_type = phymodDispatchTypeInvalid;
   9530     
   9531             pc = INT_PHY_SW_STATE(unit, clk_src_config->port);
   9532             if (pc == NULL) {
   9533                 return BCM_E_FAIL;
   9534             }
   9535             dispatch_type = pc->phymod_ctrl.phy[0]->pm_phy.type;
   9536 
   9537             if ((div_out.stage0_mode == bcmTimeSynceModeSDMFracDiv) &&
   9538                 (div_out.stage1_div == bcmTimeSynceStage1Div1)) {
   9539                 if (dispatch_type == phymodDispatchTypeTsce_dpll || dispatch_type == phymodDispatchTypeTscf ) {
   9540                     *frequency = bcmTimeSyncE25MHz;
   9541                 }
   9542             } else {
   9543                 if (dispatch_type == phymodDispatchTypeViper) {
   9544                     *frequency = bcmTimeSyncE125MHz;
   9545                 }
   9546             }
   9547         } else {
   9548             return BCM_E_PARAM;
   9549         }
   9550     }
   9551 #endif /* BCM_GREYHOUND2_SUPPORT */
   9552 
   9553 #if defined(BCM_SABER2_SUPPORT)
   9554     if (SOC_IS_SABER2(unit)) {
   9555       rv = _bcm_esw_time_saber2_synce_clock_get(unit, clk_src_config->clk_src, &div_out);
   9556       if (rv == BCM_E_NONE) {
   9557           if (div_out.input_src == bcmTimeSynceInputSourceTypePort) {
   9558               clk_src_config->port = div_out.index;
   9559               if (div_out.stage0_mode == bcmTimeSynceModeBypass)
   9560                 *frequency = bcmTimeSyncE125MHz;
   9561               else
   9562                 *frequency = bcmTimeSyncE25MHz;
   9563           } else {
   9564               clk_src_config->pll_index = div_out.index;
   9565               *frequency = bcmTimeSyncE125MHz;
   9566           }
   9567       }
   9568     }
   9569 #endif /* BCM_SABER2_SUPPORT */
   9570 
   9571 #if defined(BCM_METROLITE_SUPPORT)
   9572     if (SOC_IS_METROLITE(unit)) {
   9573       rv = _bcm_esw_time_metrolite_synce_clock_get(unit, clk_src_config->clk_src, &div_out);
   9574       if (rv == BCM_E_NONE) {
   9575           if (div_out.input_src == bcmTimeSynceInputSourceTypePort) {
   9576               clk_src_config->port = div_out.index;
   9577               if (div_out.stage0_mode == bcmTimeSynceModeBypass)
   9578                 *frequency = bcmTimeSyncE125MHz;
   9579               else
   9580                 *frequency = bcmTimeSyncE25MHz;
   9581           } else {
   9582               clk_src_config->pll_index = div_out.index;
   9583               *frequency = bcmTimeSyncE125MHz;
   9584           }
   9585       }
   9586     }
   9587 #endif /* BCM_METROLITE_SUPPORT */
   9588 
   9589 #if defined(BCM_HELIX5_SUPPORT)
   9590     if (SOC_IS_HELIX5(unit)) {
   9591       /* HELIX5 */
   9592         if (div_out.input_src == bcmTimeSynceInputSourceTypePLL) {
   9593             *frequency = bcmTimeSyncE125MHz;
   9594             clk_src_config->input_src = div_out.input_src;
   9595         }
   9596     }
   9597 #endif /* BCM_HELIX5_SUPPORT*/
   9598 
   9599 #if defined(BCM_MONTEREY_SUPPORT)
   9600     if (SOC_IS_MONTEREY(unit)) {
   9601         if (div_out.input_src == bcmTimeSynceInputSourceTypePLL) {
   9602             *frequency = bcmTimeSyncE125MHz;
   9603             clk_src_config->pll_index = div_out.index;
   9604             clk_src_config->input_src = div_out.input_src;
   9605         }
   9606     }
   9607 #endif /* BCM_MONTEREY_SUPPORT */
   9608 
   9609 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_APACHE_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT) || defined(BCM_HELIX5_SUPPORT) || \
   9610     defined(BCM_MONTEREY_SUPPORT)
   9611 
   9612     if (div_out.input_src == bcmTimeSynceInputSourceTypePort) {
   9613 
   9614     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit) || SOC_IS_APACHE(unit) || SOC_IS_MAVERICK2(unit) || SOC_IS_HELIX5(unit) || SOC_IS_MONTEREY(unit)) {
   9615         /* tomahawk  & TD3 */
   9616         if ((div_out.stage0_mode == bcmTimeSynceModeSDMFracDiv) &&
   9617                 (div_out.stage1_div == bcmTimeSynceStage1Div1)) {
   9618 
   9619             int port_speed = 0; /* speed specified in mbps*/
   9620             uint32 sdm_divisor = 0;
   9621             phymod_dispatch_type_t dispatch_type = phymodDispatchTypeInvalid;
   9622 
   9623             BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, clk_src_config->port, &port_speed));
   9624             sdm_divisor = (div_out.stage0_sdm_whole <<8) | div_out.stage0_sdm_frac;
   9625 
   9626             dispatch_type = _bcm_time_synce_tsc_phymod_dispatch_type_get(unit, clk_src_config->port);
   9627 
   9628             if ((dispatch_type == phymodDispatchTypeTsce) || 
   9629                 (dispatch_type == phymodDispatchTypeTsce16)) {
   9630                 if (!IS_HG_PORT(unit, clk_src_config->port)) {
   9631                     /* regular port */
   9632                     if (sdm_divisor == 0x14a0) {
   9633                         *frequency = bcmTimeSyncE25MHz;
   9634                     }
   9635                 } else {
   9636                     /* hi gig port */
   9637                     if (sdm_divisor == 0x15e0) {
   9638                         *frequency = bcmTimeSyncE25MHz;
   9639                     }
   9640                 }
   9641             } else if (dispatch_type == phymodDispatchTypeTscf) {
   9642                 switch (port_speed) {
   9643                     case 100:
   9644                         /* 1G ports  - VCO 25.78125 */
   9645                         if (sdm_divisor == 0x19c8) {
   9646                             *frequency = bcmTimeSyncE25MHz;
   9647                         } else {
   9648                             return BCM_E_PARAM;
   9649                         }
   9650                         break;
   9651                     case 10000:
   9652                     case 40000:
   9653                         /* 10G or 40G ports -  VCO 20.625 */
   9654                         if (sdm_divisor == 0xa50) {
   9655                             *frequency = bcmTimeSyncE25MHz;
   9656                         } else {
   9657                             return BCM_E_PARAM;
   9658                         }
   9659                         break;
   9660                      case 25000:
   9661                      case 100000:
   9662                         /* 100G ports - VCO 25.78125*/
   9663                         if (sdm_divisor == 0x19c8) {
   9664                             *frequency = bcmTimeSyncE25MHz;
   9665                         } else {
   9666                             return BCM_E_PARAM;
   9667                         }
   9668                         break;
   9669                      case 11000:
   9670                         /* 11G HG ports -VCO 21.875 */
   9671                         if (sdm_divisor == 0xaf0) {
   9672                             *frequency = bcmTimeSyncE25MHz;
   9673                         } else {
   9674                             return BCM_E_PARAM;
   9675                         }
   9676                         break;
   9677                       case 106000:
   9678                         /* 106G HG ports -VCO 21.875 */
   9679                         if (sdm_divisor == 0x1b58) {
   9680                             *frequency = bcmTimeSyncE25MHz;
   9681                         } else {
   9682                             return BCM_E_PARAM;
   9683                         }
   9684                         break;
   9685                       default:
   9686                         return BCM_E_PARAM;
   9687                         break;
   9688                 }
   9689             } else if (dispatch_type == phymodDispatchTypeTscf16) {
   9690                 switch (port_speed) {
   9691                     case 100:
   9692                         /* 1G ports  - VCO 25.78125 */
   9693                         if (sdm_divisor == 0x19c8) {
   9694                             *frequency = bcmTimeSyncE25MHz;
   9695                         } else {
   9696                             return BCM_E_PARAM;
   9697                         }
   9698                         break;
   9699                     case 10000:
   9700                     case 40000:
   9701                         /* 10G or 40G ports -  VCO 20.625 */
   9702                         if (sdm_divisor == 0xa50) {
   9703                             *frequency = bcmTimeSyncE25MHz;
   9704                         } else {
   9705                             return BCM_E_PARAM;
   9706                         }
   9707                         break;
   9708                      case 25000:
   9709                      case 100000:
   9710                         /* 100G ports - VCO 25.78125*/
   9711                         if (sdm_divisor == 0x19c8) {
   9712                             *frequency = bcmTimeSyncE25MHz;
   9713                         } else {
   9714                             return BCM_E_PARAM;
   9715                         }
   9716                         break;
   9717                      case 11000:
   9718                         /* 11G HG ports -VCO 21.875 */
   9719                         if (sdm_divisor == 0xaf0) {
   9720                             *frequency = bcmTimeSyncE25MHz;
   9721                         } else {
   9722                             return BCM_E_PARAM;
   9723                         }
   9724                         break;
   9725                       case 106000:
   9726                         /* 106G HG ports -VCO 21.875 */
   9727                         if (sdm_divisor == 0x1b58) {
   9728                             *frequency = bcmTimeSyncE25MHz;
   9729                         } else {
   9730                             return BCM_E_PARAM;
   9731                         }
   9732                         break;
   9733                       default:
   9734                         return BCM_E_PARAM;
   9735                         break;
   9736                 }
   9737             } else if (dispatch_type == phymodDispatchTypeTscbh) {
   9738 #ifdef PORTMOD_SUPPORT
   9739                 if (SOC_USE_PORTCTRL(unit)) {
   9740                     portmod_port_synce_clk_ctrl_t config;
   9741                     portmod_port_synce_clk_ctrl_t_init(unit, &config);
   9742 
   9743                     SOC_IF_ERROR_RETURN(portmod_port_synce_clk_ctrl_get(unit, clk_src_config->port, &config));
   9744                     if ((config.stg0_mode == 0x2) && (config.stg1_mode == 0x0)) {
   9745                         *frequency = bcmTimeSyncE25MHz;
   9746                     }
   9747                 }
   9748 #endif
   9749             } else if (dispatch_type == phymodDispatchTypeTsce_dpll) {
   9750                 switch (port_speed) {
   9751                     case 1000:
   9752                     case 10000:
   9753                     case 20000:
   9754                     case 40000:
   9755                         if (sdm_divisor == 0x14a0) {
   9756                             *frequency = bcmTimeSyncE25MHz;
   9757                         } else if (sdm_divisor == 0x4200) {
   9758                             *frequency = bcmTimeSyncE7MHz;
   9759                         } else if (sdm_divisor == 0x2940) {
   9760                             *frequency = bcmTimeSyncE12MHz;
   9761                         } else if (sdm_divisor == 0x1080) {
   9762                             *frequency = bcmTimeSyncE31MHz;
   9763                         } else if (sdm_divisor == 0xDC0) {
   9764                             *frequency = bcmTimeSyncE37MHz;
   9765                         } else {
   9766                             return BCM_E_PARAM;
   9767                         }
   9768                     break;
   9769                     default:
   9770                         return BCM_E_PARAM;
   9771                 }
   9772             } else if (dispatch_type == phymodDispatchTypeTscf_gen3) {
   9773                 switch (port_speed) {
   9774                     case 1000:
   9775                         if (sdm_divisor == 0x14A0) {
   9776                             *frequency = bcmTimeSyncE25MHz;
   9777                         } else if (sdm_divisor == 0x4200) {
   9778                             *frequency = bcmTimeSyncE7MHz;
   9779                         } else if (sdm_divisor == 0x2940) {
   9780                             *frequency = bcmTimeSyncE12MHz;
   9781                         } else if (sdm_divisor == 0x1080) {
   9782                             *frequency = bcmTimeSyncE31MHz;
   9783                         } else if (sdm_divisor == 0xDC0) {
   9784                             *frequency = bcmTimeSyncE37MHz;
   9785                         } else {
   9786                             return BCM_E_PARAM;
   9787                         }
   9788                     break;
   9789                     case 10000:
   9790                     case 20000:
   9791                     case 40000:
   9792                         if (sdm_divisor == 0xA50) {
   9793                             *frequency = bcmTimeSyncE25MHz;
   9794                         } else if (sdm_divisor == 0x2100) {
   9795                             *frequency = bcmTimeSyncE7MHz;
   9796                         } else if (sdm_divisor == 0x14A0) {
   9797                             *frequency = bcmTimeSyncE12MHz;
   9798                         } else if (sdm_divisor == 0x840) {
   9799                             *frequency = bcmTimeSyncE31MHz;
   9800                         } else if (sdm_divisor == 0x6E0) {
   9801                             *frequency = bcmTimeSyncE37MHz;
   9802                         } else {
   9803                             return BCM_E_PARAM;
   9804                         }
   9805                     break;
   9806                     case 25000:
   9807                     case 50000:
   9808                     case 100000:
   9809                         if (sdm_divisor == 0x19C8) {
   9810                             *frequency = bcmTimeSyncE25MHz;
   9811                         } else if (sdm_divisor == 0x5280) {
   9812                             *frequency = bcmTimeSyncE7MHz;
   9813                         } else if (sdm_divisor == 0x3390) {
   9814                             *frequency = bcmTimeSyncE12MHz;
   9815                         } else if (sdm_divisor == 0x14A0) {
   9816                             *frequency = bcmTimeSyncE31MHz;
   9817                         } else if (sdm_divisor == 0x1130) {
   9818                             *frequency = bcmTimeSyncE37MHz;
   9819                         } else {
   9820                             return BCM_E_PARAM;
   9821                         }
   9822                     break;
   9823                     default:
   9824                         cli_out("not supported port_speed:%d\n", (int)port_speed);
   9825                         return BCM_E_PARAM;
   9826                 }
   9827             }
   9828         } else {
   9829             return BCM_E_PARAM;
   9830         }
   9831     }
   9832     }
   9833 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
   9834 
   9835     return rv;
   9836 }
   9837 
   9838 /*
   9839  * Function:
   9840  *      bcm_esw_time_synce_clock_source_control_get
   9841  * Purpose:
   9842  *      Get syncE clock source control option
   9843  * Parameters:
   9844  *      unit    - (IN)  Unit number.
   9845  *      clk_src - (IN) clock source
   9846  *      vlaue - (OUT) control value
   9847  * Returns:
   9848  *      BCM_E_xxx
   9849  * Notes: New wrapper API to support synce operation
   9850  */
   9851 int
   9852 bcm_esw_time_synce_clock_source_control_get(int unit,
   9853                              bcm_time_synce_clock_source_config_t *clk_src_config,
   9854                              bcm_time_synce_clock_source_control_t control,
   9855                              int *value)
   9856 {
   9857     int rv = BCM_E_UNAVAIL;
   9858 
   9859     switch (control) {
   9860     case bcmTimeSynceClockSourceControlSquelch:
   9861         rv = _bcm_esw_time_synce_clock_source_squelch_get(unit, clk_src_config->clk_src, value);
   9862         break;
   9863     case bcmTimeSynceClockSourceControlFrequency:
   9864         rv = _bcm_esw_time_synce_clock_source_frequency_get(unit, clk_src_config, value);
   9865         break;
   9866     default:
   9867         return BCM_E_PARAM;
   9868     }
   9869 
   9870     return rv;
   9871 
   9872 }
   9873 
   9874 /*
   9875  * Function:
   9876  *      _bcm_esw_time_synce_clock_source_squelch_set
   9877  * Purpose:
   9878  *      Set syncE clock source squelch option
   9879  * Parameters:
   9880  *      unit      - (IN) Unit number.
   9881  *      clk_src   - (IN) clock source type (Primary, Secondary)
   9882  *      squelch   - (IN) synce clock source squelch setting 1 to enable , 0 to disable.
   9883  * Returns:
   9884  *      BCM_E_xxx
   9885  * Notes:
   9886  */
   9887 STATIC int
   9888 _bcm_esw_time_synce_clock_source_squelch_set(int unit,
   9889                              bcm_time_synce_clock_src_type_t clk_src,
   9890                              int squelch)
   9891 
   9892 {
   9893     int rv = BCM_E_NONE;
   9894 
   9895     COMPILER_REFERENCE(rv);
   9896 #if defined(BCM_TOMAHAWK3_SUPPORT)
   9897     if (SOC_IS_TOMAHAWK3(unit) || SOC_IS_TOMAHAWK(unit)) {
   9898         soc_reg_t synce_ctrl = TOP_SYNCE_CTRLr;
   9899         soc_field_t l1_rcvd_sw_ovwr_valid = L1_RCVD_SW_OVWR_VALIDf;
   9900         soc_field_t l1_rcvd_sw_ovwr_enable = L1_RCVD_SW_OVWR_ENf;
   9901 
   9902         if (SOC_IS_TOMAHAWK(unit)) {
   9903             synce_ctrl = TOP_MISC_CONTROLr;
   9904         }
   9905 
   9906         if (clk_src == bcmTimeSynceClockSourceSecondary) {
   9907             l1_rcvd_sw_ovwr_valid = L1_RCVD_SW_OVWR_BKUP_VALIDf;
   9908             l1_rcvd_sw_ovwr_enable = L1_RCVD_SW_OVWR_ENf;
   9909         }
   9910         SOC_IF_ERROR_RETURN
   9911             (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   9912                                     l1_rcvd_sw_ovwr_valid, ((squelch) ? 0 : 1)));
   9913         SOC_IF_ERROR_RETURN
   9914             (soc_reg_field32_modify(unit, synce_ctrl, REG_PORT_ANY,
   9915                                     l1_rcvd_sw_ovwr_enable, ((squelch) ? 1 : 0)));
   9916         return rv;
   9917     }
   9918 #endif
   9919 
   9920     switch(clk_src) {
   9921     case bcmTimeSynceClockSourcePrimary:
   9922 #if defined(BCM_TOMAHAWK2_SUPPORT)
   9923         if (SOC_IS_TOMAHAWK2(unit)) {
   9924             SOC_IF_ERROR_RETURN
   9925                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   9926                                        L1_RCVD_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
   9927             SOC_IF_ERROR_RETURN
   9928                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   9929                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
   9930         }
   9931 #endif /* defined(BCM_TOMAHAWK2_SUPPORT) */
   9932 
   9933 #if defined(BCM_SABER2_SUPPORT)
   9934         if (SOC_IS_SABER2(unit)) {
   9935             SOC_IF_ERROR_RETURN
   9936                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   9937                                         L1_RCVD_CLK0_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
   9938             SOC_IF_ERROR_RETURN
   9939                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   9940                                         L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
   9941         }
   9942 #endif /* defined(BCM_SABER2_SUPPORT) */
   9943 
   9944 #if defined(BCM_METROLITE_SUPPORT)
   9945         if (SOC_IS_METROLITE(unit)) {
   9946             SOC_IF_ERROR_RETURN
   9947                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   9948                                         L1_RCVD_CLK0_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
   9949             SOC_IF_ERROR_RETURN
   9950                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   9951                                         L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
   9952         }
   9953 #endif /* defined(BCM_METROLITE_SUPPORT) */
   9954 
   9955 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   9956         if (SOC_IS_TD2P_TT2P(unit)) {
   9957             SOC_IF_ERROR_RETURN
   9958                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   9959                                         L1_RCVD_CLK_RSTNf, ((squelch) ? 0 : 1)));
   9960         }
   9961 #endif
   9962 
   9963 #if defined(BCM_GREYHOUND_SUPPORT)
   9964         if (SOC_IS_GREYHOUND(unit) ) {
   9965             SOC_IF_ERROR_RETURN
   9966                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   9967                                        L1_RCVD_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
   9968             SOC_IF_ERROR_RETURN
   9969                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
   9970                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
   9971         }
   9972 #endif /* defined(BCM_GREYHOUND_SUPPORT) */
   9973 
   9974 #if defined(BCM_HELIX4_SUPPORT)
   9975         if (SOC_IS_HELIX4(unit) ) {
   9976             SOC_IF_ERROR_RETURN
   9977                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   9978                                        L1_RCVD_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
   9979             SOC_IF_ERROR_RETURN
   9980                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
   9981                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
   9982         }
   9983 #endif /* defined(BCM_HELIX4_SUPPORT) */
   9984 
   9985 #if defined(BCM_APACHE_SUPPORT)
   9986         if (SOC_IS_APACHE(unit)) { /* Both Apache and Monterey */
   9987             SOC_IF_ERROR_RETURN
   9988                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   9989                                        L1_RCVD_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
   9990             SOC_IF_ERROR_RETURN
   9991                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
   9992                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
   9993         }
   9994 #endif /* defined(BCM_APACHE_SUPPORT) */
   9995 
   9996 #if defined(BCM_TRIDENT3_SUPPORT)
   9997         if (SOC_IS_TRIDENT3(unit)) {
   9998             SOC_IF_ERROR_RETURN
   9999                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10000                                        L1_RCVD_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
  10001             SOC_IF_ERROR_RETURN
  10002                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10003                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10004         }
  10005 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
  10006 
  10007 #if defined(BCM_MAVERICK2_SUPPORT)
  10008         if (SOC_IS_MAVERICK2(unit)) {
  10009             SOC_IF_ERROR_RETURN
  10010                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10011                                        L1_RCVD_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
  10012             SOC_IF_ERROR_RETURN
  10013                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10014                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10015         }
  10016 #endif /* defined(BCM_MAVERICK2_SUPPORT) */
  10017 
  10018 #if defined(BCM_HELIX5_SUPPORT)
  10019         if (SOC_IS_HELIX5(unit)) {
  10020             SOC_IF_ERROR_RETURN
  10021                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10022                                        L1_RCVD_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
  10023             SOC_IF_ERROR_RETURN
  10024                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10025                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10026         }
  10027 #endif /* defined(BCM_HELIX5_SUPPORT) */
  10028 
  10029 #if defined(BCM_GREYHOUND2_SUPPORT)
  10030     if (SOC_IS_GREYHOUND2(unit)) {
  10031         SOC_IF_ERROR_RETURN
  10032             (soc_reg_field32_modify(unit, TOP_L1_RCVD_CLK_CONTROLr, REG_PORT_ANY,
  10033                                       L1_RCVD_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
  10034         SOC_IF_ERROR_RETURN
  10035             (soc_reg_field32_modify(unit, TOP_L1_RCVD_CLK_CONTROLr, REG_PORT_ANY,
  10036                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10037     }
  10038 #endif /* defined(BCM_GREYHOUND2_SUPPORT) */
  10039         break;
  10040 
  10041     case bcmTimeSynceClockSourceSecondary:
  10042 #if defined(BCM_TOMAHAWK2_SUPPORT)
  10043         if (SOC_IS_TOMAHAWK2(unit)) {
  10044             SOC_IF_ERROR_RETURN
  10045                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
  10046                                        L1_RCVD_SW_OVWR_BKUP_VALIDf, ((squelch) ? 0 : 1)));
  10047             SOC_IF_ERROR_RETURN
  10048                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
  10049                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10050         }
  10051 #endif /* defined(BCM_TOMAHAWK2_SUPPORT) */
  10052 
  10053 #if defined(BCM_SABER2_SUPPORT)
  10054         if (SOC_IS_SABER2(unit)) {
  10055             SOC_IF_ERROR_RETURN
  10056                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
  10057                                         L1_RCVD_CLK1_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
  10058             SOC_IF_ERROR_RETURN
  10059                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
  10060                                         L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1: 0)));
  10061         }
  10062 #endif /* defined(BCM_SABER2_SUPPORT) */
  10063 
  10064 #if defined(BCM_METROLITE_SUPPORT)
  10065         if (SOC_IS_METROLITE(unit)) {
  10066             SOC_IF_ERROR_RETURN
  10067                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
  10068                                         L1_RCVD_CLK1_SW_OVWR_VALIDf, ((squelch) ? 0 : 1)));
  10069             SOC_IF_ERROR_RETURN
  10070                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
  10071                                         L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1: 0)));
  10072         }
  10073 #endif /* defined(BCM_METROLITE_SUPPORT) */
  10074 
  10075 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  10076         if (SOC_IS_TD2P_TT2P(unit)) {
  10077             SOC_IF_ERROR_RETURN
  10078                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
  10079                                         L1_RCVD_CLK_BKUP_RSTNf, ((squelch) ? 0: 1)));
  10080         }
  10081 #endif
  10082 
  10083 #if defined(BCM_GREYHOUND_SUPPORT)
  10084         if (SOC_IS_GREYHOUND(unit) ) {
  10085             SOC_IF_ERROR_RETURN
  10086                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10087                                        L1_RCVD_SW_OVWR_BKUP_VALIDf, ((squelch) ? 0 : 1)));
  10088             SOC_IF_ERROR_RETURN
  10089                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10090                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10091         }
  10092 #endif /* defined(BCM_GREYHOUND_SUPPORT) */
  10093 
  10094 
  10095 #if defined(BCM_HELIX4_SUPPORT)
  10096         if (SOC_IS_HELIX4(unit)) {
  10097             SOC_IF_ERROR_RETURN
  10098                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
  10099                                         L1_RCVD_SW_OVWR_BKUP_VALIDf, ((squelch) ? 0 : 1)));
  10100             SOC_IF_ERROR_RETURN
  10101                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_1r, REG_PORT_ANY,
  10102                                         L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10103         }
  10104 #endif /* defined(BCM_HELIX4_SUPPORT) */
  10105 
  10106 #if defined(BCM_TRIDENT3_SUPPORT)
  10107         if (SOC_IS_TRIDENT3(unit)) {
  10108             SOC_IF_ERROR_RETURN
  10109                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10110                                        L1_RCVD_SW_OVWR_BKUP_VALIDf, ((squelch) ? 0 : 1)));
  10111             SOC_IF_ERROR_RETURN
  10112                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10113                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10114         }
  10115 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
  10116 
  10117 #if defined(BCM_APACHE_SUPPORT)
  10118         if (SOC_IS_APACHE(unit)) { /* Both Apache and Monterey */
  10119             SOC_IF_ERROR_RETURN
  10120                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
  10121                                         L1_RCVD_SW_OVWR_BKUP_VALIDf, ((squelch) ? 0 : 1)));
  10122             SOC_IF_ERROR_RETURN
  10123                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY,
  10124                                         L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10125         }
  10126 #endif /* defined(BCM_APACHE_SUPPORT) */
  10127 
  10128 #if defined(BCM_MAVERICK2_SUPPORT)
  10129         if (SOC_IS_MAVERICK2(unit)) {
  10130             SOC_IF_ERROR_RETURN
  10131                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10132                                        L1_RCVD_SW_OVWR_BKUP_VALIDf, ((squelch) ? 0 : 1)));
  10133             SOC_IF_ERROR_RETURN
  10134                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10135                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10136         }
  10137 #endif /* defined(BCM_MAVERICK2_SUPPORT) */
  10138 
  10139 #if defined(BCM_HELIX5_SUPPORT)
  10140         if (SOC_IS_HELIX5(unit)) {
  10141             SOC_IF_ERROR_RETURN
  10142                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10143                                        L1_RCVD_SW_OVWR_BKUP_VALIDf, ((squelch) ? 0 : 1)));
  10144             SOC_IF_ERROR_RETURN
  10145                 (soc_reg_field32_modify(unit, TOP_MISC_CONTROL_2r, REG_PORT_ANY,
  10146                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10147         }
  10148 #endif /* defined(BCM_HELIX5_SUPPORT) */
  10149 
  10150 #if defined(BCM_GREYHOUND2_SUPPORT)
  10151     if (SOC_IS_GREYHOUND2(unit)) {
  10152         SOC_IF_ERROR_RETURN
  10153             (soc_reg_field32_modify(unit, TOP_L1_RCVD_CLK_CONTROLr, REG_PORT_ANY,
  10154                                       L1_RCVD_SW_OVWR_BKUP_VALIDf, ((squelch) ? 0 : 1)));
  10155         SOC_IF_ERROR_RETURN
  10156             (soc_reg_field32_modify(unit, TOP_L1_RCVD_CLK_CONTROLr, REG_PORT_ANY,
  10157                                        L1_RCVD_SW_OVWR_ENf, ((squelch) ? 1 : 0)));
  10158     }
  10159 #endif /* defined(BCM_GREYHOUND2_SUPPORT) */
  10160         break;
  10161     default:
  10162         return BCM_E_PARAM;
  10163     }
  10164     return rv;
  10165 }
  10166 
  10167 /*
  10168  * Function:
  10169  *      _bcm_esw_time_synce_clock_source_frequency_set
  10170  * Purpose:
  10171  *      Set syncE clock source squelch option
  10172  * Parameters:
  10173  *      unit      - (IN) Unit number.
  10174  *      clk_src   - (IN) clock source type (Primary, Secondary)
  10175  *      frequency - (IN) synce clock source frequency.
  10176  * Returns:
  10177  *      BCM_E_xxx
  10178  * Notes:
  10179  */
  10180 STATIC int
  10181 _bcm_esw_time_synce_clock_source_frequency_set(int unit,
  10182                              bcm_time_synce_clock_source_config_t *clk_src_config,
  10183                              int frequency)
  10184 
  10185 {
  10186     int rv = BCM_E_NONE;
  10187     bcm_time_synce_divisor_setting_t div_in;
  10188     bcm_time_synce_divisor_setting_t_init(&div_in);
  10189     COMPILER_REFERENCE(rv);
  10190 
  10191     if (clk_src_config->input_src == bcmTimeSynceInputSourceTypePort) {
  10192         div_in.index = clk_src_config->port;
  10193     } else if(clk_src_config->input_src == bcmTimeSynceInputSourceTypePLL ) {
  10194         div_in.index = clk_src_config->pll_index;
  10195     } else {
  10196         return BCM_E_PARAM;
  10197     }
  10198 
  10199     if (IS_MANAGEMENT_PORT(unit,  clk_src_config->port) && clk_src_config->input_src == bcmTimeSynceInputSourceTypePort) {
  10200         return BCM_E_PARAM;
  10201     }
  10202  
  10203 
  10204 #if defined(BCM_HELIX5_SUPPORT)
  10205     /* port_gmii_mode_1/_17/_33 not supported */
  10206     if (SOC_IS_HELIX5(unit)) {
  10207         int phy_port = SOC_INFO(unit).port_l2p_mapping[clk_src_config->port];
  10208         if ((clk_src_config->input_src == bcmTimeSynceInputSourceTypePort) && (phy_port <= 48)) {
  10209             if (soc_property_phys_port_get(unit, 1, spn_PORT_GMII_MODE, 0)) {
  10210                 return BCM_E_CONFIG;
  10211             }
  10212             if (soc_property_phys_port_get(unit, 17, spn_PORT_GMII_MODE, 0)) {
  10213                 return BCM_E_CONFIG;
  10214             }
  10215             if (soc_property_phys_port_get(unit, 33, spn_PORT_GMII_MODE, 0)) {
  10216                 return BCM_E_CONFIG;
  10217             }
  10218         }
  10219     }
  10220 #endif /* defined(BCM_HELIX5_SUPPORT) */
  10221 
  10222     div_in.input_src = clk_src_config->input_src;
  10223 
  10224 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  10225     if(SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit) && !SOC_IS_APACHE(unit)) {
  10226         /*
  10227               *       output_freq = (rx_clk) * stage0_sdm * stage1_div
  10228               *       rx_clk      = (VCO/20)
  10229               *       stage0_sdm  = (stage0_sdm_whole) + (stage0_sdm_frac)/256
  10230               *       stage1_div  = 1
  10231               *       (0 <= stage0_sdm_whole <= 255,
  10232               *        0 <= stage0_sdm_frac  <= 255,
  10233               *        stage1_div is always locked to bypass in SDM mode. Div7,Div11 is not allowed.)
  10234               *
  10235               *       For example,
  10236               *           stage0_sdm_whole = 20
  10237               *           stage0_sdm_frac  = 160
  10238               *           stage0_sdm = 20 + 160/256 = 20.625
  10239               *       Port speed         |VCO        |VCO/20     |stage0  |stage1 |output freq(MHz)
  10240               *       10/40/100G         |10.3125    |515.625    |20.625  |1      |25
  10241               */
  10242 
  10243         switch(frequency) {
  10244             case bcmTimeSyncE23MHz:
  10245                 div_in.stage0_mode      = bcmTimeSynceModeBypass;
  10246                 div_in.stage0_sdm_whole = 23;
  10247                 div_in.stage1_div       = bcmTimeSynceStage1Div11;
  10248                 break;
  10249             case bcmTimeSyncE25MHz:
  10250                 div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10251                 div_in.stage0_sdm_whole = 20;
  10252                 div_in.stage0_sdm_frac  = 160;
  10253                 break;
  10254             case bcmTimeSyncE28MHz:
  10255                 div_in.stage0_mode      = bcmTimeSynceModeBypass;
  10256                 div_in.stage0_sdm_whole = 28;
  10257                 div_in.stage1_div       = bcmTimeSynceStage1Div11;
  10258                 break;
  10259             case bcmTimeSyncE46MHz:
  10260                 div_in.stage0_mode      = bcmTimeSynceModeBypass;
  10261                 div_in.stage0_sdm_whole = 46;
  10262                 div_in.stage1_div       = bcmTimeSynceStage1Div11;
  10263                 break;
  10264             default:
  10265                 return BCM_E_PARAM;
  10266        }
  10267     }
  10268 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  10269 
  10270 #ifdef BCM_GREYHOUND_SUPPORT
  10271     if (SOC_IS_GREYHOUND(unit)) {  /* GREYHOUND SyncE Freq Divisor*/
  10272         if(!BCM_TIME_GH_L1_FREQ_SEL_MODE(frequency)) {
  10273              return BCM_E_PARAM;
  10274          }
  10275         /* In Greyhound raw recovered clock from port will be based on below
  10276             pass-through mode             :: freq = 0(00b)
  10277             Div by 5mode(25MHz)         :: freq = 1(01b)
  10278             Div by 10mode(31.25MHz)   :: freq = 2(10b)
  10279             Div by 2mode(156.25MHz)   :: freq = 3(11b)
  10280            */
  10281         /* raw recovered clock div val  */
  10282         switch(frequency) {
  10283             case 0:/* pass-through mode */
  10284                 div_in.stage0_mode      = 0;
  10285                 break;
  10286             case 1: /* Div by 5mode(25MHz) */
  10287                 div_in.stage0_mode      = 1;
  10288                 break;
  10289             case 2: /* Div by 10mode(31.25MHz) */
  10290                 div_in.stage0_mode      = 2;
  10291                 break;
  10292             default: /*  Div by 2mode(156.25MHz)*/
  10293                 div_in.stage0_mode      = 3;
  10294        }
  10295     }
  10296 #endif /* BCM_GREYHOUND_SUPPORT */
  10297 
  10298 #ifdef BCM_HELIX4_SUPPORT
  10299     if (SOC_IS_HELIX4(unit)) {  /* HELIX4 SyncE Freq Divisor*/
  10300         if(!BCM_TIME_HX4_L1_FREQ_SEL_MODE(frequency)) {
  10301              return BCM_E_PARAM;
  10302          }
  10303         /* In Helix4 raw recovered clock from port will be based on below
  10304             pass-through mode             :: freq = 0(00b)
  10305             Div by 5mode(25MHz)         :: freq = 1(01b)
  10306             Div by 10mode(31.25MHz)   :: freq = 2(10b)
  10307             Div by 2mode(156.25MHz)   :: freq = 3(11b)
  10308            */
  10309         /* raw recovered clock div val  */
  10310         switch(frequency) {
  10311             case 0:/* pass-through mode */
  10312                 div_in.stage0_mode      = 0;
  10313                 break;
  10314             case 1: /* Div by 5mode(25MHz) */
  10315                 div_in.stage0_mode      = 1;
  10316                 break;
  10317             case 2: /* Div by 10mode(31.25MHz) */
  10318                 div_in.stage0_mode      = 2;
  10319                 break;
  10320             default: /*  Div by 2mode(156.25MHz)*/
  10321                 div_in.stage0_mode      = 3;
  10322        }
  10323     }
  10324 #endif /* BCM_HELIX4_SUPPORT */
  10325 
  10326 #if defined(BCM_KATANA_SUPPORT)
  10327     if (SOC_IS_KATANA(unit)) {
  10328         switch (frequency) {
  10329             case bcmTimeSyncE125MHz:
  10330                 /* KT do not have SDM */
  10331                 break;
  10332             default:
  10333                 return BCM_E_FAIL;
  10334                 break;
  10335         }
  10336     }
  10337 #endif /* defined(BCM_KATANA_SUPPORT) */
  10338 
  10339 #if defined(BCM_SABER2_SUPPORT)
  10340     if (SOC_IS_SABER2(unit)) {
  10341         switch (frequency) {
  10342             case bcmTimeSyncE25MHz:
  10343                 div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10344                 break;
  10345             case bcmTimeSyncE125MHz:
  10346                 div_in.stage0_mode      = bcmTimeSynceModeBypass;
  10347                 break;
  10348             default:
  10349                 return BCM_E_FAIL;
  10350                 break;
  10351         }
  10352     }
  10353 #endif /* defined(BCM_SABER2_SUPPORT) */
  10354 
  10355 #if defined (BCM_GREYHOUND2_SUPPORT)
  10356     if (SOC_IS_GREYHOUND2(unit)) {
  10357         if (clk_src_config->input_src == bcmTimeSynceInputSourceTypePort) {
  10358             phy_ctrl_t *pc;
  10359             phymod_dispatch_type_t type = phymodDispatchTypeInvalid;
  10360             int speed = 0;
  10361 
  10362             pc = INT_PHY_SW_STATE(unit, clk_src_config->port);
  10363             if (pc == NULL) {
  10364                 return BCM_E_FAIL;
  10365             }
  10366             type = pc->phymod_ctrl.phy[0]->pm_phy.type;
  10367 
  10368             BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, clk_src_config->port, &speed));
  10369 
  10370             switch (frequency) {
  10371                 case bcmTimeSyncE25MHz: /* 25MHz using SDM mode */
  10372                     if (type == phymodDispatchTypeTsce_dpll) {
  10373                         div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10374                         div_in.stage1_div = bcmTimeSynceStage1Div1;
  10375                         if (speed == 10606 || speed == 21000 || speed == 42000) {
  10376                             div_in.stage0_sdm_whole = 0x15;
  10377                             div_in.stage0_sdm_frac  = 0xe0;
  10378                         } else {
  10379                             div_in.stage0_sdm_whole = 0x14;
  10380                             div_in.stage0_sdm_frac  = 0xa0;
  10381                         }
  10382                     } else if (type == phymodDispatchTypeTscf) {
  10383                         div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10384                         div_in.stage1_div = bcmTimeSynceStage1Div1;
  10385                         /* falcon ports */
  10386                         if (speed ==  100 || speed == 10000 || speed== 40000) {
  10387                             /* 1G or 10G or 40G ports -  */
  10388                             div_in.stage0_sdm_whole = 0xa;
  10389                             div_in.stage0_sdm_frac  = 0x50;
  10390                         } else if (speed == 25000 || speed == 50000) {
  10391                             /* 25G or 50G ports - VCO 25.78125*/
  10392                             div_in.stage0_sdm_whole = 0x19;
  10393                             div_in.stage0_sdm_frac  = 0xc8;
  10394                         } 
  10395                         if (IS_HG_PORT(unit, clk_src_config->port) && (speed == 10000 || speed == 21000 || speed == 42000)) {
  10396                             /* 10G/21G/42G HG ports -VCO 21.875 */
  10397                             div_in.stage0_sdm_whole = 0xa;
  10398                             div_in.stage0_sdm_frac  = 0xf0;
  10399                         } else if (IS_HG_PORT(unit, clk_src_config->port) && speed == 25000) {
  10400                             /* 25G HG ports  */
  10401                             div_in.stage0_sdm_whole = 0x1b;
  10402                             div_in.stage0_sdm_frac  = 0x58;
  10403                         }
  10404                     }
  10405                     break;
  10406                 case bcmTimeSyncE125MHz: /* 125MHz viper */
  10407                     if (type == phymodDispatchTypeViper) {
  10408                         break;
  10409                     }
  10410                 default:
  10411                     return BCM_E_PARAM;
  10412             }
  10413         }
  10414     }
  10415 #endif /* defined (BCM_GREYHOUND2_SUPPORT) */
  10416 
  10417 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_APACHE_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT) || defined(BCM_HELIX5_SUPPORT) || \
  10418     defined(BCM_MONTEREY_SUPPORT)
  10419     if (clk_src_config->input_src == bcmTimeSynceInputSourceTypePort) {
  10420 #ifdef PORTMOD_SUPPORT
  10421         if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit) || SOC_IS_APACHE(unit) || SOC_IS_MAVERICK2(unit) || SOC_IS_HELIX5(unit) || SOC_IS_MONTEREY(unit)) &&
  10422             soc_feature(unit, soc_feature_portmod)) {
  10423 
  10424             int port_speed = 0; /* speed specified in mbps*/
  10425             phymod_dispatch_type_t dispatch_type = phymodDispatchTypeInvalid;
  10426 
  10427             BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, clk_src_config->port, &port_speed));
  10428 
  10429             dispatch_type = _bcm_time_synce_tsc_phymod_dispatch_type_get(unit, clk_src_config->port);
  10430 
  10431             /* as per top spec 25MHz recovered clock is suggested from all falcon ports
  10432              * using SDM mode configuration
  10433              * Tomahawk has 4 LCPLL ports , 1 - LCPLL1, 2 - LCPLL2, 3 - LCPLL3, 4 - LCPLL4
  10434              * TD3 has 4 XGPLL XGPLL0-XGPLL3
  10435              */
  10436             switch (frequency) {
  10437                 case bcmTimeSyncE25MHz: /* 25MHz using SDM mode */
  10438                     div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10439                     div_in.stage1_div = bcmTimeSynceStage1Div1;
  10440 
  10441                     if((dispatch_type == phymodDispatchTypeTsce) || 
  10442                        (dispatch_type == phymodDispatchTypeTsce16)) {
  10443                         /* eagle port */
  10444                         if (!IS_HG_PORT(unit, clk_src_config->port)) {
  10445                             /* regular port */
  10446                             div_in.stage0_sdm_whole = 0x14;
  10447                             div_in.stage0_sdm_frac  = 0xa0;
  10448                         } else {
  10449                             /* hi gig port */
  10450                             div_in.stage0_sdm_whole = 0x15;
  10451                             div_in.stage0_sdm_frac  = 0xe0;
  10452                         }
  10453                     } else if (dispatch_type == phymodDispatchTypeTscf) {
  10454                         /* falcon ports */
  10455                         if (port_speed ==  100) {
  10456                             /* 1G ports  - VCO 25.78125 */
  10457                             div_in.stage0_sdm_whole = 0x19;
  10458                             div_in.stage0_sdm_frac  = 0xc8;
  10459                         } else if (port_speed == 10000 || port_speed == 40000) {
  10460                             /* 10G or 40G ports -  VCO 20.625 */
  10461                             div_in.stage0_sdm_whole = 0xa;
  10462                             div_in.stage0_sdm_frac  = 0x50;
  10463                         } else if (port_speed == 100000 || port_speed == 25000) {
  10464                             /* 100G ports - VCO 25.78125*/
  10465                             div_in.stage0_sdm_whole = 0x19;
  10466                             div_in.stage0_sdm_frac  = 0xc8;
  10467                         } else if (IS_HG_PORT(unit, clk_src_config->port) && port_speed == 11000) {
  10468                             /* 11G HG ports -VCO 21.875 */
  10469                             div_in.stage0_sdm_whole = 0xa;
  10470                             div_in.stage0_sdm_frac  = 0xf0;
  10471                         } else if (IS_HG_PORT(unit, clk_src_config->port) && port_speed == 106000) {
  10472                             /* 106G HG ports -VCO 21.875 */
  10473                             div_in.stage0_sdm_whole = 0x1b;
  10474                             div_in.stage0_sdm_frac  = 0x58;
  10475                         }
  10476                     } else if (dispatch_type == phymodDispatchTypeTscf16) {
  10477                         /* falcon ports */
  10478                         if (port_speed ==  100) {
  10479                             /* 1G ports  - VCO 25.78125 */
  10480                             div_in.stage0_sdm_whole = 0x19;
  10481                             div_in.stage0_sdm_frac  = 0xc8;
  10482                         } else if (port_speed == 10000 || port_speed == 40000) {
  10483                             /* 10G or 40G ports -  VCO 20.625 */
  10484                             div_in.stage0_sdm_whole = 0xa;
  10485                             div_in.stage0_sdm_frac  = 0x50;
  10486                         } else if (port_speed == 100000 || port_speed == 25000) {
  10487                             /* 100G ports - VCO 25.78125*/
  10488                             div_in.stage0_sdm_whole = 0x19;
  10489                             div_in.stage0_sdm_frac  = 0xc8;
  10490                         } else if (IS_HG_PORT(unit, clk_src_config->port) && port_speed == 11000) {
  10491                             /* 11G HG ports -VCO 21.875 */
  10492                             div_in.stage0_sdm_whole = 0xa;
  10493                             div_in.stage0_sdm_frac  = 0xf0;
  10494                         } else if (IS_HG_PORT(unit, clk_src_config->port) && port_speed == 106000) {
  10495                             /* 106G HG ports -VCO 21.875 */
  10496                             div_in.stage0_sdm_whole = 0x1b;
  10497                             div_in.stage0_sdm_frac  = 0x58;
  10498                         }
  10499                     } else if (dispatch_type == phymodDispatchTypeTscbh) {
  10500                         /* DO NOTHING: portmod API will program the proper settings for SDM mode. */
  10501                     } else if (dispatch_type == phymodDispatchTypeTsce_dpll) {
  10502                         if (port_speed == 1000 || port_speed == 10000 || port_speed == 40000 || port_speed == 20000) {
  10503                             div_in.stage0_sdm_whole = 0x14;
  10504                             div_in.stage0_sdm_frac  = 0xa0;
  10505                         } else {
  10506                             div_in.stage0_sdm_whole = 0x15;
  10507                             div_in.stage0_sdm_frac  = 0xE0;
  10508                         }
  10509                     } else if (dispatch_type == phymodDispatchTypeTscf_gen3) {
  10510                         if (port_speed == 25000 || port_speed == 100000 || port_speed == 50000) {
  10511                             div_in.stage0_sdm_whole = 0x19;
  10512                             div_in.stage0_sdm_frac  = 0xC8;
  10513                         } else if (port_speed == 1000) {
  10514                             div_in.stage0_sdm_whole = 0x14;
  10515                             div_in.stage0_sdm_frac  = 0xA0;
  10516                         } else {
  10517                             div_in.stage0_sdm_whole = 0x0A;
  10518                             div_in.stage0_sdm_frac  = 0x50;
  10519                         }
  10520                     } else {
  10521                         cli_out("unknown port dispatch type  ... %d\n", (int)dispatch_type);
  10522                         return BCM_E_FAIL;
  10523                     }
  10524                     break;
  10525                 case bcmTimeSyncE7MHz:
  10526                     div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10527                     div_in.stage1_div = bcmTimeSynceStage1Div1;
  10528 
  10529                     if (dispatch_type == phymodDispatchTypeTsce_dpll) {
  10530                         if (port_speed == 1000 || port_speed == 10000 || port_speed == 40000 || port_speed == 20000) {
  10531                             div_in.stage0_sdm_whole = 0x42;
  10532                             div_in.stage0_sdm_frac  = 0x00;
  10533                         }
  10534                     } else if (dispatch_type == phymodDispatchTypeTscf_gen3) {
  10535                         if (port_speed == 25000 || port_speed == 100000 || port_speed == 50000) {
  10536                             div_in.stage0_sdm_whole = 0x52;
  10537                             div_in.stage0_sdm_frac  = 0x80;
  10538                         } else if (port_speed == 1000) {
  10539                             div_in.stage0_sdm_whole = 0x42;
  10540                             div_in.stage0_sdm_frac  = 0x00;
  10541                         } else {
  10542                             div_in.stage0_sdm_whole = 0x21;
  10543                             div_in.stage0_sdm_frac  = 0x00;
  10544                         }
  10545                     }
  10546                     break;
  10547                 case bcmTimeSyncE12MHz:
  10548                     div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10549                     div_in.stage1_div = bcmTimeSynceStage1Div1;
  10550 
  10551                     if (dispatch_type == phymodDispatchTypeTsce_dpll) {
  10552                         if (port_speed == 1000 || port_speed == 10000 || port_speed == 40000 || port_speed == 20000) {
  10553                             div_in.stage0_sdm_whole = 0x29;
  10554                             div_in.stage0_sdm_frac  = 0x40;
  10555                         }
  10556                     } else if (dispatch_type == phymodDispatchTypeTscf_gen3) {
  10557                         if (port_speed == 25000 || port_speed == 100000 || port_speed == 50000) {
  10558                             div_in.stage0_sdm_whole = 0x33;
  10559                             div_in.stage0_sdm_frac  = 0x90;
  10560                         } else if (port_speed == 1000) {
  10561                             div_in.stage0_sdm_whole = 0x29;
  10562                             div_in.stage0_sdm_frac  = 0x40;
  10563                         } else {
  10564                             div_in.stage0_sdm_whole = 0x14;
  10565                             div_in.stage0_sdm_frac  = 0xa0;
  10566                         }
  10567                     }
  10568                     break;
  10569                 case bcmTimeSyncE31MHz:
  10570                     div_in.stage0_mode = bcmTimeSynceModeSDMFracDiv;
  10571                     div_in.stage1_div = bcmTimeSynceStage1Div1;
  10572 
  10573                     if (dispatch_type == phymodDispatchTypeTsce_dpll) {
  10574                         if (port_speed == 1000 || port_speed == 10000 || port_speed == 40000 || port_speed == 20000) {
  10575                             div_in.stage0_sdm_whole = 0x10;
  10576                             div_in.stage0_sdm_frac  = 0x80;
  10577                         }
  10578                     } else if (dispatch_type == phymodDispatchTypeTscf_gen3) {
  10579                         if (port_speed == 25000 || port_speed == 100000 || port_speed == 50000) {
  10580                             div_in.stage0_sdm_whole = 0x14;
  10581                             div_in.stage0_sdm_frac  = 0xa0;
  10582                         } else if (port_speed == 1000) {
  10583                             div_in.stage0_sdm_whole = 0x10;
  10584                             div_in.stage0_sdm_frac  = 0x80;
  10585                         } else {
  10586                             div_in.stage0_sdm_whole = 0x08;
  10587                             div_in.stage0_sdm_frac  = 0x40;
  10588                         }
  10589                     }
  10590                     break;
  10591                 case bcmTimeSyncE37MHz:
  10592                     div_in.stage0_mode = bcmTimeSynceModeSDMFracDiv;
  10593                     div_in.stage1_div = bcmTimeSynceStage1Div1;
  10594 
  10595                     if (dispatch_type == phymodDispatchTypeTsce_dpll) {
  10596                         if (port_speed == 1000 || port_speed == 10000 || port_speed == 40000 || port_speed == 20000) {
  10597                             div_in.stage0_sdm_whole = 0x0D;
  10598                             div_in.stage0_sdm_frac  = 0xC0;
  10599                         }
  10600                     } else if (dispatch_type == phymodDispatchTypeTscf_gen3) {
  10601                         if (port_speed == 25000 || port_speed == 100000 || port_speed == 50000) {
  10602                             div_in.stage0_sdm_whole = 0x11;
  10603                             div_in.stage0_sdm_frac  = 0x30;
  10604                         } else if (port_speed == 1000) {
  10605                             div_in.stage0_sdm_whole = 0x0D;
  10606                             div_in.stage0_sdm_frac  = 0xC0;
  10607                         } else {
  10608                             div_in.stage0_sdm_whole = 0x06;
  10609                             div_in.stage0_sdm_frac  = 0xE0;
  10610                         }
  10611                     }
  10612                     break;
  10613                 default:
  10614                     /* not supported */
  10615                     return BCM_E_FAIL;
  10616                     break;
  10617             }
  10618         }
  10619         else
  10620 #endif /* PORTMOD_SUPPORT */
  10621         {
  10622             if (SOC_IS_TOMAHAWK(unit)) {
  10623                 switch (frequency) {
  10624                     case bcmTimeSyncE25MHz:
  10625                         div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10626                         div_in.stage0_sdm_whole = 20;
  10627                         div_in.stage0_sdm_frac  = 160;
  10628                         break;
  10629                     default:
  10630                         return BCM_E_FAIL;
  10631                 break;
  10632                 }
  10633 
  10634             }
  10635         }
  10636     }
  10637 #endif /* TH TD3 AP MV2 HX5 support */
  10638 
  10639 #if defined(BCM_METROLITE_SUPPORT)
  10640     if (SOC_IS_METROLITE(unit)) {
  10641         switch (frequency) {
  10642             /* For Viper: div5 logic at Mux1 gives 25MHz
  10643              * For Eagle: default SDM logic choosen TSCE synce div gives 25MHz
  10644              *            make sure portmacro side stage1 is not in default
  10645              *            div11(for SDM stage1 should be in div1)
  10646              */
  10647             case bcmTimeSyncE25MHz:
  10648                 div_in.stage0_mode      = bcmTimeSynceModeSDMFracDiv;
  10649                 break;
  10650             /* For Viper only : 125MHz bypassed L1 recov_clock */
  10651             case bcmTimeSyncE125MHz:
  10652                 div_in.stage0_mode      = bcmTimeSynceModeBypass;
  10653                 break;
  10654             default:
  10655                 return BCM_E_FAIL;
  10656                 break;
  10657         }
  10658     }
  10659 #endif /* defined(BCM_METROLITE_SUPPORT) */
  10660 
  10661     rv = bcm_esw_time_synce_clock_set(unit, clk_src_config->clk_src, &div_in);
  10662     return rv;
  10663 }
  10664 
  10665 
  10666 /*
  10667  * Function:
  10668  *      bcm_esw_time_synce_clock_source_control_set
  10669  * Purpose:
  10670  *      Set syncE clock source control option
  10671  * Parameters:
  10672  *      unit    - (IN)  Unit number.
  10673  *      clk_src_config - (IN) clock source config
  10674  *      value - (IN) control value
  10675  * Returns:
  10676  *      BCM_E_xxx
  10677  * Notes: NEW API to support SYNCE configuration
  10678  */
  10679 int
  10680 bcm_esw_time_synce_clock_source_control_set(int unit,
  10681                              bcm_time_synce_clock_source_config_t *clk_src_config,
  10682                              bcm_time_synce_clock_source_control_t control,
  10683                              int value)
  10684 {
  10685     int rv = BCM_E_UNAVAIL;
  10686 
  10687     switch (control) {
  10688     case bcmTimeSynceClockSourceControlSquelch:
  10689         rv = _bcm_esw_time_synce_clock_source_squelch_set(unit, clk_src_config->clk_src, value);
  10690         break;
  10691     case bcmTimeSynceClockSourceControlFrequency:
  10692         rv = _bcm_esw_time_synce_clock_source_frequency_set(unit, clk_src_config, value);
  10693         break;
  10694     default:
  10695         return BCM_E_PARAM;
  10696    }
  10697 
  10698    return rv;
  10699 }
  10700 
  10701 /*
  10702  * Function:
  10703  *      bcm_esw_time_bs_time_get 
  10704  * Purpose:
  10705  *      Get the broadsync time on the specified unit 
  10706  * Parameters:
  10707  *      unit - (IN) StrataSwitch Unit #.
  10708  *      bs_time - (OUT) broadsync time in seconds and nanoseconds
  10709  * Returns:
  10710  *      BCM_E_NONE
  10711  *      BCM_E_XXX
  10712  */
  10713 
  10714 int 
  10715 bcm_esw_time_bs_time_get (int unit, bcm_time_spec_t *bs_time)
  10716 {
  10717     int rv;   /* Operation return status. */
  10718     uint8 bs_initialized=0;
  10719 
  10720     /* Chek if time feature is supported on a device */
  10721     if (!soc_feature(unit, soc_feature_time_support)) {
  10722         return (BCM_E_UNAVAIL);
  10723     }
  10724 
  10725     bcm_esw_time_interface_traverse(unit, _bcm_time_interface_traverse_cb,
  10726                                         (void*)&bs_initialized);
  10727     if (!bs_initialized) {
  10728         return BCM_E_INIT;
  10729     }
  10730 
  10731     if (NULL == bs_time) {
  10732         return (BCM_E_PARAM);
  10733     }
  10734 
  10735     TIME_LOCK(unit);
  10736     rv = _bcm_time_bs_time_get(unit, bs_time);
  10737     if (BCM_FAILURE(rv)) {
  10738         TIME_UNLOCK(unit);
  10739         return (rv);
  10740     }
  10741     TIME_UNLOCK(unit);
  10742 
  10743     return (BCM_E_NONE);
  10744 }
  10745 
  10746 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  10747 int
  10748 _bcm_esw_time_counter_get(int unit, int ts_counter, uint64 *pTS_val)
  10749 {
  10750     int rv  = BCM_E_NONE;
  10751     uint64 ts;
  10752     uint32 upper;
  10753     uint32 lower;
  10754 
  10755     if (ts_counter == 1) {
  10756         READ_NS_TIMESYNC_TS1_TIMESTAMP_UPPER_STATUSr(unit, &upper);
  10757         READ_NS_TIMESYNC_TS1_TIMESTAMP_LOWER_STATUSr(unit, &lower);
  10758     } else if(ts_counter == 0) {
  10759         READ_NS_TIMESYNC_TS0_TIMESTAMP_UPPER_STATUSr(unit, &upper);
  10760         READ_NS_TIMESYNC_TS0_TIMESTAMP_LOWER_STATUSr(unit, &lower);
  10761     } else {
  10762         return BCM_E_FAIL;
  10763     }
  10764 
  10765     u64_H(ts) = upper;
  10766     u64_L(ts) = lower;
  10767 
  10768     if (SOC_IS_TOMAHAWK3(unit)) {
  10769         COMPILER_64_SHR(ts, 4);
  10770     }
  10771 
  10772     *pTS_val = ts;
  10773 
  10774     return rv;
  10775 }
  10776 
  10777 int
  10778 _bcm_esw_time_counter_set(int unit, int ts_counter, uint64 ts_val)
  10779 {
  10780     uint32 rval;
  10781     int rv  = BCM_E_NONE;
  10782 
  10783     /* 52b format frpom 48b ns */
  10784     if(SOC_IS_MONTEREY(unit) || SOC_IS_TOMAHAWK3(unit)) {
  10785         COMPILER_64_SHL(ts_val, 4);
  10786     }
  10787 
  10788     if (ts_counter == 1) {
  10789         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r(unit, &rval));
  10790         soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r, &rval, ACC2f, u64_H(ts_val) << 8 | u64_L(ts_val) >> 24);
  10791         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r(unit, rval));
  10792 
  10793         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r(unit, &rval));
  10794         soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r, &rval, ACC1f, u64_L(ts_val) << 8);
  10795         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r(unit, rval));
  10796 
  10797         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r(unit, &rval));
  10798         soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r, &rval, ACC0f, 0);
  10799         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r(unit, rval));
  10800 
  10801     } else if (ts_counter == 0) {
  10802         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r(unit, &rval));
  10803         soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r, &rval, ACC2f, u64_H(ts_val) << 8 | u64_L(ts_val) >> 24);
  10804         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r(unit, rval));
  10805 
  10806         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r(unit, &rval));
  10807         soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r, &rval, ACC1f, u64_L(ts_val) << 8);
  10808         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r(unit, rval));
  10809 
  10810         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r(unit, &rval));
  10811         soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r, &rval, ACC0f, 0);
  10812         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r(unit, rval));
  10813     } else {
  10814         rv = BCM_E_FAIL;
  10815     }
  10816 
  10817     return rv;
  10818 }
  10819 
  10820 int
  10821 _bcm_esw_time_counter_enable(int unit, int ts_counter, int enable)
  10822 {
  10823     uint32 rval;
  10824     int rv  = BCM_E_NONE;
  10825 
  10826     if (ts_counter == 1) {
  10827         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, &rval));
  10828         soc_reg_field_set(unit, NS_TIMESYNC_TS1_COUNTER_ENABLEr, &rval, ENABLEf, enable?1:0);
  10829         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, rval));
  10830     } else if (ts_counter == 0) {
  10831         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &rval));
  10832         soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &rval, ENABLEf, enable?1:0);
  10833         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, rval));
  10834     } else {
  10835         rv = BCM_E_FAIL;
  10836     }
  10837 
  10838     return rv;
  10839 }
  10840 
  10841 int
  10842 _bcm_esw_time_counter_freq_frac_set(int unit, int ts_counter)
  10843 {
  10844     uint32 rval;
  10845     int rv  = BCM_E_NONE;
  10846 
  10847     if (ts_counter == 1) {
  10848         /* Disable the common control of TS0 and TS1 */
  10849         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, &rval));
  10850         soc_reg_field_set(unit, NS_TIMESYNC_COUNTER_CONFIG_SELECTr, &rval, ENABLE_COMMON_CONTROLf, 0);
  10851         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, rval));
  10852 
  10853         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr(unit, &rval));
  10854         soc_reg_field_set(unit, NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr, &rval, UINCf, 0x2000);
  10855         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr(unit, rval));
  10856 
  10857         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr(unit, &rval));
  10858         soc_reg_field_set(unit, NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr, &rval, LINCf, 0x0);
  10859         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr(unit, rval));
  10860 
  10861     } else if (ts_counter == 0) {
  10862         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, &rval));
  10863         soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr, &rval, UINCf, 0x2000);
  10864         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, rval));
  10865 
  10866         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, &rval));
  10867         soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr, &rval, LINCf, 0x0);
  10868         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, rval));
  10869     } else {
  10870         rv = BCM_E_FAIL;
  10871     }
  10872 
  10873     return rv;
  10874 }
  10875 
  10876 #endif
  10877 
  10878 /*
  10879  * Function:
  10880  *      bcm_esw_time_ts_counter_set
  10881  * Purpose:
  10882  *      Set timestamper counter
  10883  * Parameters:
  10884  *      unit    - (IN)  Unit number.
  10885  *      counter - (IN)  counter values
  10886  * Returns:
  10887  *      BCM_E_xxx
  10888  */
  10889 int
  10890 bcm_esw_time_ts_counter_set(
  10891         int unit,
  10892         bcm_time_ts_counter_t  *counter)
  10893 {
  10894     int rv = BCM_E_UNAVAIL;
  10895 #if (defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
  10896      defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT))
  10897     uint32 freq_ctrl = 0;
  10898     uint64 check;
  10899     uint32 u64_hi = 0xffff, u64_low = 0xffffffff;
  10900 
  10901     if (counter == NULL) {
  10902         return BCM_E_PARAM;
  10903     }
  10904 
  10905     COMPILER_64_SET(check, u64_hi, u64_low);
  10906 
  10907     if (COMPILER_64_GT(counter->ts_counter_ns, check)) {
  10908         return BCM_E_PARAM;
  10909     }
  10910 
  10911 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  10912     if(SOC_IS_MONTEREY(unit) || SOC_IS_TOMAHAWK3(unit)) {
  10913         int ts_counter;
  10914 
  10915         
  10916         ts_counter = counter->ts_counter;
  10917 
  10918         SOC_IF_ERROR_RETURN(_bcm_esw_time_counter_enable(unit, ts_counter, 0));
  10919         if(SOC_IS_MONTEREY(unit)) {
  10920             SOC_IF_ERROR_RETURN(_bcm_esw_time_counter_freq_frac_set(unit, ts_counter));
  10921         } else if (SOC_IS_TOMAHAWK3(unit)) {
  10922             SOC_IF_ERROR_RETURN(_bcm_esw_time_counter_set(unit, ts_counter, counter->ts_counter_ns));
  10923         }
  10924         SOC_IF_ERROR_RETURN(_bcm_esw_time_counter_enable(unit, ts_counter, counter->enable));
  10925 
  10926         rv = BCM_E_NONE;
  10927     } else
  10928 #endif
  10929     {
  10930         freq_ctrl = (counter->time_format == bcmTimeFormatPTP) ?
  10931             0x40000000 : 0x44B82FA1;
  10932 
  10933         rv = soc_reg_field32_modify(unit, CMIC_TIMESYNC_TS1_FREQ_CTRL_FRACr,
  10934                 REG_PORT_ANY,
  10935                 FRACf, freq_ctrl);
  10936 
  10937         if (BCM_FAILURE(rv)) {
  10938             return rv;
  10939         }
  10940 
  10941         /*
  10942          * Adding 64bit upper 32 bits into 32 bit container.
  10943          * then extracting only 16 bits.
  10944          */
  10945         COMPILER_64_TO_32_HI(u64_hi, counter->ts_counter_ns);
  10946         rv = soc_reg_field32_modify(unit, CMIC_TIMESYNC_TS1_FREQ_CTRL_UPPERr,
  10947                 REG_PORT_ANY,
  10948                 NSf, (u64_hi & 0xffff));
  10949 
  10950         if (BCM_FAILURE(rv)) {
  10951             return rv;
  10952         }
  10953 
  10954         /* Adding 64bit lower 32 bits into 32 bit container. */
  10955         COMPILER_64_TO_32_LO(u64_low, counter->ts_counter_ns);
  10956         rv = soc_reg_field32_modify(unit, CMIC_TIMESYNC_TS1_FREQ_CTRL_LOWERr,
  10957                 REG_PORT_ANY,
  10958                 NSf, u64_low);
  10959 
  10960         if (BCM_FAILURE(rv)) {
  10961             return rv;
  10962         }
  10963 
  10964         /* Set the enable and disable control. */
  10965         rv = soc_reg_field32_modify(unit, CMIC_TIMESYNC_TS1_COUNTER_ENABLEr,
  10966                 REG_PORT_ANY,
  10967                 ENABLEf, counter->enable);
  10968     }
  10969 #endif
  10970 
  10971     return rv;
  10972 }
  10973 
  10974 /*
  10975  * Function:
  10976  *      bcm_esw_time_ts_counter_get
  10977  * Purpose:
  10978  *      Get timestamper counter
  10979  * Parameters:
  10980  *      unit    - (IN)  Unit number.
  10981  *      counter - (OUT)  counter values
  10982  * Returns:
  10983  *      BCM_E_xxx
  10984  */
  10985 int
  10986 bcm_esw_time_ts_counter_get(
  10987         int unit,
  10988         bcm_time_ts_counter_t  *counter)
  10989 {
  10990     int rv = BCM_E_UNAVAIL;
  10991 #if (defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
  10992      defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT))
  10993     uint32 val_hi = 0, val_lo = 0;
  10994 
  10995     if (counter == NULL) {
  10996         return BCM_E_PARAM;
  10997     }
  10998 
  10999 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  11000     if(SOC_IS_MONTEREY(unit) || SOC_IS_TOMAHAWK3(unit)) {
  11001         int ts_counter;
  11002         uint32 regval;
  11003 
  11004         
  11005         ts_counter = counter->ts_counter;
  11006 
  11007         SOC_IF_ERROR_RETURN(_bcm_esw_time_counter_get(unit, ts_counter, &counter->ts_counter_ns));
  11008 
  11009         /* Read the enable status */
  11010         if (ts_counter == 1) {
  11011             SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, &regval));
  11012             counter->enable = soc_reg_field_get(unit, NS_TIMESYNC_TS1_COUNTER_ENABLEr, regval, ENABLEf);
  11013         } else if(ts_counter == 0) {
  11014             SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &regval));
  11015             counter->enable = soc_reg_field_get(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, regval, ENABLEf);
  11016         } else {
  11017             return BCM_E_FAIL;
  11018         }
  11019 
  11020         if (SOC_IS_TOMAHAWK3(unit)) {
  11021             uint32 freq_ctrl = 0, freq_ctrl_2 = 0;
  11022             READ_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr(unit, &freq_ctrl);
  11023             READ_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr(unit, &freq_ctrl_2);
  11024 
  11025             if ((freq_ctrl == 0x2000) && (freq_ctrl_2 == 0)) {
  11026                 counter->time_format = bcmTimeFormatPTP;
  11027             } else {
  11028                 counter->time_format = bcmTimeFormatNTP;
  11029             }
  11030         } else {
  11031             counter->time_format = bcmTimeFormatPTP;
  11032         }
  11033         rv = BCM_E_NONE;
  11034     } else
  11035 #endif
  11036     {
  11037         uint32 freq_ctrl = 0;
  11038         rv = READ_CMIC_TIMESYNC_TS1_FREQ_CTRL_FRACr(unit, &freq_ctrl);
  11039         if(BCM_FAILURE(rv)) {
  11040             return rv;
  11041         }
  11042 
  11043         if (freq_ctrl == 0x40000000) {
  11044             counter->time_format = bcmTimeFormatPTP;
  11045         } else {
  11046             counter->time_format = bcmTimeFormatNTP;
  11047         }
  11048 
  11049         rv = READ_CMIC_TIMESYNC_TS1_FREQ_CTRL_UPPERr(unit, &val_hi);
  11050         if(BCM_FAILURE(rv)) {
  11051             return rv;
  11052         }
  11053 
  11054         rv = READ_CMIC_TIMESYNC_TS1_FREQ_CTRL_LOWERr(unit, &val_lo);
  11055         if(BCM_FAILURE(rv)) {
  11056             return rv;
  11057         }
  11058 
  11059         COMPILER_64_SET(counter->ts_counter_ns, val_hi, val_lo);
  11060 
  11061         val_lo = 0;
  11062         rv = READ_CMIC_TIMESYNC_TS1_COUNTER_ENABLEr(unit, &val_lo);
  11063 
  11064         counter->enable = ((val_lo) ? 1 : 0);
  11065     }
  11066 #endif
  11067 
  11068     return rv;
  11069 }
  11070 
  11071 
  11072 
  11073 /*
  11074  * Function:
  11075  *      bcmi_time_tod_set
  11076  * Purpose:
  11077  *      Internal function to update tod values.
  11078  * Parameters:
  11079  *      unit    - (IN)  Unit number.
  11080  *      tod     - (IN)  Time of the day values.
  11081  *      stage   - (IN)  Stage where time needs to be updated.
  11082  * Returns:
  11083  *      BCM_E_xxx
  11084  */
  11085 int
  11086 bcmi_time_tod_set(
  11087         int unit,
  11088         bcm_time_tod_t *tod,
  11089         int stage)
  11090 
  11091 {
  11092     soc_mem_t mem = INVALIDm;
  11093 #if defined(BCM_FLOWTRACKER_SUPPORT)
  11094     bsc_ts_utc_conversion_entry_t ts_entry;
  11095 #else
  11096     egr_ts_utc_conversion_entry_t ts_entry;
  11097 #endif /* BCM_FLOWTRACKER_SUPPORT */
  11098     uint64 check;
  11099     uint32 u64_hi = 0xffff, u64_low = 0xffffffff;
  11100     uint32 data_sec[2], data_nsec[2];
  11101     int rv = 0;
  11102 
  11103     if (stage == 1 ) {
  11104         mem = EGR_TS_UTC_CONVERSIONm;
  11105     }
  11106 #if defined(BCM_FLOWTRACKER_SUPPORT)
  11107     else {
  11108         mem = BSC_TS_UTC_CONVERSIONm;
  11109     }
  11110 #endif /* BCM_FLOWTRACKER_SUPPORT */
  11111 
  11112     /* coverity[dead_error_line] */
  11113     if(mem == INVALIDm) {
  11114        return BCM_E_NONE;
  11115     }
  11116 
  11117 #if defined(BCM_FLOWTRACKER_SUPPORT)
  11118     sal_memset(&ts_entry, 0, sizeof(bsc_ts_utc_conversion_entry_t));
  11119 #else
  11120     sal_memset(&ts_entry, 0, sizeof(egr_ts_utc_conversion_entry_t));
  11121 #endif /* BCM_FLOWTRACKER_SUPPORT */
  11122     COMPILER_64_SET(check, u64_hi, u64_low);
  11123 
  11124     if (COMPILER_64_GT(tod->ts.seconds, check)) {
  11125         return BCM_E_PARAM;
  11126     }
  11127     if (COMPILER_64_GT(tod->ts_adjustment_counter_ns, check)) {
  11128         return BCM_E_PARAM;
  11129     }
  11130 #if defined(BCM_FLOWTRACKER_SUPPORT)
  11131     /* Set timestamp format. */
  11132     if (soc_mem_field_valid(unit, mem, TIMESTAMP_FORMATf)) {
  11133         soc_mem_field32_set(unit, mem, (uint32 *)&ts_entry, TIMESTAMP_FORMATf,
  11134                 tod->time_format);
  11135     }
  11136 #endif /* BCM_FLOWTRACKER_SUPPORT */
  11137     /* Set Nanoseconds. */
  11138     if (soc_mem_field_valid(unit, mem, TIMESTAMP_TOD_NSECf)) {
  11139         soc_mem_field32_set(unit, mem, (uint32 *)&ts_entry, TIMESTAMP_TOD_NSECf,
  11140                 tod->ts.nanoseconds);
  11141     }
  11142 
  11143     sal_memset(data_sec, 0, 2*sizeof(uint32));
  11144     COMPILER_64_TO_32_LO(data_sec[0], tod->ts.seconds);
  11145     COMPILER_64_TO_32_HI(data_sec[1], tod->ts.seconds);
  11146 
  11147     if (soc_mem_field_valid(unit, mem, TIMESTAMP_TOD_SECf)) {
  11148         soc_mem_field_set(unit, mem, (uint32 *)&ts_entry, TIMESTAMP_TOD_SECf,
  11149                 data_sec);
  11150     }
  11151 
  11152     sal_memset(data_nsec, 0, 2*sizeof(uint32));
  11153     COMPILER_64_TO_32_LO(data_nsec[0], tod->ts_adjustment_counter_ns);
  11154     COMPILER_64_TO_32_HI(data_nsec[1], tod->ts_adjustment_counter_ns);
  11155 
  11156     if (soc_mem_field_valid(unit, mem, TIMESTAMP_TA_NSECf)) {
  11157         soc_mem_field_set(unit, mem, (uint32 *)&ts_entry, TIMESTAMP_TA_NSECf,
  11158                 data_nsec);
  11159     }
  11160 
  11161     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0,  &ts_entry);
  11162 
  11163 #if defined(BCM_TOMAHAWK3_SUPPORT)
  11164     if ((SOC_IS_TOMAHAWK3(unit)) && (!BCM_FAILURE(rv))) {
  11165         soc_mem_t mem_2 = EGR_TS_UTC_CONVERSION_2m;
  11166 
  11167         if (soc_mem_field_valid(unit, mem_2, TIMESTAMP_TOD_NSECf)) {
  11168             soc_mem_field32_set(unit, mem_2, (uint32 *)&ts_entry, TIMESTAMP_TOD_NSECf,
  11169                     tod->ts.nanoseconds);
  11170         }
  11171         if (soc_mem_field_valid(unit, mem_2, TIMESTAMP_TOD_SECf)) {
  11172             soc_mem_field_set(unit, mem_2, (uint32 *)&ts_entry, TIMESTAMP_TOD_SECf,
  11173                     data_sec);
  11174         }
  11175         if (soc_mem_field_valid(unit, mem_2, TIMESTAMP_TA_NSECf)) {
  11176             soc_mem_field_set(unit, mem_2, (uint32 *)&ts_entry, TIMESTAMP_TA_NSECf,
  11177                     data_nsec);
  11178         }
  11179 
  11180         rv = soc_mem_write(unit, mem_2, MEM_BLOCK_ALL, 0,  &ts_entry);
  11181     }
  11182 #endif /* BCM_TOMAHAWK3_SUPPORT */
  11183 
  11184     return rv;
  11185 }
  11186 
  11187 /*
  11188  * Function:
  11189  *      bcmi_time_tod_get
  11190  * Purpose:
  11191  *      Internal function to get tod values for stage.
  11192  * Parameters:
  11193  *      unit    - (IN)  Unit number.
  11194  *      tod     - (OUT)  Time of the day values.
  11195  *      stage   - (IN)  Stage where time needs to be updated.
  11196  * Returns:
  11197  *      BCM_E_xxx
  11198  */
  11199 int
  11200 bcmi_time_tod_get(
  11201         int unit,
  11202         bcm_time_tod_t *tod,
  11203         int stage)
  11204 
  11205 {
  11206     soc_mem_t mem = INVALIDm;
  11207 #if defined(BCM_FLOWTRACKER_SUPPORT)
  11208     bsc_ts_utc_conversion_entry_t ts_entry;
  11209 #else
  11210     egr_ts_utc_conversion_entry_t ts_entry;
  11211 #endif /* BCM_FLOWTRACKER_SUPPORT */
  11212     uint32 data[2];
  11213     int rv = 0;
  11214 
  11215     if (stage == 1 ) {
  11216         mem = EGR_TS_UTC_CONVERSIONm;
  11217     }
  11218 #if defined(BCM_FLOWTRACKER_SUPPORT)
  11219     else {
  11220         mem = BSC_TS_UTC_CONVERSIONm;
  11221     }
  11222 #endif /* BCM_FLOWTRACKER_SUPPORT */
  11223 
  11224     /* coverity[dead_error_line] */
  11225     if(mem == INVALIDm) {
  11226        return BCM_E_NONE;
  11227     }
  11228 #if defined(BCM_FLOWTRACKER_SUPPORT)
  11229     sal_memset(&ts_entry, 0, sizeof(bsc_ts_utc_conversion_entry_t));
  11230 #else
  11231     sal_memset(&ts_entry, 0, sizeof(egr_ts_utc_conversion_entry_t));
  11232 #endif
  11233     rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, 0,  &ts_entry);
  11234 
  11235     if (BCM_FAILURE(rv)) {
  11236         return rv;
  11237     }
  11238 #if defined(BCM_FLOWTRACKER_SUPPORT)
  11239     /* Set timestamp format. */
  11240     if (soc_mem_field_valid(unit, mem, TIMESTAMP_FORMATf)) {
  11241         tod->time_format = soc_mem_field32_get(unit, mem, (uint32 *)&ts_entry,
  11242                 TIMESTAMP_FORMATf);
  11243     }
  11244 #endif /* BCM_FLOWTRACKER_SUPPORT */
  11245     /* Set Nanoseconds. */
  11246     if (soc_mem_field_valid(unit, mem, TIMESTAMP_TOD_NSECf)) {
  11247         tod->ts.nanoseconds = soc_mem_field32_get(unit, mem, (uint32 *)&ts_entry,
  11248                 TIMESTAMP_TOD_NSECf);
  11249     }
  11250 
  11251     sal_memset(data, 0, 2*sizeof(uint32));
  11252 
  11253     if (soc_mem_field_valid(unit, mem, TIMESTAMP_TOD_SECf)) {
  11254         soc_mem_field_get(unit, mem, (uint32 *)&ts_entry, TIMESTAMP_TOD_SECf,
  11255                 data);
  11256     }
  11257 
  11258     COMPILER_64_SET(tod->ts.seconds, data[1], data[0]);
  11259 
  11260     sal_memset(data, 0, 2*sizeof(uint32));
  11261 
  11262     if (soc_mem_field_valid(unit, mem, TIMESTAMP_TA_NSECf)) {
  11263         soc_mem_field_get(unit, mem, (uint32 *)&ts_entry, TIMESTAMP_TA_NSECf,
  11264                 (uint32 *)&data);
  11265     }
  11266 
  11267     COMPILER_64_SET(tod->ts_adjustment_counter_ns, data[1], data[0]);
  11268 
  11269     return BCM_E_NONE;
  11270 }
  11271 
  11272 /*
  11273  * Function:
  11274  *      bcm_esw_time_tod_set
  11275  * Purpose:
  11276  *      API to update tod values for stage.
  11277  * Parameters:
  11278  *      unit    - (IN)  Unit number.
  11279  *      stages  - (IN)  Stage where time needs to be updated.
  11280  *      tod     - (IN)  Time of the day values.
  11281  * Returns:
  11282  *      BCM_E_xxx
  11283  */
  11284 int
  11285 bcm_esw_time_tod_set(
  11286         int unit,
  11287         uint32 stages,
  11288         bcm_time_tod_t *tod)
  11289 {
  11290 
  11291     int rv = BCM_E_UNAVAIL;
  11292 
  11293     if (tod == NULL) {
  11294         return BCM_E_PARAM;
  11295     }
  11296 
  11297 #if (defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
  11298      defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT))
  11299     if (stages & BCM_TIME_STAGE_ALL) {
  11300         rv = bcmi_time_tod_set(unit, tod, 1);
  11301         if (rv) {
  11302             return rv;
  11303         }
  11304 
  11305         rv = bcmi_time_tod_set(unit, tod, 0);
  11306     } else if (stages & BCM_TIME_STAGE_EGRESS) {
  11307         rv = bcmi_time_tod_set(unit, tod, 1);
  11308     }  else if (stages & BCM_TIME_STAGE_INGRESS_FLOWTRACKER) {
  11309         rv = bcmi_time_tod_set(unit, tod, 0);
  11310     } else {
  11311         return BCM_E_PARAM;
  11312     }
  11313 #endif
  11314 
  11315     return rv;
  11316 }
  11317 
  11318 /*
  11319  * Function:
  11320  *      bcm_esw_time_tod_get
  11321  * Purpose:
  11322  *      API to get tod values for stage.
  11323  * Parameters:
  11324  *      unit    - (IN)  Unit number.
  11325  *      stages  - (IN)  Stage where time needs to be updated.
  11326  *      tod     - (IN)  Time of the day values.
  11327  * Returns:
  11328  *      BCM_E_xxx
  11329  */
  11330 int
  11331 bcm_esw_time_tod_get(
  11332         int unit,
  11333         uint32 stages,
  11334         bcm_time_tod_t *tod)
  11335 {
  11336     int rv = BCM_E_UNAVAIL;
  11337 
  11338     if (tod == NULL) {
  11339         return BCM_E_PARAM;
  11340     }
  11341 
  11342 #if (defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
  11343      defined(BCM_TOMAHAWK2_SUPPORT)|| defined(BCM_MAVERICK2_SUPPORT))
  11344     if (stages & BCM_TIME_STAGE_ALL) {
  11345         rv = bcmi_time_tod_get(unit, tod, 1);
  11346     } else if (stages & BCM_TIME_STAGE_EGRESS) {
  11347         rv = bcmi_time_tod_get(unit, tod, 1);
  11348     }  else if (stages & BCM_TIME_STAGE_INGRESS_FLOWTRACKER) {
  11349         rv = bcmi_time_tod_get(unit, tod, 0);
  11350     } else {
  11351         return BCM_E_PARAM;
  11352     }
  11353 #endif
  11354 
  11355     return rv;
  11356 }
  11357 
  11358 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  11359 int _bcm_esw_get_event_config_from_time_capture(
  11360         int unit,
  11361         bcm_time_capture_t *time_capture,
  11362         _bcm_time_capture_input_t *time_capture_input)
  11363 {
  11364     time_capture_input->event_dest = _bcmTimeCaptureDestCPU;
  11365     time_capture_input->event_divisor = time_capture->event_divisor;
  11366     time_capture_input->port = time_capture->port;
  11367     time_capture_input->port_event_type = time_capture->port_event_type;
  11368     time_capture_input->ppm_check_enable = 0; /* Not valid for FIFO timestamp capture */
  11369     time_capture_input->ts_counter = time_capture->ts_counter;
  11370 
  11371     switch (time_capture->flags){
  11372     case BCM_TIME_CAPTURE_LOCKED:
  11373     case BCM_TIME_CAPTURE_L1_CLOCK_PRIMARY:
  11374     case BCM_TIME_CAPTURE_L1_CLOCK_SECONDARY:
  11375     case BCM_TIME_CAPTURE_IMMEDIATE:
  11376         bsl_printf("Unable to find mapping for flag set in time_capture\n");
  11377         return BCM_E_NOT_FOUND;
  11378     case BCM_TIME_CAPTURE_GPIO_0:
  11379         time_capture_input->input_event = _bcmTimeCaptureEventGPIO0;
  11380         break;
  11381     case BCM_TIME_CAPTURE_GPIO_1:
  11382         time_capture_input->input_event = _bcmTimeCaptureEventGPIO1;
  11383         break;
  11384     case BCM_TIME_CAPTURE_GPIO_2:
  11385         time_capture_input->input_event = _bcmTimeCaptureEventGPIO2;
  11386         break;
  11387     case BCM_TIME_CAPTURE_GPIO_3:
  11388         time_capture_input->input_event = _bcmTimeCaptureEventGPIO3;
  11389         break;
  11390     case BCM_TIME_CAPTURE_GPIO_4:
  11391         time_capture_input->input_event = _bcmTimeCaptureEventGPIO4;
  11392         break;
  11393     case BCM_TIME_CAPTURE_GPIO_5:
  11394         time_capture_input->input_event = _bcmTimeCaptureEventGPIO5;
  11395         break;
  11396     case BCM_TIME_CAPTURE_LCPLL:
  11397         time_capture_input->input_event = _bcmTimeCaptureEventLCPLL0;
  11398         break;
  11399     case BCM_TIME_CAPTURE_IP_DM_0:
  11400         time_capture_input->input_event = _bcmTimeCaptureEventIPDM0;
  11401         break;
  11402     case BCM_TIME_CAPTURE_IP_DM_1:
  11403         time_capture_input->input_event = _bcmTimeCaptureEventIPDM1;
  11404         break;
  11405     case BCM_TIME_CAPTURE_BS0HB:
  11406         time_capture_input->input_event = _bcmTimeCaptureEventBS0HB;
  11407         break;
  11408     case BCM_TIME_CAPTURE_BS1HB:
  11409         time_capture_input->input_event = _bcmTimeCaptureEventBS1HB;
  11410         break;
  11411     case BCM_TIME_CAPTURE_TS1TS:
  11412         time_capture_input->input_event = _bcmTimeCaptureEventTS1TS;
  11413         break;
  11414     case BCM_TIME_CAPTURE_BS0PLL:
  11415         time_capture_input->input_event = _bcmTimeCaptureEventBS0PLL;
  11416         break;
  11417     case BCM_TIME_CAPTURE_BS1PLL:
  11418         time_capture_input->input_event = _bcmTimeCaptureEventBS1PLL;
  11419         break;
  11420     case BCM_TIME_CAPTURE_RSVD1IF:
  11421         if (SOC_IS_TOMAHAWK3(unit)){
  11422             bsl_printf("Unable to find mapping for flag set in time_capture\n");
  11423             return BCM_E_NOT_FOUND;
  11424         } else if (SOC_IS_MONTEREY(unit)){
  11425             time_capture_input->input_event = _bcmTimeCaptureEventRSVD1IF;
  11426         }
  11427         break;
  11428     case BCM_TIME_CAPTURE_RSVD1RF:
  11429         if (SOC_IS_TOMAHAWK3(unit)){
  11430             bsl_printf("Unable to find mapping for flag set in time_capture\n");
  11431             return BCM_E_NOT_FOUND;
  11432         } else if (SOC_IS_MONTEREY(unit)){
  11433             time_capture_input->input_event = _bcmTimeCaptureEventRSVD1RF;
  11434         }
  11435         break;
  11436     case BCM_TIME_CAPTURE_BS0CONVTC:
  11437         time_capture_input->input_event = _bcmTimeCaptureEventBS0ConvTC;
  11438         break;
  11439     case BCM_TIME_CAPTURE_BS1CONVTC:
  11440         time_capture_input->input_event = _bcmTimeCaptureEventBS1ConvTC;
  11441         break;
  11442     case BCM_TIME_CAPTURE_LCPLL1:
  11443         time_capture_input->input_event = _bcmTimeCaptureEventLCPLL1;
  11444         break;
  11445     case BCM_TIME_CAPTURE_LCPLL2:
  11446         time_capture_input->input_event = _bcmTimeCaptureEventLCPLL2;
  11447         break;
  11448     case BCM_TIME_CAPTURE_LCPLL3:
  11449         time_capture_input->input_event = _bcmTimeCaptureEventLCPLL3;
  11450         break;
  11451     case BCM_TIME_CAPTURE_PORT:
  11452         if (SOC_IS_TOMAHAWK3(unit)){
  11453             bsl_printf("Unable to find mapping for flag set in time_capture\n");
  11454             return BCM_E_NOT_FOUND;
  11455         } else if (SOC_IS_MONTEREY(unit)){
  11456             time_capture_input->input_event = _bcmTimeCaptureEventPORT;
  11457         }
  11458         break;
  11459     }
  11460     return BCM_E_NONE;
  11461 }
  11462 
  11463 
  11464 STATIC int _bcm_esw_time_portmap_get(int unit, bcm_port_t port, int *pTimePort)
  11465 {
  11466     int rv  = BCM_E_NONE;
  11467 
  11468     /* Following is the mapping in Monterey */
  11469     if ((port >= 1) && (port <= BCM_TIME_CAPTURE_NUM_PORTS)) {
  11470         *pTimePort = port - 1;
  11471     } else {
  11472         LOG_ERROR(BSL_LS_SOC_COMMON,
  11473               (BSL_META_U(unit,
  11474                   "_bcm_esw_time_portmap_get: Error !! Invalid port\n")));
  11475         *pTimePort = BCM_TIME_CAPTURE_NUM_PORTS;
  11476         rv = BCM_E_PARAM;
  11477     }
  11478 
  11479     return rv;
  11480 }
  11481 
  11482 STATIC int
  11483 _bcm_esw_time_input_eventId_get(int unit,
  11484                     _bcm_time_capture_input_t *pInputEvent,
  11485                     uint32 *pEventId)
  11486 {
  11487     int rv  = BCM_E_NONE;
  11488     int idx = 0;
  11489 
  11490     if ((pEventId==NULL) ||
  11491         (pInputEvent->input_event < _bcmTimeCaptureEventCpu) ||
  11492         (pInputEvent->input_event >= _bcmTimeCaptureEventMax)) {
  11493          LOG_ERROR(BSL_LS_SOC_COMMON,
  11494                   (BSL_META_U(unit,
  11495                       "input_eventId_get: Error !! Wrong event\n")));
  11496         rv = BCM_E_PARAM;
  11497         goto exit;
  11498     }
  11499 
  11500     /* EventId 0 to 191 for port events,
  11501      * EventId 192 to 213 for EventCpu to EventLCPLL3
  11502      * EventId 214 for R5
  11503      */
  11504     switch ((int)pInputEvent->input_event) {
  11505         case _bcmTimeCaptureEventPORT:
  11506             if (pInputEvent->port < 0 || pInputEvent->port > BCM_TIME_CAPTURE_NUM_PORTS){
  11507                 LOG_ERROR(BSL_LS_SOC_COMMON,
  11508                   (BSL_META_U(unit,
  11509                       "input_eventId_get: Error !! Wrong port\n")));
  11510                 rv = BCM_E_PARAM;
  11511                 goto exit;
  11512             }
  11513 
  11514             if ((pInputEvent->port_event_type == bcmTimePortEventRXCDR) ||
  11515                 (pInputEvent->port_event_type == bcmTimePortEventRXSOF)){
  11516                 /* Event could be TXSOF or TXPI based on port type */
  11517                 idx = pInputEvent->port*2;
  11518             } else if (pInputEvent->port_event_type == bcmTimePortEventROE) {
  11519                 idx = pInputEvent->port*2 + 1;
  11520             } else if ((pInputEvent->port_event_type == bcmTimePortEventTXSOF) ||
  11521                        (pInputEvent->port_event_type == bcmTimePortEventTXPI)){
  11522                 /* Event could be TXSOF or TXPI based on port type */
  11523                 idx = BCM_TIME_CAPTURE_IA_START_TXPI_TXSOF + pInputEvent->port;
  11524             } else {
  11525                 LOG_ERROR(BSL_LS_SOC_COMMON,
  11526                   (BSL_META_U(unit,
  11527                       "input_eventId_get: Error !! Wrong param\n")));
  11528                 rv = BCM_E_PARAM;
  11529                 goto exit;
  11530             }
  11531             break;
  11532 
  11533         case _bcmTimeCaptureEventR5:
  11534             idx = BCM_TIME_CAPTURE_IA_START_R5;
  11535             break;
  11536 
  11537         default:
  11538             idx = BCM_TIME_CAPTURE_IA_START_MISC + pInputEvent->input_event;
  11539     }
  11540 
  11541     *pEventId = idx;
  11542 
  11543 exit:
  11544     return rv;
  11545 }
  11546 
  11547 STATIC int
  11548 _bcm_esw_time_event_divisor_misc_set(int unit, _bcm_time_capture_event_t event_misc,
  11549                             uint32 divisor)
  11550 {
  11551     int rv  = BCM_E_NONE;
  11552     int idx = 0;
  11553     uint32 regVal = 0;
  11554 
  11555     switch (event_misc) {
  11556         case _bcmTimeCaptureEventCpu:
  11557         case _bcmTimeCaptureEventBS0HB:
  11558         case _bcmTimeCaptureEventBS1HB:
  11559         case _bcmTimeCaptureEventIPDM0:
  11560         case _bcmTimeCaptureEventIPDM1:
  11561         case _bcmTimeCaptureEventTS1TS:
  11562         case _bcmTimeCaptureEventRSVD1IF:
  11563         case _bcmTimeCaptureEventRSVD1RF:
  11564         case _bcmTimeCaptureEventBS0ConvTC:
  11565         case _bcmTimeCaptureEventBS1ConvTC:
  11566             /* No divider */
  11567             bsl_printf("BCM_TIME: event_divisor_misc_set: No divider for event:%d \n", event_misc);
  11568             break;
  11569 
  11570         case _bcmTimeCaptureEventGPIO0:
  11571         case _bcmTimeCaptureEventGPIO1:
  11572         case _bcmTimeCaptureEventGPIO2:
  11573         case _bcmTimeCaptureEventGPIO3:
  11574         case _bcmTimeCaptureEventGPIO4:
  11575         case _bcmTimeCaptureEventGPIO5:
  11576             idx = event_misc - _bcmTimeCaptureEventGPIO0;
  11577             BCM_TIME_READ_NS_REGr(unit, _bcm_time_gpio_regs[idx], 0, &regVal);
  11578             soc_reg_field_set(unit,  _bcm_time_gpio_regs[idx], &regVal,
  11579                               DIVISORf, divisor);
  11580             BCM_TIME_WRITE_NS_REGr(unit, _bcm_time_gpio_regs[idx], 0, regVal);
  11581             break;
  11582 
  11583         case _bcmTimeCaptureEventBS0PLL:
  11584         case _bcmTimeCaptureEventBS1PLL:
  11585             idx = event_misc - _bcmTimeCaptureEventBS0PLL;
  11586             BCM_TIME_READ_NS_REGr(unit, _bcm_time_bs_pll_regs[idx], 0, &regVal);
  11587             soc_reg_field_set(unit, _bcm_time_bs_pll_regs[idx], &regVal,
  11588                               DIVISORf, divisor);
  11589             BCM_TIME_WRITE_NS_REGr(unit, _bcm_time_bs_pll_regs[idx], 0, regVal);
  11590             break;
  11591 
  11592         case _bcmTimeCaptureEventLCPLL0:
  11593         case _bcmTimeCaptureEventLCPLL1:
  11594         case _bcmTimeCaptureEventLCPLL2:
  11595         case _bcmTimeCaptureEventLCPLL3:
  11596             idx = event_misc - _bcmTimeCaptureEventLCPLL0;
  11597             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, idx, &regVal);
  11598             soc_reg_field_set(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, &regVal,
  11599                               DIVISORf, divisor);
  11600             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, idx, regVal);
  11601             break;
  11602 
  11603         default:
  11604            LOG_ERROR(BSL_LS_SOC_COMMON,
  11605                   (BSL_META_U(unit,
  11606                       "event_divisor_misc_set: Error !! wrong param\n")));
  11607            rv = BCM_E_PARAM;
  11608            goto exit;
  11609     }
  11610 
  11611 exit:
  11612     return (rv);
  11613 }
  11614 
  11615 STATIC int
  11616 _bcm_esw_time_event_dest_misc_set(int unit, _bcm_time_capture_event_t event_misc,
  11617                             _bcm_time_capture_dest_cfg_t *pEventDest,
  11618                             uint32 eventId)
  11619 {
  11620     int rv  = BCM_E_NONE;
  11621     int idx = 0;
  11622     uint32 regVal = 0;
  11623     uint32 dest;
  11624     uint32 chkProfile;
  11625 
  11626     if (event_misc < _bcmTimeCaptureEventCpu ||
  11627         event_misc > _bcmTimeCaptureEventLCPLL3) {
  11628         LOG_ERROR(BSL_LS_SOC_COMMON,
  11629               (BSL_META_U(unit,
  11630                   "event_dest_misc_set: Error !! Wrong param\n")));
  11631         rv = BCM_E_PARAM;
  11632         goto exit;
  11633     }
  11634 
  11635     /* Since we have 150 numels of NS_TIMESYNC_TS_EVENT_FWD_CFG,
  11636      * the miscellaneous events starts from index 128 per table 6.4 in uArch
  11637      */
  11638     idx = 128 + event_misc;
  11639 
  11640     if (pEventDest->event_dest == _bcmTimeCaptureDestCPU) {
  11641         dest = 0;
  11642     }else if (pEventDest->event_dest == _bcmTimeCaptureDestM7) {
  11643         dest = 1;
  11644     }else if (pEventDest->event_dest == _bcmTimeCaptureDestALL) {
  11645         dest = 2;
  11646     }else {
  11647         LOG_ERROR(BSL_LS_SOC_COMMON,
  11648               (BSL_META_U(unit,
  11649                   "event_dest_misc_set: Error !! wrong event dest\n")));
  11650         rv = BCM_E_PARAM;
  11651         goto exit;
  11652     }
  11653 
  11654     
  11655     chkProfile = 0;
  11656 
  11657     BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, &regVal);
  11658 
  11659     soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11660                               EVENT_IDf, eventId);
  11661 
  11662     dest |= soc_reg_field_get(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr,
  11663                             regVal, DESTf);
  11664     soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11665                               DESTf, dest);
  11666     /*soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11667                               DPLL_ADDRf, *eventId);*/
  11668     soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11669                               GDPLL_TSf, pEventDest->ts_counter ? 1:0);
  11670     soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11671                               PPM_CHECK_ENABLEf, pEventDest->ppm_check_enable ? 1:0);
  11672     soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11673                               SRC_TS_COUNTERf, pEventDest->ts_counter ? 1:0);
  11674     soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11675                               CHK_PROFILEf, chkProfile);
  11676     BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, regVal);
  11677 
  11678 exit:
  11679     return (rv);
  11680 }
  11681 
  11682 STATIC int
  11683 _bcm_esw_time_event_divisor_port_set(int unit, bcm_port_t port,
  11684     bcm_time_port_event_t port_event_type, uint32 divisor)
  11685 {
  11686     int rv  = BCM_E_NONE;
  11687     int idx = 0;
  11688     uint32 regVal = 0;
  11689 
  11690     if (port > BCM_TIME_CAPTURE_NUM_PORTS) {
  11691         LOG_ERROR(BSL_LS_SOC_COMMON,
  11692                   (BSL_META_U(unit,
  11693                       "event_divisor_port_set: Error !! wrong port \n")));
  11694         rv = BCM_E_PARAM;
  11695         goto exit;
  11696     }
  11697 
  11698     idx = port;
  11699     switch (port_event_type) {
  11700         case bcmTimePortEventRXSOF:
  11701         case bcmTimePortEventTXSOF:
  11702         case bcmTimePortEventROE:
  11703             LOG_ERROR(BSL_LS_SOC_COMMON,
  11704                   (BSL_META_U(unit,
  11705                       "event_divisor_port_set: Error !! No divisor\n")));
  11706             rv = BCM_E_UNAVAIL;
  11707             break;
  11708 
  11709         case bcmTimePortEventRXCDR:
  11710             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, idx, &regVal);
  11711             soc_reg_field_set(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, &regVal,
  11712                               DIVISORf, divisor);
  11713             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, idx, regVal);
  11714             break;
  11715 
  11716         case bcmTimePortEventTXPI:
  11717             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, idx, &regVal);
  11718             soc_reg_field_set(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, &regVal,
  11719                               DIVISORf, divisor);
  11720             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, idx, regVal);
  11721             break;
  11722 
  11723         default:
  11724            LOG_ERROR(BSL_LS_SOC_COMMON,
  11725                   (BSL_META_U(unit,
  11726                       "event_divisor_port_set: Error !! Wrong param\n")));
  11727            rv = BCM_E_PARAM;
  11728     }
  11729 
  11730 exit:
  11731     return (rv);
  11732 }
  11733 
  11734 STATIC int
  11735 _bcm_esw_time_event_dest_port_set (int unit, bcm_port_t port,
  11736                 bcm_time_port_event_t port_event_type,
  11737                 _bcm_time_capture_dest_cfg_t *pEventDest,
  11738                 uint32 eventId)
  11739 {
  11740     int rv  = BCM_E_NONE;
  11741     int idx = 0;
  11742     uint32 regVal = 0;
  11743     uint32 dest;
  11744     uint32 chkProfile;
  11745 
  11746     if (port >= BCM_TIME_CAPTURE_NUM_PORTS) {
  11747         LOG_ERROR(BSL_LS_SOC_COMMON,
  11748               (BSL_META_U(unit,
  11749                   "event_dest_port_set: Error !! wrong param\n")));
  11750         rv = BCM_E_PARAM;
  11751         goto exit;
  11752     }
  11753 
  11754 
  11755     if (pEventDest->event_dest == _bcmTimeCaptureDestCPU) {
  11756         dest = 0;
  11757     }else if (pEventDest->event_dest == _bcmTimeCaptureDestM7) {
  11758         dest = 1;
  11759     }else if (pEventDest->event_dest == _bcmTimeCaptureDestALL) {
  11760         dest = 2;
  11761     }else {
  11762         LOG_ERROR(BSL_LS_SOC_COMMON,
  11763               (BSL_META_U(unit,
  11764                   "event_dest_port_set: Error !! wrong event dest\n")));
  11765         rv = BCM_E_PARAM;
  11766         goto exit;
  11767     }
  11768 
  11769     
  11770     chkProfile = 0;
  11771 
  11772     switch(port_event_type) {
  11773         case bcmTimePortEventRXCDR:
  11774         case bcmTimePortEventTXPI:
  11775             if (port_event_type == bcmTimePortEventRXCDR){
  11776                 idx = port;
  11777             }else if (port_event_type == bcmTimePortEventTXPI) {
  11778                 idx = port + BCM_TIME_CAPTURE_NUM_PORTS;
  11779             }
  11780 
  11781             bsl_printf("BCM_TIME: Setting NS_TIMESYNC_TS_EVENT_FWD_CFG idx:%d\n",
  11782                         idx);
  11783 
  11784             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, &regVal);
  11785             soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11786                               EVENT_IDf, eventId);
  11787             dest |= soc_reg_field_get(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr,
  11788                                     regVal, DESTf);
  11789             soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11790                               DESTf, dest);
  11791             /*soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11792                               DPLL_ADDRf, *pIaAddr);*/
  11793             soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11794                               GDPLL_TSf, pEventDest->ts_counter ? 1:0);
  11795             soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11796                               PPM_CHECK_ENABLEf, pEventDest->ppm_check_enable ? 1:0);
  11797             soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11798                               SRC_TS_COUNTERf, pEventDest->ts_counter ? 1:0);
  11799             soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, &regVal,
  11800                               CHK_PROFILEf, chkProfile);
  11801             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, regVal);
  11802 
  11803             break;
  11804 
  11805         case bcmTimePortEventRXSOF:    /* Type-0 */
  11806         case bcmTimePortEventTXSOF:    /* Type-1 */
  11807         case bcmTimePortEventROE:      /* Type-2 */
  11808             /*
  11809              * Having 128 Numels, register map is
  11810              * Port-0: type-0, type-1, type-2, unused
  11811              * Port-1: type-0, type-1, type-2, unused
  11812              */
  11813             if ((port >= BCM_TIME_CAPTURE_NUM_CPRI_PORTS) || (port < 0)) {
  11814                 LOG_ERROR(BSL_LS_SOC_COMMON,
  11815                     (BSL_META_U(unit,
  11816                       "event_dest_port_set: Error !! Invalid CPRI port\n")));
  11817                 rv = BCM_E_PARAM;
  11818                 goto exit;
  11819             }
  11820 
  11821             idx = port*4;
  11822             if (port_event_type == bcmTimePortEventTXSOF) {
  11823                 idx = idx + 1;
  11824             }else if (port_event_type == bcmTimePortEventROE) {
  11825                 idx = idx + 2;
  11826             }
  11827 
  11828             bsl_printf("BCM_TIME: Setting NS_TIMESYNC_MAPPER_FWD_CFG idx:%d\n",
  11829                         idx);
  11830             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, idx, &regVal);
  11831             soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, &regVal,
  11832                               EVENT_IDf, eventId);
  11833             dest |= soc_reg_field_get(unit, NS_TIMESYNC_MAPPER_FWD_CFGr,
  11834                                     regVal, DESTf);
  11835             soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, &regVal,
  11836                               DESTf, dest);
  11837             /*soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, &regVal,
  11838                               DPLL_ADDRf, *pIaAddr);*/
  11839             soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, &regVal,
  11840                               PPM_CHECK_ENABLEf, pEventDest->ppm_check_enable ? 1:0);
  11841             soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, &regVal,
  11842                               SRC_TS_COUNTERf, 1);  /* It is TS1 counter */
  11843             soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, &regVal,
  11844                               CHK_PROFILEf, chkProfile);
  11845             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, idx, regVal);
  11846             break;
  11847 
  11848         default:
  11849             LOG_ERROR(BSL_LS_SOC_COMMON,
  11850                     (BSL_META_U(unit,
  11851                       "event_dest_port_set: Error !! wrong event\n")));
  11852             rv = BCM_E_PARAM;
  11853             goto exit;
  11854     }
  11855 
  11856 exit:
  11857     return (rv);
  11858 }
  11859 
  11860 STATIC int
  11861 _bcm_esw_time_event_roe_52b_set(int unit, bcm_port_t port, int enable)
  11862 {
  11863     int rv = BCM_E_NONE;
  11864     uint32 enable_field = 0;
  11865     uint32 regVal = 0;
  11866     uint32 reg_enable = 0;
  11867 
  11868     /* Program NS_TIMESYNC_MAPPER_TYPE2_FORMAT */
  11869 
  11870     enable_field = 1 << port;
  11871 
  11872     BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_MAPPER_TYPE2_FORMATr, port, &regVal);
  11873     reg_enable = soc_reg_field_get(unit, NS_TIMESYNC_MAPPER_TYPE2_FORMATr, regVal, CONV_ENf);
  11874 
  11875     reg_enable = enable ? (reg_enable | enable_field) : (reg_enable & (~enable_field));
  11876 
  11877     soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_TYPE2_FORMATr, &regVal, CONV_ENf, reg_enable);
  11878     BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_MAPPER_TYPE2_FORMATr, port, regVal);
  11879 
  11880     return (rv);
  11881 }
  11882 
  11883 STATIC int
  11884 _bcm_esw_time_capture_enable_misc_set(int unit, _bcm_time_capture_event_t  event_misc,
  11885                                int enable)
  11886 {
  11887     int rv = BCM_E_NONE;
  11888     uint32 idx = 0;
  11889     uint32 enable_field = 0;
  11890     uint32 regVal = 0;
  11891     uint32 reg_enable;
  11892 
  11893     /*
  11894     NS_MISC_CLK_EVENT_CTRL
  11895     NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRL
  11896     NS_BROADSYNC0_CLK_EVENT_CTRL
  11897     NS_BROADSYNC1_CLK_EVENT_CTRL
  11898     NS_TIMESYNC_GPIO_x_CTRL
  11899      */
  11900     switch (event_misc){
  11901         case _bcmTimeCaptureEventCpu:
  11902             if (event_misc == _bcmTimeCaptureEventCpu) {
  11903                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_CPU;
  11904             }
  11905         case _bcmTimeCaptureEventBS0HB:
  11906             if (event_misc == _bcmTimeCaptureEventBS0HB) {
  11907                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_BS0HB;
  11908             }
  11909         case _bcmTimeCaptureEventBS1HB:
  11910             if (event_misc == _bcmTimeCaptureEventBS1HB) {
  11911                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_BS1HB;
  11912             }
  11913         case _bcmTimeCaptureEventIPDM0:
  11914             if (event_misc == _bcmTimeCaptureEventIPDM0) {
  11915                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_IPDM0;
  11916             }
  11917         case _bcmTimeCaptureEventIPDM1:
  11918             if (event_misc == _bcmTimeCaptureEventIPDM1) {
  11919                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_IPDM1;
  11920             }
  11921         case _bcmTimeCaptureEventTS1TS:
  11922             if (event_misc == _bcmTimeCaptureEventTS1TS) {
  11923                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_TS1;
  11924             }
  11925         case _bcmTimeCaptureEventRSVD1IF:
  11926             if (event_misc == _bcmTimeCaptureEventRSVD1IF) {
  11927                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_RSVD1IF;
  11928             }
  11929         case _bcmTimeCaptureEventRSVD1RF:
  11930             if (event_misc == _bcmTimeCaptureEventRSVD1RF) {
  11931                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_RSVD1RF;
  11932             }
  11933         case _bcmTimeCaptureEventBS0ConvTC:
  11934             if (event_misc == _bcmTimeCaptureEventBS0ConvTC) {
  11935                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_BS0CONV;
  11936             }
  11937         case _bcmTimeCaptureEventBS1ConvTC:
  11938             if (event_misc == _bcmTimeCaptureEventBS1ConvTC) {
  11939                 enable_field = BCM_TIME_CAPTURE_MISC_EVENT_EN_BS1CONV;
  11940             }
  11941 
  11942             /* Write the enable flag */
  11943             BCM_TIME_READ_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, &regVal);
  11944             reg_enable = soc_reg_field_get(unit, NS_MISC_CLK_EVENT_CTRLr, regVal, ENABLEf);
  11945 
  11946             reg_enable = enable ? (reg_enable | enable_field) : (reg_enable & (~enable_field));
  11947 
  11948             soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regVal,
  11949                               ENABLEf, reg_enable);
  11950             BCM_TIME_WRITE_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, regVal);
  11951             break;
  11952 
  11953         case _bcmTimeCaptureEventGPIO0:
  11954         case _bcmTimeCaptureEventGPIO1:
  11955         case _bcmTimeCaptureEventGPIO2:
  11956         case _bcmTimeCaptureEventGPIO3:
  11957         case _bcmTimeCaptureEventGPIO4:
  11958         case _bcmTimeCaptureEventGPIO5:
  11959             idx = event_misc - _bcmTimeCaptureEventGPIO0;
  11960             BCM_TIME_READ_NS_REGr(unit, _bcm_time_gpio_regs[idx], 0, &regVal);
  11961 #ifndef INCLUDE_GDPLL
  11962             soc_reg_field_set(unit,  _bcm_time_gpio_regs[idx], &regVal,
  11963                                CAPTURE_ENABLEf, enable ? 1:0);
  11964 #endif
  11965             BCM_TIME_WRITE_NS_REGr(unit, _bcm_time_gpio_regs[idx], 0, regVal);
  11966             break;
  11967 
  11968         case _bcmTimeCaptureEventBS0PLL:
  11969         case _bcmTimeCaptureEventBS1PLL:
  11970             idx = event_misc - _bcmTimeCaptureEventBS0PLL;
  11971             BCM_TIME_READ_NS_REGr(unit, _bcm_time_bs_pll_regs[idx], 0, &regVal);
  11972             soc_reg_field_set(unit, _bcm_time_bs_pll_regs[idx], &regVal,
  11973                               ENABLEf, enable ? 1:0);
  11974             BCM_TIME_WRITE_NS_REGr(unit, _bcm_time_bs_pll_regs[idx], 0, regVal);
  11975             break;
  11976 
  11977         case _bcmTimeCaptureEventLCPLL0:
  11978         case _bcmTimeCaptureEventLCPLL1:
  11979         case _bcmTimeCaptureEventLCPLL2:
  11980         case _bcmTimeCaptureEventLCPLL3:
  11981             idx = event_misc - _bcmTimeCaptureEventLCPLL0;
  11982             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, idx, &regVal);
  11983             soc_reg_field_set(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, &regVal,
  11984                               ENABLEf, enable ? 1:0);
  11985             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, idx, regVal);
  11986             break;
  11987 
  11988         case _bcmTimeCaptureEventPORT:
  11989         default:
  11990             LOG_ERROR(BSL_LS_SOC_COMMON,
  11991                     (BSL_META_U(unit,
  11992                       "event_enable_misc_set: Error !! wrong event\n")));
  11993             rv = BCM_E_PARAM;
  11994             goto exit;
  11995     }
  11996 
  11997 exit:
  11998     return (rv);
  11999 }
  12000 
  12001 STATIC int
  12002 _bcm_esw_time_capture_enable_port_set(int unit, bcm_port_t port, bcm_time_port_event_t port_event_type,
  12003                                  int enable)
  12004 {
  12005     int rv = BCM_E_NONE;
  12006     uint32 mapper_reg;
  12007     uint32 regVal = 0;
  12008     uint32 enable_field = 0;
  12009     uint32 reg_enable = 0;
  12010 
  12011     if (port >= BCM_TIME_CAPTURE_NUM_PORTS) {
  12012         LOG_ERROR(BSL_LS_SOC_COMMON,
  12013                 (BSL_META_U(unit,
  12014                       "event_enable_port_set: Error !! wrong port\n")));
  12015         rv = BCM_E_PARAM;
  12016         goto exit;
  12017     }
  12018 
  12019     switch (port_event_type) {
  12020         case bcmTimePortEventRXSOF:
  12021         case bcmTimePortEventTXSOF:
  12022         case bcmTimePortEventROE:
  12023             /* NS has support to 32 CPRI ports */
  12024             if ((port >= BCM_TIME_CAPTURE_NUM_CPRI_PORTS) || (port < 0)) {
  12025                 LOG_ERROR(BSL_LS_SOC_COMMON,
  12026                     (BSL_META_U(unit,
  12027                       "event_enable_port_set: Error !! wrong port or non-cpri\n")));
  12028                 rv = BCM_E_PARAM;
  12029                 goto exit;
  12030             }
  12031 
  12032             /* Program NS_TIMESYNC_MAPPER_PORT_ENABLE_x */
  12033             enable_field = 1 << (port_event_type - bcmTimePortEventRXSOF);
  12034             mapper_reg = port/8;
  12035 
  12036             BCM_TIME_READ_NS_REGr(unit, __bcm_time_mapper_port_enable_regs[mapper_reg], 0, &regVal);
  12037             reg_enable = soc_reg_field_get(unit, __bcm_time_mapper_port_enable_regs[mapper_reg], regVal, _bcm_time_mapper_port_enable[port]);
  12038 
  12039             reg_enable = enable ? (reg_enable | enable_field) : (reg_enable & (~enable_field));
  12040 
  12041             soc_reg_field_set(unit, __bcm_time_mapper_port_enable_regs[mapper_reg], &regVal, _bcm_time_mapper_port_enable[port], reg_enable);
  12042             BCM_TIME_WRITE_NS_REGr(unit, __bcm_time_mapper_port_enable_regs[mapper_reg], 0, regVal);
  12043 
  12044             break;
  12045 
  12046         case bcmTimePortEventRXCDR:
  12047             /* Program NS_TIMESYNC_RX_CDR_EVENT_CTRL */
  12048             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, port, &regVal);
  12049             soc_reg_field_set(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, &regVal, ENABLEf, enable ? 1:0);
  12050             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, port, regVal);
  12051             break;
  12052 
  12053         case bcmTimePortEventTXPI:
  12054             /* Program NS_TIMESYNC_TX_PI_CLK_EVENT_CTRL */
  12055             BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, port, &regVal);
  12056             soc_reg_field_set(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, &regVal, ENABLEf, enable ? 1:0);
  12057             BCM_TIME_WRITE_NS_REGr(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, port, regVal);
  12058             break;
  12059 
  12060         default:
  12061             LOG_ERROR(BSL_LS_SOC_COMMON,
  12062                 (BSL_META_U(unit,
  12063                       "event_enable_port_set: Error !! wrong port event\n")));
  12064             rv = BCM_E_PARAM;
  12065           goto exit;
  12066     }
  12067 
  12068 exit:
  12069     return (rv);
  12070 }
  12071 
  12072 STATIC int
  12073 _bcm_esw_time_capture_enable_cpu_set(int unit, int enable)
  12074 {
  12075     int rv = BCM_E_NONE;
  12076     uint32 regVal = 0;
  12077 
  12078     BCM_TIME_READ_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, &regVal);
  12079     soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, &regVal, TIME_CAPTURE_ENABLEf, enable ? 1:0);
  12080     BCM_TIME_WRITE_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, regVal);
  12081 
  12082     return (rv);
  12083 }
  12084 
  12085 STATIC int
  12086 bcm_esw_time_capture_enable(int unit, _bcm_time_capture_input_t event_misc, int enable)
  12087 {
  12088     int rv = BCM_E_NONE;
  12089 
  12090     bsl_printf("BCM TIME: Set enable for time capture event\n");
  12091     if (event_misc.input_event == _bcmTimeCaptureEventPORT) {
  12092         _bcm_esw_time_capture_enable_port_set(unit, event_misc.port, event_misc.port_event_type, enable);
  12093     } else {
  12094         _bcm_esw_time_capture_enable_misc_set(unit, event_misc.input_event, enable);
  12095     }
  12096 
  12097     _bcm_esw_time_capture_enable_cpu_set(unit,enable);
  12098     return (rv);
  12099 }
  12100 
  12101 STATIC int
  12102 _bcm_esw_time_event_config_set(int unit, _bcm_time_capture_input_t *pTimeCapture, uint32 eventId)
  12103 {
  12104     int rv = BCM_E_NONE;
  12105     _bcm_time_capture_dest_cfg_t eventDest;
  12106 
  12107     /* Configure the event */
  12108     eventDest.event_dest = pTimeCapture->event_dest;
  12109     eventDest.ts_counter = pTimeCapture->ts_counter;
  12110     eventDest.ppm_check_enable = pTimeCapture->ppm_check_enable;
  12111 
  12112     if ((pTimeCapture->input_event >= _bcmTimeCaptureEventCpu) &&
  12113         (pTimeCapture->input_event <= _bcmTimeCaptureEventLCPLL3)) {
  12114         BCM_IF_ERROR_RETURN(_bcm_esw_time_event_divisor_misc_set(unit,
  12115                             pTimeCapture->input_event,
  12116                             pTimeCapture->event_divisor));
  12117         BCM_IF_ERROR_RETURN(_bcm_esw_time_event_dest_misc_set(unit,
  12118                             pTimeCapture->input_event,
  12119                             &eventDest, eventId));
  12120 
  12121     } else if(pTimeCapture->input_event == _bcmTimeCaptureEventPORT) {
  12122         if ((pTimeCapture->port_event_type == bcmTimePortEventRXCDR) ||
  12123             (pTimeCapture->port_event_type == bcmTimePortEventTXPI)) {
  12124             BCM_IF_ERROR_RETURN(_bcm_esw_time_event_divisor_port_set(unit,
  12125                             pTimeCapture->port, pTimeCapture->port_event_type,
  12126                             pTimeCapture->event_divisor));
  12127         }
  12128         BCM_IF_ERROR_RETURN(_bcm_esw_time_event_dest_port_set(unit, pTimeCapture->port,
  12129                             pTimeCapture->port_event_type,
  12130                             &eventDest, eventId));
  12131 
  12132         /* ROE event, disable the 52b conversion SWIPROC-591 */
  12133         if (pTimeCapture->port_event_type == bcmTimePortEventROE)
  12134             BCM_IF_ERROR_RETURN(_bcm_esw_time_event_roe_52b_set(unit,
  12135                             pTimeCapture->port, 0));
  12136 
  12137     } /*else if(pTimeCapture->input_event == _bcmTimeCaptureEventR5) {*/
  12138         
  12139          /*pIaAddr = 214;
  12140     } */else {
  12141         LOG_ERROR(BSL_LS_SOC_COMMON,
  12142                 (BSL_META_U(unit,
  12143                       "event_config_set: Error !! invalid input event\n")));
  12144         rv = BCM_E_PARAM;
  12145     }
  12146 
  12147     return (rv);
  12148 }
  12149 
  12150 #endif /* BCM_MONTEREY_SUPPORT  || defined(BCM_TOMAHAWK3_SUPPORT)*/
  12151 
  12152 int bcm_esw_time_capture_enable_set(
  12153         int unit,
  12154         bcm_time_if_t id,
  12155         bcm_time_capture_t *time_capture,
  12156         int enable,
  12157         int *capture_handle)
  12158 {
  12159     int rv = BCM_E_UNAVAIL;
  12160 
  12161 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12162     _bcm_time_capture_input_t time_capture_input;
  12163     int ts_port;
  12164     uint32 eventId = BCM_TIME_CAPTURE_HANDLE_INVALID;
  12165 
  12166     if (_bcm_esw_get_event_config_from_time_capture(unit,
  12167             time_capture,
  12168             &time_capture_input) != BCM_E_NONE) {
  12169         rv = BCM_E_INTERNAL;
  12170         goto exit;
  12171     }
  12172 
  12173     if (time_capture_input.input_event == _bcmTimeCaptureEventPORT) {
  12174         _bcm_esw_time_portmap_get(unit, time_capture_input.port, &ts_port);
  12175         time_capture_input.port = ts_port;
  12176     }
  12177 
  12178     if (_bcm_esw_time_input_eventId_get(unit,
  12179             &time_capture_input,
  12180             &eventId) != BCM_E_NONE) {
  12181         rv = BCM_E_INTERNAL;
  12182         goto exit;
  12183     }
  12184 
  12185     if (eventId >= BCM_TIME_CAPTURE_MAX_EVENT_ID){
  12186         bsl_printf("BCM TIME: Internal error. Invalid capture_handle: %d", eventId);
  12187         rv = BCM_E_INTERNAL;
  12188         goto exit;
  12189     }
  12190 
  12191     if (_bcm_time_capture_event_state[eventId] == BCM_TIME_CAPTURE_EVENT_STATE_NOT_IN_USE &&
  12192             enable == 0) {
  12193         bsl_printf("BCM_TIME: Error! Trying to disable a capture handle that is not enabled");
  12194         rv = BCM_E_PARAM;
  12195         goto exit;
  12196     } else if (_bcm_time_capture_event_state[eventId] == BCM_TIME_CAPTURE_EVENT_STATE_IN_USE &&
  12197             enable == 1) {
  12198         bsl_printf("BCM_TIME: Error! Trying to enable a capture handle that is in use");
  12199         rv = BCM_E_PARAM;
  12200         goto exit;
  12201     }
  12202 
  12203     _bcm_time_capture_event_state[eventId] = (enable)?BCM_TIME_CAPTURE_EVENT_STATE_IN_USE:BCM_TIME_CAPTURE_EVENT_STATE_NOT_IN_USE;
  12204 
  12205     bsl_printf("Capture handle generated:%d\n", eventId);
  12206     /*bsl_printf("event_dest: %d, event_divisor: %d, input_event: %d, port: %d, port_event_type: %d, ppm_check_enable: %d, ts_counter: %d\n",time_capture.event_dest,
  12207             time_capture.event_divisor,
  12208             time_capture.input_event,
  12209             time_capture.port,
  12210             time_capture.port_event_type,
  12211             time_capture.ppm_check_enable,
  12212             time_capture.ts_counter);*/
  12213 
  12214     /* Configure the input event and get iaAddr_ref */
  12215     if(_bcm_esw_time_event_config_set(unit,
  12216             &time_capture_input,
  12217             eventId) != BCM_E_NONE) {
  12218         rv = BCM_E_INTERNAL;
  12219         goto exit;
  12220     }
  12221 
  12222     rv = bcm_esw_time_capture_enable(unit, time_capture_input, enable);
  12223 
  12224 exit:
  12225     *capture_handle = eventId;
  12226 #endif /*BCM_MONTEREY_SUPPORT  || defined(BCM_TOMAHAWK3_SUPPORT)*/
  12227     return (rv);
  12228 }
  12229 
  12230 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || defined (BCM_TIMESYNC_TIME_CAPTURE_SUPPORT)
  12231 typedef struct bcm_time_cb_context_s {
  12232     bcm_time_capture_cb cb;
  12233     bcm_time_capture_cb_type_t cb_type;
  12234     void    *user_data_ptr;
  12235 }bcm_time_cb_context_t;
  12236 
  12237 bcm_time_cb_context_t cb_overflow,cb_fill,cb_all;
  12238 
  12239 #endif /* #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)*/
  12240 
  12241 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12242 uint32 g_int_status = 0;  /* Interrupt status */
  12243 uint8 g_fifo_data_fill[BCM_TIME_CAPTURE_MAX_FIFO_DATA_SIZE];
  12244 uint8 g_fifo_data_overflow[2];
  12245 sal_sem_t    g_fifo_sem;
  12246 #endif /* #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) */
  12247 
  12248 
  12249 #if defined(BCM_TIMESYNC_TIME_CAPTURE_SUPPORT)
  12250 typedef struct bcm_esw_time_ts_capture_info_s {
  12251     int time_capture_ts_enable;
  12252     int time_capture_ts_active;
  12253     sal_thread_t thread_id_time_capture_ts;
  12254     sal_sem_t ts_fifo_sem;
  12255     uint32 ts_fifo_wr_index;
  12256     uint32 ts_fifo_rd_index;
  12257     uint8 ts_fifo_data_fill[BCM_TIME_TS_CAPTURE_BUF_SIZE];
  12258 } bcm_esw_time_ts_capture_info_t;
  12259 
  12260 STATIC bcm_esw_time_ts_capture_info_t *ts_capture_info[BCM_UNITS_MAX] = {0};
  12261 #endif /* BCM_TIMESYNC_TIME_CAPTURE_SUPPORT */
  12262 
  12263 
  12264 
  12265 int bcm_esw_time_capture_cb_register(
  12266         int unit,
  12267         bcm_time_if_t id,
  12268         bcm_time_capture_cb_type_t cb_type,
  12269         bcm_time_capture_cb cb,
  12270         void *user_data)
  12271 {
  12272     int rv = BCM_E_NONE;
  12273 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || defined(BCM_TIMESYNC_TIME_CAPTURE_SUPPORT)
  12274     if (cb_overflow.cb == NULL && cb_fill.cb == NULL && cb_all.cb == NULL){
  12275         /* At least one callback is registered. Enable the interrupt */
  12276 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12277         if (SOC_IS_MONTEREY(unit) || SOC_IS_TOMAHAWK3(unit)) {
  12278             BCM_TIME_WRITE_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, INTR_NS_TIME_CAPTURE);
  12279         }
  12280 #ifdef BCM_CMICX_SUPPORT
  12281         if (soc_feature(unit, soc_feature_cmicx)) {
  12282             soc_cmic_intr_enable(unit, TS_INTR);
  12283         }
  12284 #endif
  12285 #endif
  12286 #if defined (BCM_TIMESYNC_TIME_CAPTURE_SUPPORT)
  12287         if (soc_feature(unit, soc_feature_timesync_time_capture)) {
  12288             (void)soc_cmicm_intr1_enable(unit, IRQ_CMCx_TIMESYNC_INTR);
  12289         }
  12290 
  12291         if (soc_feature(unit, soc_feature_timesync_time_capture)) {
  12292             ts_capture_info[unit]->ts_fifo_rd_index = 0;
  12293             ts_capture_info[unit]->ts_fifo_wr_index = 0;
  12294             sal_memset(ts_capture_info[unit]->ts_fifo_data_fill, 0, BCM_TIME_TS_CAPTURE_BUF_SIZE);
  12295         }
  12296 #endif
  12297     }
  12298     switch (cb_type){
  12299     case bcmTimeCaptureOverflow:
  12300         if (cb_overflow.cb != NULL){
  12301             bsl_printf("BCM TIME: Error! Callback function already registered for bcmTimeCaptureOverflow");
  12302             rv = BCM_E_PARAM;
  12303             goto exit;
  12304         }
  12305         cb_overflow.cb_type = bcmTimeCaptureOverflow;
  12306         cb_overflow.cb = cb;
  12307         cb_overflow.user_data_ptr = user_data;
  12308         break;
  12309     case bcmTimeCapturetFill:
  12310         if (cb_fill.cb != NULL){
  12311             bsl_printf("BCM TIME: Error! Callback function already registered for bcmTimeCapturetFill");
  12312             rv = BCM_E_PARAM;
  12313             goto exit;
  12314         }
  12315         cb_fill.cb_type = bcmTimeCapturetFill;
  12316         cb_fill.cb = cb;
  12317         cb_fill.user_data_ptr = user_data;
  12318         break;
  12319     case bcmTimeCaptureAll:
  12320         if (cb_all.cb != NULL){
  12321             bsl_printf("BCM TIME: Error! Callback function already registered for bcmTimeCaptureAll");
  12322             rv = BCM_E_PARAM;
  12323             goto exit;
  12324         }
  12325         cb_all.cb_type = bcmTimeCaptureAll;
  12326         cb_all.cb = cb;
  12327         cb_all.user_data_ptr = user_data;
  12328         break;
  12329     }
  12330 exit:
  12331 #endif /* #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) */
  12332     return rv;
  12333 }
  12334 
  12335 
  12336 int bcm_esw_time_capture_cb_unregister(
  12337         int unit,
  12338         bcm_time_if_t id,
  12339         bcm_time_capture_cb_type_t cb_type)
  12340 {
  12341 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || defined (BCM_TIMESYNC_TIME_CAPTURE_SUPPORT)
  12342     switch (cb_type){
  12343     case bcmTimeCaptureOverflow:
  12344         cb_overflow.cb_type = bcmTimeCaptureOverflow;
  12345         cb_overflow.cb = NULL;
  12346         cb_overflow.user_data_ptr = NULL;
  12347         break;
  12348     case bcmTimeCapturetFill:
  12349         cb_fill.cb_type = bcmTimeCapturetFill;
  12350         cb_fill.cb = NULL;
  12351         cb_fill.user_data_ptr = NULL;
  12352         break;
  12353     case bcmTimeCaptureAll:
  12354         cb_all.cb_type = bcmTimeCaptureAll;
  12355         cb_all.cb = NULL;
  12356         cb_all.user_data_ptr = NULL;
  12357         break;
  12358     }
  12359 
  12360     if (cb_overflow.cb == NULL && cb_fill.cb == NULL && cb_all.cb == NULL){
  12361         /* No callbacks are registered anymore. Disable interrupts */
  12362 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12363         if (SOC_IS_MONTEREY(unit) || SOC_IS_TOMAHAWK3(unit)) {
  12364             BCM_TIME_WRITE_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, 0);
  12365         }
  12366 #endif
  12367     }
  12368     if (cb_overflow.cb == NULL && cb_fill.cb == NULL && cb_all.cb == NULL){
  12369         /* At least one callback is registered. Enable the interrupt */
  12370 #if defined(BCM_TIMESYNC_TIME_CAPTURE_SUPPORT)
  12371         if (soc_feature(unit, soc_feature_timesync_time_capture)) {
  12372             (void)soc_cmicm_intr1_disable(unit, IRQ_CMCx_TIMESYNC_INTR);
  12373         }
  12374 #endif
  12375     }
  12376 #endif /* #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) */
  12377 
  12378     return BCM_E_NONE;
  12379 }
  12380 
  12381 void
  12382 soc_nanosync_intr(void *unit_vp, void *d1, void *d2,
  12383                   void *d3, void *d4)
  12384 {
  12385 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12386     int unit = PTR_TO_INT(unit_vp);
  12387     int valid = 0;
  12388 
  12389     uint32 int_status_clear = 0;  /* Interrupt status clear */
  12390     uint32 int_enable = 0;  /* Interrupt enable */
  12391     uint32 regval,regval1,regval2,regval3,lower, middle, upper,event_id, fifo_depth, capture_status;
  12392 
  12393     uint16 g_fifo_data_index = 0;
  12394 
  12395     /* Read the GDPLL interrupt */
  12396     BCM_TIME_READ_NS_REGr(unit, NS_TS_INT_STATUSr, 0, &g_int_status);
  12397     BCM_TIME_READ_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, &int_enable);
  12398 
  12399     /* Process only enabled interrupts */
  12400     g_int_status &= int_enable;
  12401 
  12402     /* TS_FIFO_NOT_EMPTY interrupt */
  12403     if (tsfifo_flag && soc_reg_field_get(unit, NS_TS_INT_STATUSr, g_int_status, TS_FIFO_NOT_EMPTYf)) {
  12404 
  12405         /* Set W1TC to clear the flag */
  12406         soc_reg_field_set(unit, NS_TS_INT_STATUSr, &int_status_clear, TS_FIFO_NOT_EMPTYf, 1);
  12407         /* Write W1TC to clear the flags in NS_TS_INT_STATUS */
  12408         BCM_TIME_WRITE_NS_REGr(unit, NS_TS_INT_STATUSr, 0, int_status_clear);
  12409 
  12410         BCM_TIME_READ_NS_REGr(unit, NS_TS_CAPTURE_STATUSr, 0, &capture_status);
  12411         fifo_depth = soc_reg_field_get(unit, NS_TS_CAPTURE_STATUSr, capture_status, FIFO_DEPTHf);
  12412         g_fifo_data_fill[g_fifo_data_index++] = 0xFF & fifo_depth;
  12413         g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (fifo_depth >> 8);
  12414         /*bsl_printf("FIFO_Depth: %d\n", fifo_depth);*/
  12415 
  12416         while (fifo_depth != 0) {
  12417             /* Must read LOWER regiser first */
  12418             /* Read to this register POPs the FIFO */
  12419             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r(unit, &regval3);
  12420             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_2r(unit, &regval2);
  12421             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_1r(unit, &regval1);
  12422             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_0r(unit, &regval);
  12423 
  12424 
  12425 
  12426             /* Check capture event id */
  12427             event_id = soc_reg_field_get(
  12428                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r,
  12429                             regval3, TS_EVENT_IDf);
  12430 
  12431             valid = (regval3 >> 20) & 1;
  12432 
  12433             if (!valid){
  12434                 continue;
  12435             }
  12436 
  12437 #if 0
  12438             /* Calculate seconds/nanoseconds from the timestamp value */
  12439             lower = soc_reg_field_get(
  12440                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_0r,
  12441                             regval, TS0_Lf);
  12442 
  12443             upper = soc_reg_field_get(
  12444                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_1r,
  12445                             regval1, TS0_Uf);
  12446 
  12447             bsl_printf("FIFO timestamp popped. EventId: %d, TS0: %x%x\n", event_id, upper, lower);
  12448 
  12449             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & event_id;
  12450             g_fifo_data_fill[g_fifo_data_index++] = 0x0;
  12451             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & lower;
  12452             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (lower >> 8);
  12453             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (lower >> 16);
  12454             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (lower >> 24);
  12455             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & upper;
  12456             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (upper >> 8);
  12457             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (upper >> 16);
  12458 #endif
  12459 
  12460             /* Calculate seconds/nanoseconds from the timestamp value */
  12461             lower = soc_reg_field_get(
  12462                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_1r,
  12463                             regval1, TS1_Lf);
  12464 
  12465             middle = soc_reg_field_get(
  12466                                         unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_2r,
  12467                                         regval2, TS1_Mf);
  12468 
  12469             upper = soc_reg_field_get(
  12470                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r,
  12471                             regval3, TS1_Uf);
  12472 
  12473             lower = (lower & 0xFFF) | ((middle & 0xFFFFF) << 12);
  12474             upper = ((upper & 0xF) << 12) | ((middle >> 20) & 0xFFF);
  12475 
  12476 
  12477             /*bsl_printf("FIFO timestamp popped. EventId: %d, TS1: %x%x\n", event_id, upper, lower);*/
  12478 
  12479             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & event_id;
  12480             g_fifo_data_fill[g_fifo_data_index++] = 0x0;
  12481             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & lower;
  12482             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (lower >> 8);
  12483             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (lower >> 16);
  12484             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (lower >> 24);
  12485             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & upper;
  12486             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (upper >> 8);
  12487             g_fifo_data_fill[g_fifo_data_index++] = 0xFF & (upper >> 16);
  12488             fifo_depth--;
  12489         }
  12490     }
  12491 
  12492     /* TS_FIFO_OVERFLOW interrupt */
  12493     if (tsfifo_flag && soc_reg_field_get(unit, NS_TS_INT_STATUSr, g_int_status, TS_FIFO_OVERFLOWf)) {
  12494         g_fifo_data_index = 0;
  12495 
  12496         /* Set W1TC to clear the flag */
  12497         soc_reg_field_set(unit, NS_TS_INT_STATUSr, &int_status_clear, TS_FIFO_OVERFLOWf, 1);
  12498         /* Write W1TC to clear the flags in NS_TS_INT_STATUS */
  12499         BCM_TIME_WRITE_NS_REGr(unit, NS_TS_INT_STATUSr, 0, int_status_clear);
  12500 
  12501         BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_INPUT_TIME_FIFO_STATUSr, 0, &capture_status);
  12502         event_id = soc_reg_field_get(unit, NS_TIMESYNC_INPUT_TIME_FIFO_STATUSr,
  12503                                     capture_status, SOURCE_OVERFLOW_TYPEf);
  12504         g_fifo_data_overflow[g_fifo_data_index++] = 0xFF & event_id;
  12505 
  12506     }
  12507 
  12508 #if defined(INCLUDE_GDPLL)
  12509     gdpll_intr(unit, g_int_status, int_enable);
  12510 #endif
  12511 
  12512     /* Signal the thread for buffer read */
  12513     if (tsfifo_flag && g_fifo_sem) {
  12514         sal_sem_give(g_fifo_sem);
  12515     }
  12516     /* Re-enable TS NS IRQ */
  12517     /*  soc_cmicm_intr2_enable(unit, SOC_TIME_NS_INTR_POS); */
  12518     soc_cmicm_intr2_enable(unit, (1<<24) | (1<<25));/* SOC_GDPLL_NS_INTR_POS | SOC_GDPLL_NS_INTR_DEBUG_POS */
  12519 
  12520 #endif /* #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) */
  12521 }
  12522 
  12523 
  12524 #if defined (BCM_TIMESYNC_TIME_CAPTURE_SUPPORT)
  12525 void
  12526 soc_esw_timesync_ts_intr(int unit)
  12527 {
  12528 
  12529     uint32 int_enable = 0;  /* Interrupt enable */
  12530     uint32 regval1=0, lower=0, upper=0, event_id=0;
  12531     uint32 fifo_depth=0, capture_status=0, fifo_status=0;
  12532     uint32 intr=0, over_flow=0;
  12533     uint16 notify=0;
  12534     uint32 int_status = 0;  /* Interrupt status */
  12535     int buf_full=0, buf_idx=0;
  12536 
  12537     READ_CMIC_TIMESYNC_INTERRUPT_STATUSr(unit, &int_status);
  12538 
  12539     READ_CMIC_TIMESYNC_CAPTURE_STATUS_1r(unit, &capture_status);
  12540 
  12541     /* TS_FIFO_NOT_EMPTY interrupt */
  12542     intr = soc_reg_field_get(unit, CMIC_TIMESYNC_INTERRUPT_STATUSr, int_status, INTERRUPTf);
  12543     if (intr)
  12544 	{
  12545 
  12546         READ_CMIC_TIMESYNC_FIFO_STATUSr(unit, &fifo_status);
  12547         over_flow = soc_reg_field_get(unit, CMIC_TIMESYNC_FIFO_STATUSr,
  12548                                     fifo_status, SOURCE_OVERFLOWf);
  12549         if(over_flow) {
  12550             LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "TS FIFO status source overflow \n")));
  12551             soc_reg_field_set(unit, CMIC_TIMESYNC_FIFO_STATUSr, &fifo_status, SOURCE_OVERFLOWf, 0);
  12552             WRITE_CMIC_TIMESYNC_FIFO_STATUSr(unit, fifo_status);
  12553         }
  12554 
  12555         fifo_depth = soc_reg_field_get(unit, CMIC_TIMESYNC_CAPTURE_STATUS_1r, capture_status, FIFO_DEPTHf);
  12556         LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "FIFO depth[%d]\n"),fifo_depth));
  12557 
  12558         while (fifo_depth != 0) {
  12559             notify = 1;
  12560             /* Must read LOWER regiser first */
  12561             READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr(unit, &lower);
  12562             READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr(unit, &regval1);
  12563 
  12564             /* Check capture event id */
  12565             event_id = soc_reg_field_get(
  12566                             unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr,
  12567                             regval1, EVENT_IDf);
  12568 
  12569             /* Calculate seconds/nanoseconds from the timestamp value */
  12570             upper = soc_reg_field_get(
  12571                             unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr,
  12572                             regval1, TIMESTAMPf);
  12573 
  12574             /* LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "[%d]:%d:%x%x\n"),fifo_depth, event_id, upper, lower));*/
  12575 
  12576             buf_idx = (ts_capture_info[unit]->ts_fifo_wr_index);
  12577             buf_full = ((buf_idx + 12) >= BCM_TIME_TS_CAPTURE_BUF_SIZE);
  12578             if (!buf_full) {
  12579 
  12580             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x0;
  12581             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x0;
  12582             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x0;
  12583             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x1;
  12584 
  12585             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x0;
  12586             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & event_id;
  12587             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & (upper >> 8);
  12588             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & upper;
  12589             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & (lower >> 24);
  12590             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & (lower >> 16);
  12591             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & (lower >> 8);
  12592             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & lower;
  12593 
  12594             ts_capture_info[unit]->ts_fifo_wr_index = buf_idx;
  12595             }
  12596             fifo_depth--;
  12597         }
  12598 
  12599         if(over_flow) {
  12600             LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "[%d]:%d:%x%x \n"),fifo_depth, event_id, upper, lower));
  12601         }
  12602 
  12603         /* Clear status */
  12604         WRITE_CMIC_TIMESYNC_CAPTURE_STATUS_CLR_1r(unit, capture_status);
  12605 
  12606         READ_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, &int_enable);
  12607 
  12608         /* Clear interrupts */
  12609         WRITE_CMIC_TIMESYNC_INTERRUPT_CLRr(unit, int_status);
  12610         WRITE_CMIC_TIMESYNC_INTERRUPT_CLRr(unit, 0);
  12611 
  12612         /* Enable interrupts */
  12613         WRITE_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, int_enable);
  12614 
  12615     }
  12616 
  12617     if (notify && !over_flow && (ts_capture_info[unit]->ts_fifo_sem)) {
  12618         sal_sem_give(ts_capture_info[unit]->ts_fifo_sem);
  12619     }
  12620 
  12621 }
  12622 
  12623 #ifdef BCM_CMICX_SUPPORT
  12624 void
  12625 soc_esw_timesync_ts_cmicx_intr(int unit, void *data)
  12626 {
  12627     soc_esw_timesync_ts_intr(unit);
  12628 }
  12629 #endif
  12630 
  12631 #endif
  12632 
  12633 
  12634 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12635 void
  12636 time_capture_cb_thread(void *unit_vp)
  12637 {
  12638     int unit = PTR_TO_INT(unit_vp);
  12639     uint8 cb_data_fill[BCM_TIME_CAPTURE_MAX_FIFO_DATA_SIZE];
  12640     uint8 cb_data_overflow[2];
  12641     uint32 int_status = 0;
  12642 
  12643     while(1) {
  12644         /* Wait on the signal from the ISR */
  12645         (void)sal_sem_take(g_fifo_sem, sal_sem_FOREVER);
  12646 
  12647         int_status = g_int_status;
  12648 
  12649         if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_FIFO_NOT_EMPTYf)) {
  12650             sal_memcpy(cb_data_fill, g_fifo_data_fill, BCM_TIME_CAPTURE_MAX_FIFO_DATA_SIZE);
  12651         }
  12652 
  12653         /* TS_FIFO_OVERFLOW interrupt */
  12654         if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_FIFO_OVERFLOWf)) {
  12655             sal_memcpy(cb_data_overflow, g_fifo_data_overflow, 2);
  12656         }
  12657 
  12658         if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_FIFO_NOT_EMPTYf)) {
  12659             if (cb_fill.cb != NULL)
  12660                 cb_fill.cb(unit, cb_fill.user_data_ptr, (uint32 *)cb_data_fill, bcmTimeCapturetFill);
  12661             if (cb_all.cb != NULL)
  12662                 cb_all.cb(unit, cb_all.user_data_ptr, (uint32 *)cb_data_fill, bcmTimeCapturetFill);
  12663         }
  12664 
  12665         /* TS_FIFO_OVERFLOW interrupt */
  12666         if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_FIFO_OVERFLOWf)) {
  12667             if (cb_overflow.cb != NULL)
  12668                 cb_overflow.cb(unit, cb_overflow.user_data_ptr, (uint32 *)cb_data_overflow, bcmTimeCaptureOverflow);
  12669             if (cb_all.cb != NULL)
  12670                 cb_all.cb(unit, cb_all.user_data_ptr, (uint32 *)cb_data_overflow, bcmTimeCaptureOverflow);
  12671         }
  12672     }
  12673 }
  12674 
  12675 #if defined(BCM_TOMAHAWK3_SUPPORT)
  12676 void
  12677 soc_esw_nanosync_ts_cmicx_intr(int unit, void *data)
  12678 {
  12679     int valid = 0;
  12680     uint32 int_status = 0;  /* Interrupt status */
  12681     uint32 int_status_clear = 0;  /* Interrupt status clear */
  12682     uint32 int_enable = 0;  /* Interrupt enable */
  12683     uint32 regval,regval1,regval2,regval3,lower, middle, upper,event_id, fifo_depth, capture_status;
  12684 
  12685     int buf_full=0, buf_idx=0;
  12686 
  12687     /* Read the GDPLL interrupt */
  12688     BCM_TIME_READ_NS_REGr(unit, NS_TS_INT_STATUSr, 0, &int_status);
  12689     BCM_TIME_READ_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, &int_enable);
  12690 
  12691     /* Process only enabled interrupts */
  12692     int_status &= int_enable;
  12693 
  12694     /* TS_FIFO_NOT_EMPTY interrupt */
  12695     if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_FIFO_NOT_EMPTYf)) {
  12696 
  12697         /* Set W1TC to clear the flag */
  12698         soc_reg_field_set(unit, NS_TS_INT_STATUSr, &int_status_clear, TS_FIFO_NOT_EMPTYf, 1);
  12699 
  12700         /* Write W1TC to clear the flags in NS_TS_INT_STATUS */
  12701         BCM_TIME_WRITE_NS_REGr(unit, NS_TS_INT_STATUSr, 0, int_status_clear);
  12702 
  12703         BCM_TIME_READ_NS_REGr(unit, NS_TS_CAPTURE_STATUSr, 0, &capture_status);
  12704 
  12705         fifo_depth = soc_reg_field_get(unit, NS_TS_CAPTURE_STATUSr, capture_status, FIFO_DEPTHf);
  12706 
  12707         /*bsl_printf("FIFO_Depth: %d\n", fifo_depth);*/
  12708 
  12709         while (fifo_depth != 0) {
  12710             /* Must read LOWER regiser first */
  12711             /* Read to this register POPs the FIFO */
  12712             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r(unit, &regval3);
  12713             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_2r(unit, &regval2);
  12714             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_1r(unit, &regval1);
  12715             READ_NS_TIMESYNC_INPUT_TIME_FIFO_TS_0r(unit, &regval);
  12716 
  12717 
  12718             /* Check capture event id */
  12719             event_id = soc_reg_field_get(
  12720                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r,
  12721                             regval3, TS_EVENT_IDf);
  12722             valid = soc_reg_field_get(
  12723                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r,
  12724                             regval3, TS_VALIDf);
  12725 
  12726             if (!valid){
  12727                 continue;
  12728             }
  12729 
  12730             /* Calculate seconds/nanoseconds from the timestamp value */
  12731             lower = soc_reg_field_get(
  12732                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_1r,
  12733                             regval1, TS1_Lf);
  12734 
  12735             middle = soc_reg_field_get(
  12736                                         unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_2r,
  12737                                         regval2, TS1_Mf);
  12738 
  12739             upper = soc_reg_field_get(
  12740                             unit, NS_TIMESYNC_INPUT_TIME_FIFO_TS_3r,
  12741                             regval3, TS1_Uf);
  12742 
  12743             lower = (lower & 0xFFF) | ((middle & 0xFFFFF) << 12);
  12744             upper = ((upper & 0xF) << 12) | ((middle >> 20) & 0xFFF);
  12745 
  12746 
  12747             /*bsl_printf("FIFO timestamp popped. EventId: %d, TS1: %x%x\n", event_id, upper, lower);*/
  12748 
  12749             buf_idx = (ts_capture_info[unit]->ts_fifo_wr_index);
  12750             buf_full = ((buf_idx + 12) >= BCM_TIME_TS_CAPTURE_BUF_SIZE);
  12751             if (!buf_full) {
  12752 
  12753             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x0;
  12754             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x0;
  12755             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x0;
  12756             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x1;
  12757 
  12758             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0x0;
  12759             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & event_id;
  12760             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & (upper >> 8);
  12761             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & upper;
  12762             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & (lower >> 24);
  12763             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & (lower >> 16);
  12764             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & (lower >> 8);
  12765             ts_capture_info[unit]->ts_fifo_data_fill[buf_idx++] = 0xFF & lower;
  12766 
  12767             ts_capture_info[unit]->ts_fifo_wr_index = buf_idx;
  12768             }
  12769             fifo_depth--;
  12770 
  12771         }
  12772     }
  12773 
  12774     /* TS_FIFO_OVERFLOW interrupt */
  12775     if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_FIFO_OVERFLOWf)) {
  12776 
  12777         /* Set W1TC to clear the flag */
  12778         soc_reg_field_set(unit, NS_TS_INT_STATUSr, &int_status_clear, TS_FIFO_OVERFLOWf, 1);
  12779         /* Write W1TC to clear the flags in NS_TS_INT_STATUS */
  12780         BCM_TIME_WRITE_NS_REGr(unit, NS_TS_INT_STATUSr, 0, int_status_clear);
  12781 
  12782         BCM_TIME_READ_NS_REGr(unit, NS_TIMESYNC_INPUT_TIME_FIFO_STATUSr, 0, &capture_status);
  12783 
  12784     } else if ((ts_capture_info[unit]->ts_fifo_sem)) {
  12785         /* Signal the thread for buffer read */
  12786         sal_sem_give(ts_capture_info[unit]->ts_fifo_sem);
  12787     }
  12788 
  12789     /* Re-enable TS NS IRQ */
  12790 #ifdef BCM_CMICX_SUPPORT
  12791     if (soc_feature(unit, soc_feature_cmicx)) {
  12792         soc_cmic_intr_enable(unit, TS_INTR);
  12793     }
  12794 #endif
  12795 
  12796 
  12797 }
  12798 #endif /* defined(BCM_TOMAHAWK3_SUPPORT) */
  12799 
  12800 
  12801 int
  12802 _bcm_esw_time_capture_init(int unit)
  12803 {
  12804     sal_thread_t thread_id_time_capture_cb;
  12805 
  12806     /* Create the time capture semaphore */
  12807     g_fifo_sem = sal_sem_create("fifo_time_capture", sal_sem_COUNTING, 0);
  12808     if (g_fifo_sem == NULL) {
  12809         LOG_ERROR(BSL_LS_SOC_COMMON,
  12810                   (BSL_META_U(unit,
  12811                       "BCM TIME: Error !! failed to create the sem\n")));
  12812           return (SOC_E_MEMORY);
  12813     }
  12814 
  12815     /* Create the time capture callback thread */
  12816     thread_id_time_capture_cb = sal_thread_create("Time capture cb thread", SAL_THREAD_STKSZ, 100,
  12817                                         time_capture_cb_thread, INT_TO_PTR(unit));
  12818     if (thread_id_time_capture_cb == SAL_THREAD_ERROR) {
  12819         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "BCM TIME: Error !! callback thread create failed\n")));
  12820         return SOC_E_INTERNAL;
  12821     }
  12822 
  12823     return BCM_E_NONE;
  12824 }
  12825 #endif /*#if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)*/
  12826 
  12827 #if defined(BCM_TIMESYNC_TIME_CAPTURE_SUPPORT)
  12828 
  12829 void
  12830 time_capture_ts_cb_thread(void *unit_vp)
  12831 {
  12832     int num_entries;
  12833     int unit = PTR_TO_INT(unit_vp);
  12834     uint8 cb_data_fill[12] = {0};
  12835 
  12836     ts_capture_info[unit]->time_capture_ts_active = 1;
  12837 
  12838     while (ts_capture_info[unit]->time_capture_ts_enable) {
  12839 
  12840         /* Wait on the signal from the ISR */
  12841         (void)sal_sem_take(ts_capture_info[unit]->ts_fifo_sem, sal_sem_FOREVER);
  12842         if ((ts_capture_info[unit] != NULL) &&
  12843             (ts_capture_info[unit]->time_capture_ts_enable == 0)) {
  12844             break;
  12845         }
  12846 
  12847         num_entries = ((ts_capture_info[unit]->ts_fifo_wr_index - ts_capture_info[unit]->ts_fifo_rd_index) / 12);
  12848         while (num_entries) {
  12849             sal_memcpy(cb_data_fill, &(ts_capture_info[unit]->ts_fifo_data_fill[ts_capture_info[unit]->ts_fifo_rd_index]), 12);
  12850             ts_capture_info[unit]->ts_fifo_rd_index += 12;
  12851 
  12852             if (cb_fill.cb != NULL) {
  12853                  cb_fill.cb(unit, cb_fill.user_data_ptr, (uint32 *)cb_data_fill, bcmTimeCapturetFill);
  12854             }
  12855             num_entries--;
  12856         }
  12857     }
  12858 
  12859     ts_capture_info[unit]->time_capture_ts_active = 0;
  12860 
  12861     return;
  12862 }
  12863 
  12864 int
  12865 bcm_esw_time_capture_ts_init(int unit)
  12866 {
  12867 #ifdef BCM_CMICX_SUPPORT
  12868     soc_cmic_intr_handler_t handle;
  12869 #endif
  12870 
  12871     if (ts_capture_info[unit] != NULL) {
  12872         return BCM_E_NONE;
  12873     }
  12874 
  12875     ts_capture_info[unit] = sal_alloc(sizeof(bcm_esw_time_ts_capture_info_t), "ts capture info");
  12876     if (ts_capture_info[unit] == NULL) {
  12877         LOG_ERROR(BSL_LS_SOC_COMMON,
  12878                   (BSL_META_U(unit,
  12879                               "BCM TIME: Error !! failed to allocate memory for time capture info\n")));
  12880           return (SOC_E_MEMORY);
  12881     }
  12882     sal_memset(ts_capture_info[unit], 0, sizeof(bcm_esw_time_ts_capture_info_t));
  12883 
  12884     /* Create the time capture semaphore */
  12885     ts_capture_info[unit]->ts_fifo_sem = sal_sem_create("fifo_time_capture", sal_sem_COUNTING, 0);
  12886     if (ts_capture_info[unit]->ts_fifo_sem == NULL) {
  12887         LOG_ERROR(BSL_LS_SOC_COMMON,
  12888                   (BSL_META_U(unit,
  12889                               "BCM TIME: Error !! failed to create semaphore\n")));
  12890           return (SOC_E_MEMORY);
  12891     }
  12892 
  12893 #ifdef BCM_CMICX_SUPPORT
  12894     if (soc_feature(unit, soc_feature_cmicx)) {
  12895 
  12896         handle.num = TS_INTR;
  12897 #ifdef BCM_TOMAHAWK3_SUPPORT
  12898         if (SOC_IS_TOMAHAWK3(unit)) {
  12899             handle.intr_fn = soc_esw_nanosync_ts_cmicx_intr;
  12900         } else
  12901 #endif
  12902         {
  12903             handle.intr_fn = soc_esw_timesync_ts_cmicx_intr;
  12904         }
  12905         handle.intr_data = NULL;
  12906         soc_cmic_intr_register(unit, &handle, 1);
  12907 
  12908         soc_cmic_intr_enable(unit, TS_INTR);
  12909     }
  12910 #endif
  12911 
  12912     /* Create the time capture callback thread */
  12913     ts_capture_info[unit]->time_capture_ts_enable = 1;
  12914     ts_capture_info[unit]->thread_id_time_capture_ts =
  12915         sal_thread_create("Time capture cb thread", SAL_THREAD_STKSZ, 100,
  12916                           time_capture_ts_cb_thread, INT_TO_PTR(unit));
  12917 
  12918     if (ts_capture_info[unit]->thread_id_time_capture_ts == SAL_THREAD_ERROR) {
  12919         LOG_ERROR(BSL_LS_SOC_COMMON,
  12920                   (BSL_META_U(unit,
  12921                               "BCM TIME: Error !! callback thread create failed\n")));
  12922         return SOC_E_INTERNAL;
  12923     }
  12924 
  12925     return BCM_E_NONE;
  12926 }
  12927 
  12928 int
  12929 bcm_esw_time_capture_ts_deinit(int unit)
  12930 {
  12931     soc_timeout_t       to;
  12932 
  12933     if (ts_capture_info[unit] == NULL) {
  12934         return BCM_E_NONE;
  12935     }
  12936 
  12937     ts_capture_info[unit]->time_capture_ts_enable = 0;
  12938     sal_sem_give(ts_capture_info[unit]->ts_fifo_sem);
  12939 
  12940     soc_timeout_init(&to, 50000, 0);
  12941 
  12942     do {
  12943         if (soc_timeout_check(&to)) {
  12944             LOG_WARN(BSL_LS_SOC_COMMON,
  12945                      (BSL_META_U(unit, "TS Thread exit timed out\n")));
  12946         }
  12947     } while (ts_capture_info[unit]->time_capture_ts_active != 0);
  12948 
  12949     /* Destroy the time capture semaphore */
  12950     sal_sem_destroy(ts_capture_info[unit]->ts_fifo_sem);
  12951 
  12952     /* Free ts_capture info */
  12953     sal_free(ts_capture_info[unit]);
  12954     ts_capture_info[unit] = NULL;
  12955 
  12956     return BCM_E_NONE;
  12957 }
  12958 
  12959 #endif /* BCM_TIMESYNC_TIME_CAPTURE_SUPPORT */