gdpll.c (160724B)
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: gdpll.c 8 * 9 * Remarks: Broadcom StrataSwitch Time GDPLL API 10 * 11 * Functions: 12 * Private Interface functions 13 * _bcm_esw_gdpll_event_divisor_misc_set 14 * _bcm_esw_gdpll_event_divisor_misc_get 15 * _bcm_esw_gdpll_event_divisor_port_set 16 * _bcm_esw_gdpll_event_divisor_port_get 17 * _bcm_esw_gdpll_event_dest_misc_set 18 * _bcm_esw_gdpll_event_dest_misc_get 19 * _bcm_esw_gdpll_event_dest_port_set 20 * _bcm_esw_gdpll_event_dest_port_get 21 * _bcm_esw_gdpll_event_enable_misc_set 22 * _bcm_esw_gdpll_event_enable_misc_get 23 * _bcm_esw_gdpll_event_enable_port_set 24 * _bcm_esw_gdpll_event_enable_port_get 25 * _bcm_esw_gdpll_event_roe_52b_set 26 * _bcm_esw_gdpll_event_roe_52b_get 27 * _bcm_esw_gdpll_event_config_set 28 * 29 * _bcm_esw_gdpll_capture_enable_m7_set 30 * _bcm_esw_gdpll_capture_enable_m7_get 31 * _bcm_esw_gdpll_capture_enable_cpu_set 32 * _bcm_esw_gdpll_capture_enable_cpu_get 33 * 34 * _bcm_esw_gdpll_chan_update_set 35 * _bcm_esw_gdpll_chan_update_get 36 * _bcm_esw_gdpll_chan_enable_set 37 * _bcm_esw_gdpll_chan_enable_get 38 * _bcm_esw_gdpll_chan_out_txpi_set 39 * _bcm_esw_gdpll_chan_out_txpi_get 40 * _bcm_esw_gdpll_chan_out_misc_set 41 * _bcm_esw_gdpll_chan_out_misc_get 42 * _bcm_esw_gdpll_chan_out_enable_set 43 * _bcm_esw_gdpll_chan_out_enable_get 44 * _bcm_esw_gdpll_chan_priority_set 45 * 46 * _bcm_esw_gdpll_chan_config_dpll_set 47 * _bcm_esw_gdpll_chan_config_dpll_get 48 * _bcm_esw_gdpll_chan_debug_mode_set 49 * _bcm_esw_gdpll_chan_debug_mode_get 50 * _bcm_esw_gdpll_debug_enable_set 51 * 52 * _bcm_esw_gdpll_flush 53 * _bcm_esw_gdpll_init 54 * _bcm_esw_gdpll_deinit 55 * _bcm_esw_gdpll_input_eventId_get 56 * _bcm_esw_gdpll_input_array_alloc 57 * _bcm_esw_gdpll_input_array_free 58 * _bcm_esw_gdpll_chan_alloc 59 * _bcm_esw_gdpll_chan_free 60 * 61 * _bcm_esw_gdpll_offset_get 62 * _bcm_esw_gdpll_offset_set 63 * 64 * _bcm_esw_tdpll_chan_create 65 * _bcm_esw_tdpll_gdpll_chan_destroy 66 * 67 * Public Interface functions 68 * bcm_esw_gdpll_chan_create 69 * bcm_esw_gdpll_chan_destroy 70 * bcm_esw_gdpll_chan_enable 71 * bcm_esw_gdpll_chan_state_get 72 * bcm_esw_gdpll_chan_debug_enable 73 * bcm_esw_gdpll_debug_cb_register 74 * bcm_esw_gdpll_flush 75 * bcm_esw_gdpll_cb_register 76 * bcm_esw_gdpll_cb_unregister 77 * bcm_esw_gdpll_debug 78 */ 79 80 #include <shared/util.h> 81 #include <shared/bsl.h> 82 83 #include <soc/defs.h> 84 #include <soc/mem.h> 85 #include <soc/iproc.h> 86 87 #ifdef PORTMOD_SUPPORT 88 #include <soc/portmod/portmod.h> 89 #include <soc/portmod/portmod_internal.h> 90 #endif 91 92 #include <bcm/port.h> 93 #include <bcm/error.h> 94 #include <bcm_int/esw/switch.h> 95 96 #if defined(INCLUDE_GDPLL) 97 #include <bcm/gdpll.h> 98 #include <bcm_int/esw/gdpll.h> 99 100 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_IPROC_SUPPORT) 101 #include <soc/uc.h> 102 #endif 103 #ifdef BCM_MONTEREY_SUPPORT 104 #include <soc/monterey.h> 105 #endif /* BCM_MONTEREY_SUPPORT */ 106 107 #define BCN_WAR 108 /****************************************************************************/ 109 /* MACRO definitions */ 110 /****************************************************************************/ 111 #define BCM_GDPLL_MISC_EVENT_EN_CPU (1<<0) 112 #define BCM_GDPLL_MISC_EVENT_EN_BS0HB (1<<1) 113 #define BCM_GDPLL_MISC_EVENT_EN_BS1HB (1<<2) 114 #define BCM_GDPLL_MISC_EVENT_EN_IPDM0 (1<<3) 115 #define BCM_GDPLL_MISC_EVENT_EN_IPDM1 (1<<4) 116 #define BCM_GDPLL_MISC_EVENT_EN_TS1 (1<<5) 117 #define BCM_GDPLL_MISC_EVENT_EN_RSVD1IF (1<<6) 118 #define BCM_GDPLL_MISC_EVENT_EN_RSVD1RF (1<<7) 119 #define BCM_GDPLL_MISC_EVENT_EN_BS0CONV (1<<8) 120 #define BCM_GDPLL_MISC_EVENT_EN_BS1CONV (1<<9) 121 122 /* GDPLL debug buffer thresholds */ 123 #define BCM_GDPLL_DEBUG_BUFFER_START (0x3274000) 124 #define BCM_GDPLL_DEBUG_BUFFER_SIZE (1024*10) /* 40KB/4 */ 125 #define BCM_GDPLL_DEBUG_THRESHOLD_1K (1024/4) 126 #define BCM_GDPLL_DEBUG_THRESHOLD_2K (2048/4) 127 #define BCM_GDPLL_DEBUG_THRESHOLD_8K (8192/4) 128 #define BCM_GDPLL_DEBUG_THRESHOLD (BCM_GDPLL_DEBUG_THRESHOLD_1K) 129 130 /* Debug buffer interrupts */ 131 #define INTR_GDPLL_DEBUG_THR (1<<0) 132 #define INTR_GDPLL_DEBUG_OF (1<<1) 133 #define INTR_GDPLL_DEBUG_ECC0 (1<<2) 134 #define INTR_GDPLL_DEBUG_ECC1 (1<<3) 135 #if 0 136 #define INTR_NS_DEBUG (INTR_GDPLL_DEBUG_THR | \ 137 INTR_GDPLL_DEBUG_OF | \ 138 INTR_GDPLL_DEBUG_ECC0 | \ 139 INTR_GDPLL_DEBUG_ECC1) 140 #endif 141 #define INTR_NS_DEBUG (INTR_GDPLL_DEBUG_THR | \ 142 INTR_GDPLL_DEBUG_OF) 143 /* NS Interrupts */ 144 #define INTR_TS_FIFO_NOT_EMPTY (1<<0) /* TS_FIFO fill */ 145 #define INTR_TS_FIFO_OVERFLOW (1<<1) /* TS_FIFO overflow */ 146 #define INTR_TS0_CNT_OFFSET_UPDATED (1<<2) /* TS0 counter offset updated */ 147 #define INTR_TS1_CNT_OFFSET_UPDATED (1<<3) /* TS1 counter offset updated */ 148 #define INTR_ROE_TS_ERR (1<<4) 149 #define INTR_GDPLL_IA_0_STATUS (1<<5) /* Channel(0:31) update */ 150 #define INTR_GDPLL_IA_1_STATUS (1<<6) /* Channel(32:63) update */ 151 #define INTR_GDPLL_IA_2_STATUS (1<<7) /* Channel(64:95) update */ 152 #define INTR_GDPLL_IA_3_STATUS (1<<8) /* Channel(96:127) update */ 153 #define INTR_GDPLL_OA_0_STATUS (1<<9) /* Channel(0:31) OA */ 154 #define INTR_GDPLL_OA_1_STATUS (1<<10) /* Channel(32:63) OA */ 155 #define INTR_GDPLL_OA_2_STATUS (1<<11) /* Channel(64:95) OA */ 156 #define INTR_GDPLL_OA_3_STATUS (1<<12) /* Channel(96:127) OA */ 157 #define INTR_GDPLL_NCO_OVERLOAD_0_STATUS (1<<13) 158 #define INTR_GDPLL_NCO_OVERLOAD_1_STATUS (1<<14) 159 #define INTR_GDPLL_NCO_OVERLOAD_2_STATUS (1<<15) 160 #define INTR_GDPLL_NCO_OVERLOAD_3_STATUS (1<<16) 161 #define INTR_GDPLL_COMMON_STATUS (1<<17) 162 #define INTR_M7_CORE_INT_STATUS (1<<18) 163 #define INTR_TS_CPU_FIFO_ECC_ERR_STATUS (1<<19) 164 #define INTR_GDPLL_MEM_ECC_ERR_STATUS (1<<20) 165 #define INTR_M7_TCM_ECC_ERR_STATUS (1<<21) 166 #define INTR_RSVD1_MESSAGE_RX_STATUS (1<<22) 167 #define INTR_TS_CAPTURE_OVRD (1<<23) 168 #define INTR_NS_TS (INTR_TS_FIFO_NOT_EMPTY | \ 169 INTR_TS_FIFO_OVERFLOW | \ 170 INTR_TS0_CNT_OFFSET_UPDATED | \ 171 INTR_TS1_CNT_OFFSET_UPDATED | \ 172 INTR_ROE_TS_ERR | \ 173 INTR_GDPLL_COMMON_STATUS | \ 174 INTR_M7_CORE_INT_STATUS | \ 175 INTR_TS_CPU_FIFO_ECC_ERR_STATUS | \ 176 INTR_M7_TCM_ECC_ERR_STATUS | \ 177 INTR_RSVD1_MESSAGE_RX_STATUS | \ 178 INTR_TS_CAPTURE_OVRD | \ 179 INTR_GDPLL_NCO_OVERLOAD_0_STATUS | \ 180 INTR_GDPLL_NCO_OVERLOAD_1_STATUS | \ 181 INTR_GDPLL_NCO_OVERLOAD_2_STATUS | \ 182 INTR_GDPLL_NCO_OVERLOAD_3_STATUS | \ 183 INTR_GDPLL_IA_0_STATUS | \ 184 INTR_GDPLL_IA_1_STATUS | \ 185 INTR_GDPLL_IA_2_STATUS | \ 186 INTR_GDPLL_IA_3_STATUS ) 187 188 #define READ_NS_REGr(unit, reg, idx, rvp) \ 189 soc_iproc_getreg(unit, soc_reg_addr(unit, reg, REG_PORT_ANY, idx), rvp); 190 #define WRITE_NS_REGr(unit, reg, idx, rv) \ 191 soc_iproc_setreg(unit, soc_reg_addr(unit, reg, REG_PORT_ANY, idx), rv) 192 193 #define SOC_GDPLL_NS_INTR_POS (1<<24) 194 #define SOC_GDPLL_NS_INTR_DEBUG_POS (1<<25) 195 #define TS_GPIO_COUNT 6 196 197 /****************************************************************************/ 198 /* LOCAL VARIABLES DECLARATION */ 199 /****************************************************************************/ 200 /* Like context structure, etc */ 201 STATIC 202 soc_reg_t 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 bs_pll_regs[2] = { NS_BROADSYNC0_CLK_EVENT_CTRLr, 211 NS_BROADSYNC1_CLK_EVENT_CTRLr }; 212 213 STATIC 214 soc_reg_t mapper_port_enable_regs[4] = { NS_TIMESYNC_MAPPER_PORT_ENABLE_0r, 215 NS_TIMESYNC_MAPPER_PORT_ENABLE_1r, 216 NS_TIMESYNC_MAPPER_PORT_ENABLE_2r, 217 NS_TIMESYNC_MAPPER_PORT_ENABLE_3r 218 }; 219 220 STATIC 221 soc_reg_t mapper_port_enable[32] = { PORT0_TS_ENABLEf, PORT1_TS_ENABLEf, 222 PORT2_TS_ENABLEf, PORT3_TS_ENABLEf, 223 PORT4_TS_ENABLEf, PORT5_TS_ENABLEf, 224 PORT6_TS_ENABLEf, PORT7_TS_ENABLEf, 225 226 PORT8_TS_ENABLEf, PORT9_TS_ENABLEf, 227 PORT10_TS_ENABLEf, PORT11_TS_ENABLEf, 228 PORT12_TS_ENABLEf, PORT13_TS_ENABLEf, 229 PORT14_TS_ENABLEf, PORT15_TS_ENABLEf, 230 231 PORT16_TS_ENABLEf, PORT17_TS_ENABLEf, 232 PORT18_TS_ENABLEf, PORT19_TS_ENABLEf, 233 PORT20_TS_ENABLEf, PORT21_TS_ENABLEf, 234 PORT22_TS_ENABLEf, PORT23_TS_ENABLEf, 235 236 PORT24_TS_ENABLEf, PORT25_TS_ENABLEf, 237 PORT26_TS_ENABLEf, PORT27_TS_ENABLEf, 238 PORT28_TS_ENABLEf, PORT29_TS_ENABLEf, 239 PORT30_TS_ENABLEf, PORT31_TS_ENABLEf 240 }; 241 242 #define NUM_TDPLL_INSTANCE 64 243 typedef struct gdpll_tdpll_state_s { 244 uint32 tdpll_instace[NUM_TDPLL_INSTANCE]; /* Hold the I/A indicator of each instance */ 245 } gdpll_tdpll_state_t; 246 247 STATIC gdpll_tdpll_state_t gdpll_tdpll_state; 248 249 STATIC gdpll_context_t *pGdpllCtx = NULL; 250 #if defined(DPLL_VERSION_02) 251 m7_dpll_param_t m7DpllParam; 252 #endif 253 254 STATIC int soc_iproc_m7_write(int unit, uint32 addr, uint32 data); 255 256 /****************************************************************************/ 257 /* Internal functions implementation */ 258 /****************************************************************************/ 259 int 260 _bcm_esw_get_timestamp(int unit, int timestamper, uint64 *pTs_52) 261 { 262 int rv = BCM_E_NONE; 263 uint32 acc1 = 0; 264 uint32 acc2 = 0; 265 uint64 ts; 266 267 if (timestamper == 1) { 268 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_ACCUMULATOR_2r(unit, &acc2)); 269 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_ACCUMULATOR_1r(unit, &acc1)); 270 } else if (timestamper == 0) { 271 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_ACCUMULATOR_2r(unit, &acc2)); 272 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_ACCUMULATOR_1r(unit, &acc1)); 273 } else { 274 bsl_printf("GDPLL: Error !! _bcm_esw_get_timestamp: Wrong timestamper:%d\n", timestamper); 275 rv = BCM_E_FAIL; 276 } 277 278 u64_L(ts) = acc1 >> 8 | acc2 << 24; 279 u64_H(ts) = acc2 >> 8; 280 *pTs_52 = ts; 281 282 return rv; 283 } 284 285 int 286 _bcm_esw_set_timestamp(int unit, int timestamper, uint64 ts_52) 287 { 288 uint32 rval; 289 int rv = BCM_E_NONE; 290 291 if (timestamper == 1) { 292 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r(unit, &rval)); 293 soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r, &rval, ACC2f, u64_H(ts_52) << 8 | u64_L(ts_52) >> 24); 294 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r(unit, rval)); 295 296 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r(unit, &rval)); 297 soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r, &rval, ACC1f, u64_L(ts_52) << 8); 298 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r(unit, rval)); 299 300 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r(unit, &rval)); 301 soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r, &rval, ACC0f, 0); 302 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r(unit, rval)); 303 304 } else if (timestamper == 0) { 305 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r(unit, &rval)); 306 soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r, &rval, ACC2f, u64_H(ts_52) << 8 | u64_L(ts_52) >> 24); 307 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r(unit, rval)); 308 309 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r(unit, &rval)); 310 soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r, &rval, ACC1f, u64_L(ts_52) << 8); 311 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r(unit, rval)); 312 313 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r(unit, &rval)); 314 soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r, &rval, ACC0f, 0); 315 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r(unit, rval)); 316 } else { 317 cli_out("Error !! _bcm_esw_set_timestamp: Wrong timestamper:%d\n", timestamper); 318 rv = BCM_E_FAIL; 319 } 320 321 return rv; 322 } 323 324 int 325 _bcm_esw_timestamp_enable(int unit, int timestamper, int enable) 326 { 327 uint32 rval; 328 int rv = BCM_E_NONE; 329 330 if (timestamper == 1) { 331 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, &rval)); 332 soc_reg_field_set(unit, NS_TIMESYNC_TS1_COUNTER_ENABLEr, &rval, ENABLEf, enable?1:0); 333 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, rval)); 334 } else if (timestamper == 0) { 335 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &rval)); 336 soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &rval, ENABLEf, enable?1:0); 337 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, rval)); 338 } else { 339 cli_out("Error !! _bcm_esw_timestamp_enable: Wrong timestamper:%d\n", timestamper); 340 rv = BCM_E_FAIL; 341 } 342 343 return rv; 344 } 345 346 347 STATIC int 348 _bcm_esw_gdpll_portmap_get(int unit, bcm_port_t port, int *pGdpllPort) 349 { 350 int rv = BCM_E_NONE; 351 352 /* Check if the port is valid */ 353 if (port <= 0) { 354 return BCM_E_PORT; 355 } 356 357 /* Following is the mapping in Monterey */ 358 if ((port >= 1) && (port <= BCM_GDPLL_NUM_PORTS)) { 359 *pGdpllPort = port - 1; 360 } else { 361 LOG_ERROR(BSL_LS_SOC_COMMON, 362 (BSL_META_U(unit, 363 "_bcm_esw_gdpll_portmap_get: Error !! Invalid port\n"))); 364 *pGdpllPort = BCM_GDPLL_NUM_PORTS; 365 } 366 367 return rv; 368 } 369 370 STATIC int 371 _bcm_esw_port_get(int unit, int gdpllPort, bcm_port_t *pPort) 372 { 373 int rv = BCM_E_NONE; 374 375 /* Following is the mapping in Monterey */ 376 if ((gdpllPort >= 0) && (gdpllPort <= (BCM_GDPLL_NUM_PORTS-1))) { 377 *pPort = gdpllPort + 1; 378 } else { 379 LOG_ERROR(BSL_LS_SOC_COMMON, 380 (BSL_META_U(unit, 381 "_bcm_esw_port_get: Error !! Invalid gdpll port\n"))); 382 rv = BCM_E_PARAM; 383 } 384 385 return rv; 386 } 387 388 STATIC int 389 _bcm_esw_gdpll_event_divisor_misc_set(int unit, bcm_gdpll_input_event_t event_misc, 390 uint32 divisor) 391 { 392 int rv = BCM_E_NONE; 393 int idx = 0; 394 uint32 regVal = 0; 395 396 switch (event_misc) { 397 case bcmGdpllInputEventCpu: 398 case bcmGdpllInputEventBS0HB: 399 case bcmGdpllInputEventBS1HB: 400 case bcmGdpllInputEventIPDM0: 401 case bcmGdpllInputEventIPDM1: 402 case bcmGdpllInputEventTS1TS: 403 case bcmGdpllInputEventRSVD1IF: 404 case bcmGdpllInputEventRSVD1RF: 405 case bcmGdpllInputEventBS0ConvTC: 406 case bcmGdpllInputEventBS1ConvTC: 407 /* No divider */ 408 bsl_printf("GDPLL: event_divisor_misc_set: No divider for event:%d \n", event_misc); 409 break; 410 411 case bcmGdpllInputEventGPIO0: 412 case bcmGdpllInputEventGPIO1: 413 case bcmGdpllInputEventGPIO2: 414 case bcmGdpllInputEventGPIO3: 415 case bcmGdpllInputEventGPIO4: 416 case bcmGdpllInputEventGPIO5: 417 idx = event_misc - bcmGdpllInputEventGPIO0; 418 READ_NS_REGr(unit, gpio_regs[idx], 0, ®Val); 419 soc_reg_field_set(unit, gpio_regs[idx], ®Val, 420 DIVISORf, divisor); 421 WRITE_NS_REGr(unit, gpio_regs[idx], 0, regVal); 422 break; 423 424 case bcmGdpllInputEventBS0PLL: 425 case bcmGdpllInputEventBS1PLL: 426 idx = event_misc - bcmGdpllInputEventBS0PLL; 427 READ_NS_REGr(unit, bs_pll_regs[idx], 0, ®Val); 428 soc_reg_field_set(unit, bs_pll_regs[idx], ®Val, 429 DIVISORf, divisor); 430 WRITE_NS_REGr(unit, bs_pll_regs[idx], 0, regVal); 431 break; 432 433 case bcmGdpllInputEventLCPLL0: 434 case bcmGdpllInputEventLCPLL1: 435 case bcmGdpllInputEventLCPLL2: 436 case bcmGdpllInputEventLCPLL3: 437 idx = event_misc - bcmGdpllInputEventLCPLL0; 438 READ_NS_REGr(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, idx, ®Val); 439 soc_reg_field_set(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, ®Val, 440 DIVISORf, divisor); 441 WRITE_NS_REGr(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, idx, regVal); 442 break; 443 444 default: 445 LOG_ERROR(BSL_LS_SOC_COMMON, 446 (BSL_META_U(unit, 447 "event_divisor_misc_set: Error !! wrong param\n"))); 448 rv = BCM_E_PARAM; 449 goto exit; 450 } 451 452 exit: 453 return (rv); 454 } 455 456 STATIC int 457 _bcm_esw_gdpll_event_divisor_misc_get(int unit, bcm_gdpll_input_event_t event_misc, 458 uint32 *pDivisor) 459 { 460 int rv = BCM_E_NONE; 461 462 return (rv); 463 } 464 465 STATIC int 466 _bcm_esw_gdpll_event_divisor_port_set(int unit, bcm_port_t port, 467 bcm_gdpll_port_event_t port_event_type, uint32 divisor) 468 { 469 int rv = BCM_E_NONE; 470 int idx = 0; 471 uint32 regVal = 0; 472 473 if (port > BCM_GDPLL_NUM_PORTS) { 474 LOG_ERROR(BSL_LS_SOC_COMMON, 475 (BSL_META_U(unit, 476 "event_divisor_port_set: Error !! wrong port \n"))); 477 rv = BCM_E_PARAM; 478 goto exit; 479 } 480 481 idx = port; 482 switch (port_event_type) { 483 case bcmGdpllPortEventRXSOF: 484 case bcmGdpllPortEventTXSOF: 485 case bcmGdpllPortEventROE: 486 LOG_ERROR(BSL_LS_SOC_COMMON, 487 (BSL_META_U(unit, 488 "event_divisor_port_set: Error !! No divisor\n"))); 489 rv = BCM_E_UNAVAIL; 490 break; 491 492 case bcmGdpllPortEventRXCDR: 493 READ_NS_REGr(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, idx, ®Val); 494 soc_reg_field_set(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, ®Val, 495 DIVISORf, divisor); 496 WRITE_NS_REGr(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, idx, regVal); 497 break; 498 499 case bcmGdpllPortEventTXPI: 500 READ_NS_REGr(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, idx, ®Val); 501 soc_reg_field_set(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, ®Val, 502 DIVISORf, divisor); 503 WRITE_NS_REGr(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, idx, regVal); 504 break; 505 506 default: 507 LOG_ERROR(BSL_LS_SOC_COMMON, 508 (BSL_META_U(unit, 509 "event_divisor_port_set: Error !! Wrong param\n"))); 510 rv = BCM_E_PARAM; 511 } 512 513 exit: 514 return (rv); 515 } 516 517 STATIC int 518 _bcm_esw_gdpll_event_divisor_port_get(int unit, bcm_port_t port, 519 bcm_gdpll_port_event_t port_event_type, 520 uint32 *pDivisor) 521 { 522 int rv = BCM_E_NONE; 523 return (rv); 524 } 525 526 /* Mapping of input events to eventId will be device specific */ 527 STATIC int 528 _bcm_esw_gdpll_input_eventId_get(int unit, 529 bcm_gdpll_chan_input_t *pInputEvent, 530 uint32 *pEventId) 531 { 532 int rv = BCM_E_NONE; 533 int idx = 0; 534 gdpll_context_t *pGdpllContext = pGdpllCtx; 535 536 if ((pEventId==NULL) || (pGdpllContext==NULL) || 537 (pInputEvent->input_event < bcmGdpllInputEventCpu) || 538 (pInputEvent->input_event >= bcmGdpllInputEventMax)) { 539 LOG_ERROR(BSL_LS_SOC_COMMON, 540 (BSL_META_U(unit, 541 "input_eventId_get: Error !! Wrong event\n"))); 542 rv = BCM_E_PARAM; 543 goto exit; 544 } 545 546 /* EventId 0 to 191 for port events, 547 * EventId 192 to 213 for EventCpu to EventLCPLL3 548 * EventId 214 for R5 549 */ 550 switch ((int)pInputEvent->input_event) { 551 case bcmGdpllInputEventPORT: 552 if (pInputEvent->port < 0 || pInputEvent->port > BCM_GDPLL_NUM_PORTS){ 553 LOG_ERROR(BSL_LS_SOC_COMMON, 554 (BSL_META_U(unit, 555 "input_eventId_get: Error !! Wrong port\n"))); 556 rv = BCM_E_PARAM; 557 goto exit; 558 } 559 560 if ((pInputEvent->port_event_type == bcmGdpllPortEventRXCDR) || 561 (pInputEvent->port_event_type == bcmGdpllPortEventRXSOF)){ 562 /* Event could be TXSOF or TXPI based on port type */ 563 idx = pInputEvent->port*2; 564 } else if (pInputEvent->port_event_type == bcmGdpllPortEventROE) { 565 idx = pInputEvent->port*2 + 1; 566 } else if ((pInputEvent->port_event_type == bcmGdpllPortEventTXSOF) || 567 (pInputEvent->port_event_type == bcmGdpllPortEventTXPI)){ 568 /* Event could be TXSOF or TXPI based on port type */ 569 idx = BCM_GDPLL_IA_START_TXPI_TXSOF + pInputEvent->port; 570 } else { 571 LOG_ERROR(BSL_LS_SOC_COMMON, 572 (BSL_META_U(unit, 573 "input_eventId_get: Error !! Wrong param\n"))); 574 rv = BCM_E_PARAM; 575 goto exit; 576 } 577 break; 578 579 case bcmGdpllInputEventR5: 580 idx = BCM_GDPLL_IA_START_R5; 581 break; 582 583 default: 584 idx = BCM_GDPLL_IA_START_MISC + pInputEvent->input_event; 585 } 586 587 *pEventId = idx; 588 589 exit: 590 return rv; 591 } 592 593 /* Get the event based on the eventId */ 594 STATIC int 595 _bcm_esw_gdpll_input_event_get(int unit, 596 uint32 eventId, 597 bcm_gdpll_input_event_t *pEvent_misc, 598 bcm_gdpll_port_event_t *pPort_event_type, 599 bcm_port_t *pPort) 600 { 601 int rv = BCM_E_NONE; 602 int idx = 0; 603 bcm_port_t port; 604 605 if (eventId >= BCM_GDPLL_NUM_INPUT_EVENTS){ 606 LOG_ERROR(BSL_LS_SOC_COMMON, 607 (BSL_META_U(unit, 608 "input_event_get: Error !! Wrong param\n"))); 609 rv = BCM_E_PARAM; 610 goto exit; 611 } 612 613 if (eventId >= BCM_GDPLL_IA_START_R5) { 614 /* Event from R5 */ 615 *pEvent_misc = bcmGdpllInputEventR5; 616 617 } else if (eventId >= BCM_GDPLL_IA_START_MISC) { 618 /* Miscellaneous events */ 619 *pEvent_misc = eventId - BCM_GDPLL_IA_START_MISC; 620 621 } else if (eventId >= BCM_GDPLL_IA_START_TXPI_TXSOF) { 622 /* Its a TXPI or TXSOF event based on the port */ 623 *pEvent_misc = bcmGdpllInputEventPORT; 624 *pPort = eventId - BCM_GDPLL_IA_START_TXPI_TXSOF; 625 #if 0 626 *pPort_event_type = IS_CPRI_PORT(unit, *pPort) ? bcmGdpllPortEventTXSOF : 627 bcmGdpllPortEventTXPI; 628 #else 629 _bcm_esw_port_get(unit, *pPort, &port); 630 if (IS_CPRI_PORT(unit, port)) { 631 *pPort_event_type = bcmGdpllPortEventTXSOF; 632 } else { 633 *pPort_event_type = bcmGdpllPortEventTXPI; 634 } 635 #endif 636 } else { 637 /* Its a TXPI or TXSOF event based on the port */ 638 *pEvent_misc = bcmGdpllInputEventPORT; 639 *pPort = eventId/2; 640 idx = eventId%2; 641 642 #if 0 643 if (IS_CPRI_PORT(unit, *pPort)) { 644 #else 645 _bcm_esw_port_get(unit, *pPort, &port); 646 if (IS_CPRI_PORT(unit, port)) { 647 #endif 648 *pPort_event_type = idx ? bcmGdpllPortEventROE : bcmGdpllPortEventRXSOF; 649 } else { 650 if (idx) { 651 /* Unused event ID */ 652 LOG_ERROR(BSL_LS_SOC_COMMON, 653 (BSL_META_U(unit, 654 "input_event_get: Error !! Unused event ID\n"))); 655 rv = BCM_E_PARAM; 656 goto exit; 657 } 658 *pPort_event_type = bcmGdpllPortEventRXCDR; 659 } 660 } 661 662 exit: 663 return rv; 664 } 665 666 STATIC int 667 _bcm_esw_gdpll_input_eventId_inUse(int unit, 668 uint32 eventId, int *pIsUse) 669 { 670 int rv = BCM_E_NONE; 671 int chan; 672 gdpll_context_t *pGdpllContext = pGdpllCtx; 673 674 /* Since the event from R5 can be for multiple outpts, skip the check */ 675 if (eventId == 214) { 676 *pIsUse = 0; 677 goto exit; 678 } 679 680 /* Check if this event is ref or fb for any of the active channels */ 681 for (chan=0; chan<BCM_GDPLL_NUM_CHANNELS; chan++) { 682 if (pGdpllContext->dpll_chan[chan].flag & BCM_GDPLL_CHAN_ALLOC) { 683 if ((pGdpllContext->dpll_chan[chan].eventId_ref == eventId) || 684 (pGdpllContext->dpll_chan[chan].eventId_fb == eventId)) { 685 /* This event is already used by chan */ 686 *pIsUse = 1; 687 goto exit; 688 } 689 } 690 } 691 692 *pIsUse = 0; 693 694 exit: 695 return rv; 696 } 697 698 STATIC int 699 _bcm_esw_gdpll_input_array_alloc(int unit, uint32 eventId, uint32 *pIaAddr) 700 { 701 int rv = BCM_E_NONE; 702 int ia_loc; 703 704 /* 705 * Findout if this event is already under use by active channel 706 * If not, findout the free ia address from the pool and allocate, 707 * 708 * Monterey have event id's less than the input array size. 709 * Hence let the event id be the input array address for now 710 * HW team recommends the eventId to be same as iaAddr 711 */ 712 713 if (eventId == 214/*BCM_GDPLL_IA_START_R5, R5-event */) { 714 /* For now, the IA locations assigned is from 214 */ 715 int ia_found = 0; 716 int instance_count; 717 for (ia_loc = eventId; ia_loc < BCM_GDPLL_NUM_IA_ENTRIES; ia_loc++) { 718 for (instance_count = 0; instance_count < NUM_TDPLL_INSTANCE; instance_count++) { 719 if (gdpll_tdpll_state.tdpll_instace[instance_count] != ia_loc) 720 continue; 721 } 722 if (instance_count == NUM_TDPLL_INSTANCE) { 723 /* Found the ia location */ 724 ia_found = 1; 725 break; 726 } 727 728 continue; 729 } 730 731 if (!ia_found) { 732 bsl_printf("_bcm_esw_gdpll_input_array_alloc: Error!! IA location for R5 is not found\n"); 733 rv = BCM_E_FULL; 734 } else { 735 *pIaAddr = ia_loc; 736 bsl_printf("_bcm_esw_gdpll_input_array_alloc: ia location for R5 is:%d\n", ia_loc); 737 } 738 739 } else { 740 *pIaAddr = eventId; 741 } 742 743 return rv; 744 } 745 746 STATIC int 747 _bcm_esw_gdpll_input_array_free(int unit, uint32 eventId) 748 { 749 int rv = BCM_E_NONE; 750 /* 751 * Figure out if this eventId is under use by any active channel 752 * If not, free the input array address assocuated with this event 753 */ 754 return rv; 755 } 756 757 758 STATIC int 759 _bcm_esw_gdpll_event_dest_misc_set(int unit, bcm_gdpll_input_event_t event_misc, 760 gdpll_event_dest_cfg_t *pEventDest, 761 uint32 eventId, uint32 *pIaAddr) 762 { 763 int rv = BCM_E_NONE; 764 int idx = 0; 765 uint32 regVal = 0; 766 uint32 dest; 767 uint32 chkProfile; 768 gdpll_context_t *pGdpllContext = pGdpllCtx; 769 770 if (event_misc < bcmGdpllInputEventCpu || 771 event_misc > bcmGdpllInputEventLCPLL3) { 772 LOG_ERROR(BSL_LS_SOC_COMMON, 773 (BSL_META_U(unit, 774 "event_dest_misc_set: Error !! Wrong param\n"))); 775 rv = BCM_E_PARAM; 776 goto exit; 777 } 778 779 /* Check if the event is already enabled, that may indicate 780 * that it will be used by some active GDPLL channel. 781 * if so, return error 782 */ 783 /* Check if this event is forwared to any of IA location */ 784 if ((pGdpllContext->eventId[eventId] >= 0) && 785 (pGdpllContext->eventId[eventId] < BCM_GDPLL_NUM_IA_ENTRIES)) { 786 /* This event is already forwarded to IA location and could 787 * be in use by an active GDPLL channel. 788 * Hence it cant be forwarded 789 */ 790 LOG_ERROR(BSL_LS_SOC_COMMON, 791 (BSL_META_U(unit, 792 "event_dest_misc_set: Error !! Event busy eventId:%d IA:%d\n"), eventId, pGdpllContext->eventId[eventId])); 793 rv = BCM_E_BUSY; 794 goto exit; 795 } 796 797 /* Get the free Input array address */ 798 BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_input_array_alloc(unit, 799 eventId, pIaAddr)); 800 801 /* Since we have 150 numels of NS_TIMESYNC_TS_EVENT_FWD_CFG, 802 * the miscellaneous events starts from index 128 per table 6.4 in uArch 803 */ 804 idx = 128 + event_misc; 805 806 if (pEventDest->event_dest == bcmGdpllEventDestCPU) { 807 dest = 0; 808 }else if (pEventDest->event_dest == bcmGdpllEventDestM7) { 809 dest = 1; 810 }else if (pEventDest->event_dest == bcmGdpllEventDestALL) { 811 dest = 2; 812 }else { 813 LOG_ERROR(BSL_LS_SOC_COMMON, 814 (BSL_META_U(unit, 815 "event_dest_misc_set: Error !! wrong event dest\n"))); 816 rv = BCM_E_PARAM; 817 goto exit; 818 } 819 820 821 chkProfile = 0; 822 823 READ_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, ®Val); 824 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 825 EVENT_IDf, eventId); 826 dest |= soc_reg_field_get(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, 827 regVal, DESTf); 828 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 829 DESTf, dest); 830 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 831 DPLL_ADDRf, *pIaAddr); 832 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 833 GDPLL_TSf, pEventDest->ts_counter ? 1:0); 834 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 835 PPM_CHECK_ENABLEf, pEventDest->ppm_check_enable ? 1:0); 836 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 837 SRC_TS_COUNTERf, pEventDest->ts_counter ? 1:0); 838 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 839 CHK_PROFILEf, chkProfile); 840 WRITE_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, regVal); 841 842 exit: 843 return (rv); 844 } 845 846 STATIC int 847 _bcm_esw_gdpll_event_dest_misc_get (int unit, bcm_gdpll_input_event_t event_misc, 848 gdpll_event_dest_cfg_t *pEventDest) 849 { 850 int rv = BCM_E_NONE; 851 return (rv); 852 } 853 854 STATIC int 855 _bcm_esw_gdpll_event_dest_port_set (int unit, bcm_port_t port, 856 bcm_gdpll_port_event_t port_event_type, 857 gdpll_event_dest_cfg_t *pEventDest, 858 uint32 eventId, uint32 *pIaAddr) 859 { 860 int rv = BCM_E_NONE; 861 int idx = 0; 862 uint32 regVal = 0; 863 uint32 dest; 864 uint32 chkProfile; 865 gdpll_context_t *pGdpllContext = pGdpllCtx; 866 867 if (port >= BCM_GDPLL_NUM_PORTS) { 868 LOG_ERROR(BSL_LS_SOC_COMMON, 869 (BSL_META_U(unit, 870 "event_dest_port_set: Error !! wrong param\n"))); 871 rv = BCM_E_PARAM; 872 goto exit; 873 } 874 875 /* Check if the event is already enabled, that may indicate 876 * it will be used by some active GDPLL channel. 877 * if so, return error 878 */ 879 if ((pGdpllContext->eventId[eventId] >= 0) && 880 (pGdpllContext->eventId[eventId] < BCM_GDPLL_NUM_IA_ENTRIES)) { 881 /* This event is already forwarded IA location and could be in use 882 * by an active GDPLL channel. Hence it cant be forwarded 883 */ 884 LOG_ERROR(BSL_LS_SOC_COMMON, 885 (BSL_META_U(unit, 886 "event_dest_port_set: Error !! event busy\n"))); 887 rv = BCM_E_BUSY; 888 goto exit; 889 } 890 891 /* Get the free Input array address */ 892 BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_input_array_alloc(unit, 893 eventId, pIaAddr)); 894 895 if (pEventDest->event_dest == bcmGdpllEventDestCPU) { 896 dest = 0; 897 }else if (pEventDest->event_dest == bcmGdpllEventDestM7) { 898 dest = 1; 899 }else if (pEventDest->event_dest == bcmGdpllEventDestALL) { 900 dest = 2; 901 }else { 902 LOG_ERROR(BSL_LS_SOC_COMMON, 903 (BSL_META_U(unit, 904 "event_dest_port_set: Error !! wrong event dest\n"))); 905 rv = BCM_E_PARAM; 906 goto exit; 907 } 908 909 910 chkProfile = 0; 911 912 switch(port_event_type) { 913 case bcmGdpllPortEventRXCDR: 914 case bcmGdpllPortEventTXPI: 915 if (port_event_type == bcmGdpllPortEventRXCDR){ 916 idx = port; 917 }else if (port_event_type == bcmGdpllPortEventTXPI) { 918 idx = port + BCM_GDPLL_NUM_PORTS; 919 } 920 921 bsl_printf("GDPLL: Setting NS_TIMESYNC_TS_EVENT_FWD_CFG idx:%d IA-Addr:%d\n", 922 idx, *pIaAddr); 923 924 READ_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, ®Val); 925 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 926 EVENT_IDf, eventId); 927 dest |= soc_reg_field_get(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, 928 regVal, DESTf); 929 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 930 DESTf, dest); 931 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 932 DPLL_ADDRf, *pIaAddr); 933 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 934 GDPLL_TSf, pEventDest->ts_counter ? 1:0); 935 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 936 PPM_CHECK_ENABLEf, pEventDest->ppm_check_enable ? 1:0); 937 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 938 SRC_TS_COUNTERf, pEventDest->ts_counter ? 1:0); 939 soc_reg_field_set(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, ®Val, 940 CHK_PROFILEf, chkProfile); 941 WRITE_NS_REGr(unit, NS_TIMESYNC_TS_EVENT_FWD_CFGr, idx, regVal); 942 943 break; 944 945 case bcmGdpllPortEventRXSOF: /* Type-0 */ 946 case bcmGdpllPortEventTXSOF: /* Type-1 */ 947 case bcmGdpllPortEventROE: /* Type-2 */ 948 /* 949 * Having 128 Numels, register map is 950 * Port-0: type-0, type-1, type-2, unused 951 * Port-1: type-0, type-1, type-2, unused 952 */ 953 if ((port >= BCM_GDPLL_NUM_CPRI_PORTS) || (port < 0)) { 954 LOG_ERROR(BSL_LS_SOC_COMMON, 955 (BSL_META_U(unit, 956 "event_dest_port_set: Error !! Invalid CPRI port\n"))); 957 rv = BCM_E_PARAM; 958 goto exit; 959 } 960 961 idx = port*4; 962 if (port_event_type == bcmGdpllPortEventTXSOF) { 963 idx = idx + 1; 964 }else if (port_event_type == bcmGdpllPortEventROE) { 965 idx = idx + 2; 966 } 967 968 bsl_printf("GDPLL: Setting NS_TIMESYNC_MAPPER_FWD_CFG idx:%d, IA-Addr:%d\n", 969 idx, *pIaAddr); 970 READ_NS_REGr(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, idx, ®Val); 971 soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, ®Val, 972 EVENT_IDf, eventId); 973 dest |= soc_reg_field_get(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, 974 regVal, DESTf); 975 soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, ®Val, 976 DESTf, dest); 977 soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, ®Val, 978 DPLL_ADDRf, *pIaAddr); 979 soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, ®Val, 980 PPM_CHECK_ENABLEf, pEventDest->ppm_check_enable ? 1:0); 981 soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, ®Val, 982 SRC_TS_COUNTERf, 1); /* It is TS1 counter */ 983 soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, ®Val, 984 CHK_PROFILEf, chkProfile); 985 WRITE_NS_REGr(unit, NS_TIMESYNC_MAPPER_FWD_CFGr, idx, regVal); 986 break; 987 988 default: 989 LOG_ERROR(BSL_LS_SOC_COMMON, 990 (BSL_META_U(unit, 991 "event_dest_port_set: Error !! wrong event\n"))); 992 rv = BCM_E_PARAM; 993 goto exit; 994 } 995 996 /* eventId got set the forwarding to iaAddr */ 997 bsl_printf("GDPLL: Event Id populated :%d\n",*pIaAddr); 998 pGdpllContext->eventId[eventId] = *pIaAddr; 999 1000 exit: 1001 return (rv); 1002 } 1003 1004 STATIC int 1005 _bcm_esw_gdpll_event_dest_port_get(int unit, bcm_port_t port, bcm_gdpll_port_event_t port_event_type, 1006 gdpll_event_dest_cfg_t *pEventDest) 1007 { 1008 int rv = BCM_E_NONE; 1009 return (rv); 1010 } 1011 1012 STATIC int 1013 _bcm_esw_gdpll_event_enable_misc_set(int unit, bcm_gdpll_input_event_t event_misc, 1014 int enable) 1015 { 1016 int rv = BCM_E_NONE; 1017 uint32 idx = 0; 1018 uint32 enable_field = 0; 1019 uint32 regVal = 0; 1020 uint32 reg_enable; 1021 1022 /* 1023 NS_MISC_CLK_EVENT_CTRL 1024 NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRL 1025 NS_BROADSYNC0_CLK_EVENT_CTRL 1026 NS_BROADSYNC1_CLK_EVENT_CTRL 1027 NS_TIMESYNC_GPIO_x_CTRL 1028 */ 1029 switch (event_misc){ 1030 case bcmGdpllInputEventCpu: 1031 if (event_misc == bcmGdpllInputEventCpu) { 1032 enable_field = BCM_GDPLL_MISC_EVENT_EN_CPU; 1033 } 1034 case bcmGdpllInputEventBS0HB: 1035 if (event_misc == bcmGdpllInputEventBS0HB) { 1036 enable_field = BCM_GDPLL_MISC_EVENT_EN_BS0HB; 1037 } 1038 case bcmGdpllInputEventBS1HB: 1039 if (event_misc == bcmGdpllInputEventBS1HB) { 1040 enable_field = BCM_GDPLL_MISC_EVENT_EN_BS1HB; 1041 } 1042 case bcmGdpllInputEventIPDM0: 1043 if (event_misc == bcmGdpllInputEventIPDM0) { 1044 enable_field = BCM_GDPLL_MISC_EVENT_EN_IPDM0; 1045 } 1046 case bcmGdpllInputEventIPDM1: 1047 if (event_misc == bcmGdpllInputEventIPDM1) { 1048 enable_field = BCM_GDPLL_MISC_EVENT_EN_IPDM1; 1049 } 1050 case bcmGdpllInputEventTS1TS: 1051 if (event_misc == bcmGdpllInputEventTS1TS) { 1052 enable_field = BCM_GDPLL_MISC_EVENT_EN_TS1; 1053 } 1054 case bcmGdpllInputEventRSVD1IF: 1055 if (event_misc == bcmGdpllInputEventRSVD1IF) { 1056 enable_field = BCM_GDPLL_MISC_EVENT_EN_RSVD1IF; 1057 } 1058 case bcmGdpllInputEventRSVD1RF: 1059 if (event_misc == bcmGdpllInputEventRSVD1RF) { 1060 enable_field = BCM_GDPLL_MISC_EVENT_EN_RSVD1RF; 1061 } 1062 case bcmGdpllInputEventBS0ConvTC: 1063 if (event_misc == bcmGdpllInputEventBS0ConvTC) { 1064 enable_field = BCM_GDPLL_MISC_EVENT_EN_BS0CONV; 1065 } 1066 case bcmGdpllInputEventBS1ConvTC: 1067 if (event_misc == bcmGdpllInputEventBS1ConvTC) { 1068 enable_field = BCM_GDPLL_MISC_EVENT_EN_BS1CONV; 1069 } 1070 1071 /* Write the enable flag */ 1072 READ_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, ®Val); 1073 reg_enable = soc_reg_field_get(unit, NS_MISC_CLK_EVENT_CTRLr, regVal, ENABLEf); 1074 1075 reg_enable = enable ? (reg_enable | enable_field) : (reg_enable & (~enable_field)); 1076 1077 soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, ®Val, 1078 ENABLEf, reg_enable); 1079 WRITE_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, regVal); 1080 break; 1081 1082 case bcmGdpllInputEventGPIO0: 1083 case bcmGdpllInputEventGPIO1: 1084 case bcmGdpllInputEventGPIO2: 1085 case bcmGdpllInputEventGPIO3: 1086 case bcmGdpllInputEventGPIO4: 1087 case bcmGdpllInputEventGPIO5: 1088 idx = event_misc - bcmGdpllInputEventGPIO0; 1089 READ_NS_REGr(unit, gpio_regs[idx], 0, ®Val); 1090 /* soc_reg_field_set(unit, gpio_regs[idx], ®Val, 1091 CAPTURE_ENABLEf, enable ? 1:0); */ 1092 WRITE_NS_REGr(unit, gpio_regs[idx], 0, regVal); 1093 break; 1094 1095 case bcmGdpllInputEventBS0PLL: 1096 case bcmGdpllInputEventBS1PLL: 1097 idx = event_misc - bcmGdpllInputEventBS0PLL; 1098 READ_NS_REGr(unit, bs_pll_regs[idx], 0, ®Val); 1099 soc_reg_field_set(unit, bs_pll_regs[idx], ®Val, 1100 ENABLEf, enable ? 1:0); 1101 WRITE_NS_REGr(unit, bs_pll_regs[idx], 0, regVal); 1102 break; 1103 1104 case bcmGdpllInputEventLCPLL0: 1105 case bcmGdpllInputEventLCPLL1: 1106 case bcmGdpllInputEventLCPLL2: 1107 case bcmGdpllInputEventLCPLL3: 1108 idx = event_misc - bcmGdpllInputEventLCPLL0; 1109 READ_NS_REGr(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, idx, ®Val); 1110 soc_reg_field_set(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, ®Val, 1111 ENABLEf, enable ? 1:0); 1112 WRITE_NS_REGr(unit, NS_TIMESYNC_SERDES_LCPLL_EVENT_CTRLr, idx, regVal); 1113 break; 1114 1115 case bcmGdpllInputEventPORT: 1116 default: 1117 LOG_ERROR(BSL_LS_SOC_COMMON, 1118 (BSL_META_U(unit, 1119 "event_enable_misc_set: Error !! wrong event\n"))); 1120 rv = BCM_E_PARAM; 1121 goto exit; 1122 } 1123 1124 exit: 1125 return (rv); 1126 } 1127 1128 STATIC int 1129 _bcm_esw_gdpll_event_enable_misc_get(int unit, bcm_gdpll_input_event_t event_misc, 1130 int *pEnable) 1131 { 1132 int rv = BCM_E_NONE; 1133 return (rv); 1134 } 1135 1136 STATIC int 1137 _bcm_esw_gdpll_event_enable_port_set(int unit, bcm_port_t port, bcm_gdpll_port_event_t port_event_type, 1138 int enable) 1139 { 1140 int rv = BCM_E_NONE; 1141 uint32 mapper_reg; 1142 uint32 regVal = 0; 1143 uint32 enable_field = 0; 1144 uint32 reg_enable = 0; 1145 1146 if (port >= BCM_GDPLL_NUM_PORTS) { 1147 LOG_ERROR(BSL_LS_SOC_COMMON, 1148 (BSL_META_U(unit, 1149 "event_enable_port_set: Error !! wrong port\n"))); 1150 rv = BCM_E_PARAM; 1151 goto exit; 1152 } 1153 1154 switch (port_event_type) { 1155 case bcmGdpllPortEventRXSOF: 1156 case bcmGdpllPortEventTXSOF: 1157 case bcmGdpllPortEventROE: 1158 /* GDPLL has support to 32 CPRI ports */ 1159 if ((port >= BCM_GDPLL_NUM_CPRI_PORTS) || (port < 0)) { 1160 LOG_ERROR(BSL_LS_SOC_COMMON, 1161 (BSL_META_U(unit, 1162 "event_enable_port_set: Error !! wrong port or non-cpri\n"))); 1163 rv = BCM_E_PARAM; 1164 goto exit; 1165 } 1166 1167 /* Program NS_TIMESYNC_MAPPER_PORT_ENABLE_x */ 1168 enable_field = 1 << (port_event_type - bcmGdpllPortEventRXSOF); 1169 mapper_reg = port/8; 1170 1171 READ_NS_REGr(unit, mapper_port_enable_regs[mapper_reg], 0, ®Val); 1172 reg_enable = soc_reg_field_get(unit, mapper_port_enable_regs[mapper_reg], regVal, mapper_port_enable[port]); 1173 1174 reg_enable = enable ? (reg_enable | enable_field) : (reg_enable & (~enable_field)); 1175 1176 soc_reg_field_set(unit, mapper_port_enable_regs[mapper_reg], ®Val, mapper_port_enable[port], reg_enable); 1177 WRITE_NS_REGr(unit, mapper_port_enable_regs[mapper_reg], 0, regVal); 1178 1179 break; 1180 1181 case bcmGdpllPortEventRXCDR: 1182 /* Program NS_TIMESYNC_RX_CDR_EVENT_CTRL */ 1183 READ_NS_REGr(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, port, ®Val); 1184 soc_reg_field_set(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, ®Val, ENABLEf, enable ? 1:0); 1185 WRITE_NS_REGr(unit, NS_TIMESYNC_RX_CDR_EVENT_CTRLr, port, regVal); 1186 break; 1187 1188 case bcmGdpllPortEventTXPI: 1189 /* Program NS_TIMESYNC_TX_PI_CLK_EVENT_CTRL */ 1190 READ_NS_REGr(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, port, ®Val); 1191 soc_reg_field_set(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, ®Val, ENABLEf, enable ? 1:0); 1192 WRITE_NS_REGr(unit, NS_TIMESYNC_TX_PI_CLK_EVENT_CTRLr, port, regVal); 1193 break; 1194 1195 default: 1196 LOG_ERROR(BSL_LS_SOC_COMMON, 1197 (BSL_META_U(unit, 1198 "event_enable_port_set: Error !! wrong port event\n"))); 1199 rv = BCM_E_PARAM; 1200 goto exit; 1201 } 1202 1203 exit: 1204 return (rv); 1205 } 1206 1207 STATIC int 1208 _bcm_esw_gdpll_event_enable_port_get(int unit, bcm_port_t port, bcm_gdpll_port_event_t port_event_type, 1209 int *pEnable) 1210 { 1211 int rv = BCM_E_NONE; 1212 1213 return (rv); 1214 } 1215 1216 STATIC int 1217 _bcm_esw_gdpll_event_roe_52b_set(int unit, bcm_port_t port, int enable) 1218 { 1219 int rv = BCM_E_NONE; 1220 uint32 enable_field = 0; 1221 uint32 regVal = 0; 1222 uint32 reg_enable = 0; 1223 1224 /* Program NS_TIMESYNC_MAPPER_TYPE2_FORMAT */ 1225 1226 enable_field = 1 << port; 1227 1228 READ_NS_REGr(unit, NS_TIMESYNC_MAPPER_TYPE2_FORMATr, port, ®Val); 1229 reg_enable = soc_reg_field_get(unit, NS_TIMESYNC_MAPPER_TYPE2_FORMATr, regVal, CONV_ENf); 1230 1231 reg_enable = enable ? (reg_enable | enable_field) : (reg_enable & (~enable_field)); 1232 1233 soc_reg_field_set(unit, NS_TIMESYNC_MAPPER_TYPE2_FORMATr, ®Val, CONV_ENf, reg_enable); 1234 WRITE_NS_REGr(unit, NS_TIMESYNC_MAPPER_TYPE2_FORMATr, port, regVal); 1235 1236 return (rv); 1237 } 1238 1239 STATIC int 1240 _bcm_esw_gdpll_event_roe_52b_get(int unit, bcm_port_t port, int *pEnable) 1241 { 1242 int rv = BCM_E_NONE; 1243 /* NS_TIMESYNC_MAPPER_TYPE2_FORMAT */ 1244 1245 return (rv); 1246 } 1247 1248 STATIC int 1249 _bcm_esw_gdpll_chan_update_set(int unit, int chan) 1250 { 1251 /* Update NS_GDPLL_IA_UPDATE_CONFIG */ 1252 int rv = BCM_E_NONE; 1253 uint32 regVal = 0; 1254 gdpll_context_t *pGdpllContext = pGdpllCtx; 1255 uint32 eventId_fb; 1256 uint32 eventId_ref; 1257 1258 if (chan >= BCM_GDPLL_NUM_CHANNELS) { 1259 LOG_ERROR(BSL_LS_SOC_COMMON, 1260 (BSL_META_U(unit, 1261 "chan_update_set: Error !! wrong channel\n"))); 1262 rv = BCM_E_PARAM; 1263 goto exit; 1264 } 1265 1266 eventId_fb = pGdpllContext->dpll_chan[chan].eventId_fb; 1267 eventId_ref = pGdpllContext->dpll_chan[chan].eventId_ref; 1268 1269 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, ®Val); 1270 1271 /* Set the feedback for the channel */ 1272 if ((eventId_fb < BCM_GDPLL_NUM_INPUT_EVENTS) && 1273 (pGdpllContext->eventId[eventId_fb] < BCM_GDPLL_NUM_IA_ENTRIES)){ 1274 bsl_printf("GDPLL: chan_update: feedback Id:0x%x\n", pGdpllContext->eventId[eventId_fb]); 1275 soc_reg_field_set(unit, NS_GDPLL_IA_UPDATE_CONFIGr, ®Val, FEEDBACK_IDf, 1276 pGdpllContext->eventId[eventId_fb]); 1277 } else { 1278 LOG_ERROR(BSL_LS_SOC_COMMON, 1279 (BSL_META_U(unit, 1280 "chan_update_set: Error !! fb event not found\n"))); 1281 rv = BCM_E_NOT_FOUND; 1282 goto exit; 1283 } 1284 1285 /* Set the reference for the channel */ 1286 if (pGdpllContext->dpll_chan[chan].phaseConterRef == 0){ 1287 if ((eventId_ref < BCM_GDPLL_NUM_INPUT_EVENTS) && 1288 (pGdpllContext->eventId[eventId_ref] < BCM_GDPLL_NUM_IA_ENTRIES)){ 1289 bsl_printf("GDPLL: chan_update: ref Id:0x%x\n", pGdpllContext->eventId[eventId_ref]); 1290 soc_reg_field_set(unit, NS_GDPLL_IA_UPDATE_CONFIGr, ®Val, REFERENCE_IDf, 1291 pGdpllContext->eventId[eventId_ref]); 1292 } else { 1293 LOG_ERROR(BSL_LS_SOC_COMMON, 1294 (BSL_META_U(unit, 1295 "chan_update_set: Error !! ref event not found\n"))); 1296 rv = BCM_E_NOT_FOUND; 1297 goto exit; 1298 } 1299 } 1300 1301 WRITE_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, regVal); 1302 1303 exit: 1304 return (rv); 1305 } 1306 1307 STATIC int 1308 _bcm_esw_gdpll_chan_update_get(int unit, int chan, 1309 bcm_gdpll_chan_t *pGdpllChan) 1310 { 1311 int rv = BCM_E_NONE; 1312 1313 return (rv); 1314 } 1315 1316 STATIC int 1317 _bcm_esw_gdpll_chan_enable_set(int unit, int chan, int enable) 1318 { 1319 /* NS_GDPLL_IA_UPDATE_CONFIG */ 1320 int rv = BCM_E_NONE; 1321 uint32 regVal = 0; 1322 1323 if (chan >= BCM_GDPLL_NUM_CHANNELS) { 1324 LOG_ERROR(BSL_LS_SOC_COMMON, 1325 (BSL_META_U(unit, 1326 "chan_enable_set: Error !! invalid channel\n"))); 1327 rv = BCM_E_PARAM; 1328 goto exit; 1329 } 1330 1331 if (enable) { 1332 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, ®Val); 1333 if (soc_reg_field_get(unit, NS_GDPLL_IA_UPDATE_CONFIGr, regVal, ENABLEf)) { 1334 /* Already in enable state */ 1335 return rv; 1336 } 1337 1338 /* Clear the status flags if any */ 1339 if (chan < 32) { 1340 WRITE_NS_REGr(unit, NS_GDPLL_IA_TS_PAIR_AVAILABLE0r, 0, 1<<chan); 1341 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS0r, 0, 1<<chan); 1342 } else if (chan < 64) { 1343 WRITE_NS_REGr(unit, NS_GDPLL_IA_TS_PAIR_AVAILABLE1r, 0, 1<<(chan-32)); 1344 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS1r, 0, 1<<(chan-32)); 1345 } else if (chan < 96) { 1346 WRITE_NS_REGr(unit, NS_GDPLL_IA_TS_PAIR_AVAILABLE2r, 0, 1<<(chan-64)); 1347 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS2r, 0, 1<<(chan-64)); 1348 } else if (chan < 128) { 1349 WRITE_NS_REGr(unit, NS_GDPLL_IA_TS_PAIR_AVAILABLE3r, 0, 1<<(chan-96)); 1350 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS3r, 0, 1<<(chan-96)); 1351 } 1352 } 1353 1354 bsl_printf("GDPLL: Set enable:%d on GDPLL channel:%d\n", enable, chan); 1355 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, ®Val); 1356 soc_reg_field_set(unit, NS_GDPLL_IA_UPDATE_CONFIGr, ®Val, ENABLEf, enable ? 1:0); 1357 WRITE_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, regVal); 1358 1359 exit: 1360 return (rv); 1361 } 1362 1363 STATIC int 1364 _bcm_esw_gdpll_chan_enable_get(int unit, int chan, int *pEnable) 1365 { 1366 int rv = BCM_E_NONE; 1367 1368 return (rv); 1369 } 1370 1371 STATIC int 1372 _bcm_esw_gdpll_capture_enable_m7_set(int unit, int enable) 1373 { 1374 int rv = BCM_E_NONE; 1375 uint32 regVal = 0; 1376 /* NS_MISC_CLK_EVENT_CTRL */ 1377 bsl_printf("GDPLL: gdpll_capture_enable_m7_set enable:%d\n", enable); 1378 1379 READ_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, ®Val); 1380 soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, ®Val, GDPLL_CAPTURE_ENABLEf, enable ? 1:0); 1381 WRITE_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, regVal); 1382 1383 return (rv); 1384 } 1385 1386 STATIC int 1387 _bcm_esw_gdpll_capture_enable_m7_get(int unit, int *pEnable) 1388 { 1389 int rv = BCM_E_NONE; 1390 1391 return (rv); 1392 } 1393 1394 int 1395 _bcm_esw_gdpll_capture_enable_cpu_set(int unit, int enable) 1396 { 1397 int rv = BCM_E_NONE; 1398 uint32 regVal = 0; 1399 1400 READ_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, ®Val); 1401 soc_reg_field_set(unit, NS_MISC_CLK_EVENT_CTRLr, ®Val, TIME_CAPTURE_ENABLEf, enable ? 1:0); 1402 WRITE_NS_REGr(unit, NS_MISC_CLK_EVENT_CTRLr, 0, regVal); 1403 1404 return (rv); 1405 } 1406 1407 STATIC int 1408 _bcm_esw_gdpll_capture_enable_cpu_get(int unit, int *pEnable) 1409 { 1410 int rv = BCM_E_NONE; 1411 1412 return (rv); 1413 } 1414 1415 STATIC int 1416 _bcm_esw_gdpll_flush(int unit) 1417 { 1418 int rv = BCM_E_NONE; 1419 /* NS_GDPLL_GDPLL_COMMON_CTRL */ 1420 1421 WRITE_NS_REGr(unit, NS_GDPLL_GDPLL_COMMON_CTRLr, 0, 1); 1422 sal_usleep(100); 1423 WRITE_NS_REGr(unit, NS_GDPLL_GDPLL_COMMON_CTRLr, 0, 0); 1424 1425 return (rv); 1426 } 1427 1428 STATIC int 1429 _bcm_esw_gdpll_chan_out_txpi_set(int unit, int chan, bcm_port_t port) 1430 { 1431 int rv = BCM_E_NONE; 1432 uint32 regVal = 0; 1433 1434 if ((chan >= BCM_GDPLL_NUM_CHANNELS) && 1435 (port >= BCM_GDPLL_NUM_PORTS)) { 1436 LOG_ERROR(BSL_LS_SOC_COMMON, 1437 (BSL_META_U(unit, 1438 "chan_out_txpi_set: Error !! invalid param\n"))); 1439 rv = BCM_E_PARAM; 1440 goto exit; 1441 } 1442 1443 /* NS_GDPLL_NCO_UPDATE_CONTROL */ 1444 READ_NS_REGr(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, chan, ®Val); 1445 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_HW_IDf, port); 1446 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_TYPEf, 1); 1447 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_HW_TYPEf, 0); 1448 WRITE_NS_REGr(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, chan, regVal); 1449 1450 exit: 1451 return (rv); 1452 } 1453 1454 STATIC int 1455 _bcm_esw_gdpll_chan_out_txpi_get(int unit, int chan, bcm_port_t *pPort) 1456 { 1457 int rv = BCM_E_NONE; 1458 1459 return (rv); 1460 } 1461 1462 STATIC int 1463 _bcm_esw_gdpll_chan_out_misc_set(int unit, int chan, 1464 bcm_gdpll_output_event_t event) 1465 { 1466 int rv = BCM_E_NONE; 1467 uint32 regVal = 0; 1468 uint32 dest_hw_id = 0; 1469 uint32 dest_hw_type = 0; 1470 #ifdef BCN_WAR 1471 uint32 enableReg = 0; 1472 #endif 1473 1474 if (chan >= BCM_GDPLL_NUM_CHANNELS) { 1475 LOG_ERROR(BSL_LS_SOC_COMMON, 1476 (BSL_META_U(unit, 1477 "chan_out_misc_set: Error !! invalid param\n"))); 1478 rv = BCM_E_PARAM; 1479 goto exit; 1480 } 1481 1482 switch ((int)event) { 1483 case bcmGdpllOutputEventBSPLL0: 1484 case bcmGdpllOutputEventBSPLL1: 1485 case bcmGdpllOutputEventLCPLL0: 1486 case bcmGdpllOutputEventLCPLL1: 1487 case bcmGdpllOutputEventLCPLL2: 1488 case bcmGdpllOutputEventLCPLL3: 1489 bsl_printf("GDPLL: Setting NCO out control for BSPLL/LCPLL\n"); 1490 dest_hw_id = BCM_GDPLL_NUM_PORTS + 1491 (event - bcmGdpllOutputEventBSPLL0); 1492 dest_hw_type = 0; 1493 break; 1494 1495 case bcmGdpllOutputEventTS0: 1496 case bcmGdpllOutputEventTS1: 1497 bsl_printf("GDPLL: Setting NCO out control for TS0/TS1\n"); 1498 dest_hw_id = event - bcmGdpllOutputEventTS0; 1499 dest_hw_type = 1; 1500 break; 1501 1502 /* This is supposed to be BCN counter which is not there, 1503 * but now R5 reads the NCO and updates the BCN counter 1504 */ 1505 case bcmGdpllOutputEventBCN: 1506 bsl_printf("GDPLL: Setting NCO out control for BCN\n"); 1507 dest_hw_id = 1; 1508 dest_hw_type = 1; 1509 break; 1510 1511 case 10/*bcmGdpllOutputEventNTPTOD*/: 1512 bsl_printf("GDPLL: Setting NCO out control for NTP-TOD\n"); 1513 dest_hw_id = 2; 1514 dest_hw_type = 1; 1515 break; 1516 1517 case 11/*bcmGdpllOutputEventPTPTOD*/: 1518 bsl_printf("GDPLL: Setting NCO out control for PTP-TOD\n"); 1519 dest_hw_id = 3; 1520 dest_hw_type = 1; 1521 break; 1522 1523 default: 1524 LOG_ERROR(BSL_LS_SOC_COMMON, 1525 (BSL_META_U(unit, 1526 "chan_out_misc_set: Error !! invalid event\n"))); 1527 rv = BCM_E_PARAM; 1528 goto exit; 1529 } 1530 1531 READ_NS_REGr(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, chan, ®Val); 1532 #ifdef BCN_WAR 1533 if ((event == bcmGdpllOutputEventBCN) || (event == 10/*bcmGdpllOutputEventNTPTOD*/) || 1534 (event == 11/*bcmGdpllOutputEventPTPTOD*/)) { 1535 1536 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_TYPEf, 0); 1537 if (event == bcmGdpllOutputEventBCN) { 1538 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_BCN_UPDATE_LOC, chan); 1539 } else if (event == 10/*bcmGdpllOutputEventNTPTOD*/) { 1540 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_NTPTOD_UPDATE_LOC, chan); 1541 } else if (event == 11/*bcmGdpllOutputEventPTPTOD*/) { 1542 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_PTPTOD_UPDATE_LOC, chan); 1543 } 1544 1545 /* Enable the Channel Output array status reporting to R5 */ 1546 if (chan < 32) { 1547 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE0r, 0, &enableReg); 1548 enableReg |= 1<<chan; 1549 soc_reg_field_set(unit, NS_GDPLL_NCO_OUT_ENABLE0r, &enableReg, INTENf, enableReg); 1550 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE0r, 0, enableReg); /* 0:31 */ 1551 1552 } else if (chan < 64) { 1553 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE1r, 0, &enableReg); 1554 enableReg |= 1<<(chan-32); 1555 soc_reg_field_set(unit, NS_GDPLL_NCO_OUT_ENABLE1r, &enableReg, INTENf, enableReg); 1556 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE1r, 0, enableReg); /* 32:63 */ 1557 1558 } else if (chan < 96) { 1559 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE2r, 0, &enableReg); 1560 enableReg |= 1<<(chan-64); 1561 soc_reg_field_set(unit, NS_GDPLL_NCO_OUT_ENABLE2r, &enableReg, INTENf, enableReg); 1562 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE2r, 0, enableReg); /* 64:95 */ 1563 1564 } else if (chan < 128) { 1565 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE3r, 0, &enableReg); 1566 enableReg |= 1<<(chan-96); 1567 soc_reg_field_set(unit, NS_GDPLL_NCO_OUT_ENABLE3r, &enableReg, INTENf, enableReg); 1568 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE3r, 0, enableReg); /* 96:127 */ 1569 } 1570 1571 if (chan < 128) { 1572 /* Enable in the NS interrupt line */ 1573 sal_usleep(100); 1574 READ_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, &enableReg); 1575 enableReg |= INTR_GDPLL_OA_0_STATUS | INTR_GDPLL_OA_1_STATUS | 1576 INTR_GDPLL_OA_2_STATUS | INTR_GDPLL_OA_3_STATUS; 1577 WRITE_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, enableReg); 1578 } 1579 1580 } else { 1581 #endif 1582 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_HW_IDf, dest_hw_id); 1583 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_TYPEf, 1); 1584 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_HW_TYPEf, dest_hw_type); 1585 #ifdef BCN_WAR 1586 } 1587 #endif 1588 WRITE_NS_REGr(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, chan, regVal); 1589 1590 exit: 1591 return (rv); 1592 } 1593 1594 STATIC int 1595 _bcm_esw_gdpll_chan_out_misc_get(int unit, int chan, 1596 bcm_gdpll_output_event_t *pOutEvent) 1597 { 1598 int rv = BCM_E_NONE; 1599 1600 return (rv); 1601 } 1602 1603 #if 0 1604 STATIC int 1605 _bcm_esw_gdpll_chan_out_enable_set(int unit, int chan, int enable) 1606 { 1607 int rv = BCM_E_NONE; 1608 /* NS_GDPLL_NCO_UPDATE_COMMON_CONTROL */ 1609 1610 return (rv); 1611 } 1612 1613 STATIC int 1614 _bcm_esw_gdpll_chan_out_enable_get(int unit, int chan, 1615 int *pEnable) 1616 { 1617 int rv = BCM_E_NONE; 1618 1619 return (rv); 1620 } 1621 #endif 1622 1623 STATIC int 1624 soc_iproc_m7_write(int unit, uint32 addr, uint32 data) 1625 { 1626 if (soc_feature(unit, soc_feature_uc_mhost)) { 1627 soc_cm_iproc_write(unit, addr, data); 1628 return BCM_E_NONE; 1629 } 1630 return BCM_E_NONE; 1631 } 1632 1633 STATIC int 1634 soc_iproc_m7_read(int unit, uint32 addr) 1635 { 1636 if (soc_feature(unit, soc_feature_uc_mhost)) { 1637 return soc_cm_iproc_read(unit, addr); 1638 } 1639 return BCM_E_NONE; 1640 } 1641 1642 int 1643 _bcm_esw_gdpll_m7_status (int unit, uint8 *pBuff) 1644 { 1645 int rv = BCM_E_NONE; 1646 int count; 1647 int version_size = DPLL_FW_VERSION_SIZE; 1648 uint32 *pVersion; 1649 1650 uint32 m7AliveIndi = BCM_M7_DTCM_BASE + DPLL_ALIVE_OFFSET; 1651 uint32 versionAddr = BCM_M7_DTCM_BASE + DPLL_FW_VERSION_OFFSET; 1652 1653 pVersion = (uint32 *)pBuff; 1654 if (pBuff == NULL) { 1655 return BCM_E_PARAM; 1656 } 1657 1658 version_size = version_size / 4; 1659 soc_iproc_m7_write(unit, m7AliveIndi, 0); 1660 sal_usleep(100); 1661 if(soc_iproc_m7_read(unit, m7AliveIndi)) { 1662 /* M7 is alive */ 1663 for (count=0; count < version_size; count++) { 1664 *pVersion = soc_iproc_m7_read(unit, versionAddr); 1665 versionAddr = versionAddr + 4; 1666 pVersion++; 1667 } 1668 } else { 1669 return BCM_E_FAIL; 1670 } 1671 1672 return rv; 1673 } 1674 1675 /*STATIC int*/ 1676 int 1677 _bcm_esw_gdpll_chan_config_dpll_set(int unit, int chan, 1678 dpll_param_t *pDpllParam) 1679 { 1680 int rv = BCM_E_NONE; 1681 uint32 regVal = 0; 1682 #if defined(DPLL_VERSION_01) || defined(DPLL_VERSION_02) 1683 uint32 stateNum; 1684 uint32 count; 1685 uint32 dpllAddr = DPLL_CHAN_PARAM_ADDR(BCM_M7_DTCM_BASE, chan); 1686 uint32 *pData; 1687 #endif 1688 #if defined(DPLL_VERSION_01) 1689 uint8 serialzedData[DPLL_PARAM_SIZE] = {0}; 1690 #endif 1691 1692 if ((chan >= BCM_GDPLL_NUM_CHANNELS) || 1693 (pDpllParam == NULL)) { 1694 LOG_ERROR(BSL_LS_SOC_COMMON, 1695 (BSL_META_U(unit, 1696 "chan_config_dpll_set: Error !! invalid param\n"))); 1697 rv = BCM_E_PARAM; 1698 goto exit; 1699 } 1700 1701 #if defined (DPLL_VERSION_02) 1702 1703 1704 /* Clear the param memory */ 1705 sal_memset(&m7DpllParam, 0, sizeof(m7DpllParam)); 1706 1707 /* m7DpllParam.debugMode = pDpllParam->debugMode; */ 1708 1709 m7DpllParam.m7_dpll_config.DPLLNumOfStates = pDpllParam->dpll_config.dpll_num_states; 1710 for (stateNum = 0; stateNum < m7DpllParam.m7_dpll_config.DPLLNumOfStates; stateNum++) { 1711 m7DpllParam.m7_dpll_config.K1[stateNum] = pDpllParam->dpll_config.k1[stateNum]; 1712 m7DpllParam.m7_dpll_config.K1Shift[stateNum] = pDpllParam->dpll_config.k1Shift[stateNum]; 1713 m7DpllParam.m7_dpll_config.K1K2[stateNum] = pDpllParam->dpll_config.k1k2[stateNum]; 1714 m7DpllParam.m7_dpll_config.K1K2Shift[stateNum] = pDpllParam->dpll_config.k1k2Shift[stateNum]; 1715 m7DpllParam.m7_dpll_config.LockDetThres[stateNum] = pDpllParam->dpll_config.lockDetThres[stateNum]; 1716 m7DpllParam.m7_dpll_config.DwellCount[stateNum] = pDpllParam->dpll_config.dwell_count[stateNum]; 1717 m7DpllParam.m7_dpll_config.PhaseErrorLimiterThres[stateNum] = 1718 pDpllParam->dpll_config.phase_error_limiter_thres[stateNum]; 1719 m7DpllParam.m7_dpll_config.IdumpMod[stateNum] = pDpllParam->dpll_config.idump_mod[stateNum]; 1720 } 1721 1722 m7DpllParam.m7_dpll_config.LockIndicatorThresholdLo = pDpllParam->dpll_config.lockIndicatorThresholdLo; 1723 m7DpllParam.m7_dpll_config.LockIndicatorThresholdHi = pDpllParam->dpll_config.lockIndicatorThresholdLHi; 1724 1725 m7DpllParam.m7_dpll_config.NCObits = pDpllParam->dpll_config.nco_bits; 1726 m7DpllParam.m7_dpll_config.PhaseCounterRef = pDpllParam->dpll_config.phase_counter_ref; 1727 m7DpllParam.m7_dpll_config.PhaseErrorShift = pDpllParam->dpll_config.phase_error_shift; 1728 m7DpllParam.m7_dpll_config.NominalLoopFilter = pDpllParam->dpll_config.nominal_loop_filter; 1729 m7DpllParam.m7_dpll_config.InvertPhaseError = pDpllParam->dpll_config.invert_phase_error; 1730 1731 m7DpllParam.m7_dpll_config.NormalizePhaseError = pDpllParam->dpll_config.norm_phase_error; 1732 m7DpllParam.m7_dpll_config.NormPhaseErrorThres0 = pDpllParam->dpll_config.norm_phase_error_thres0; 1733 m7DpllParam.m7_dpll_config.NormPhaseErrorThres1 = pDpllParam->dpll_config.norm_phase_error_thres1; 1734 1735 m7DpllParam.m7_dpll_state.DPLLState = pDpllParam->dpll_state.dpll_state; 1736 m7DpllParam.m7_dpll_state.LoopFilter = pDpllParam->dpll_state.loop_filter; 1737 m7DpllParam.m7_dpll_state.DwellCounter = pDpllParam->dpll_state.dwell_counter; 1738 m7DpllParam.m7_dpll_state.LockDetFilter = pDpllParam->dpll_state.lockDetFilter; 1739 m7DpllParam.m7_dpll_state.Offset = pDpllParam->dpll_state.offset; 1740 m7DpllParam.m7_dpll_state.InitPhaseCounterFlag = pDpllParam->dpll_state.init_flag; 1741 m7DpllParam.m7_dpll_state.InitOffsetFlag = pDpllParam->dpll_state.init_offset_flag; 1742 m7DpllParam.m7_dpll_state.PhaseCounter = pDpllParam->dpll_state.phase_counter; 1743 m7DpllParam.m7_dpll_state.PhaseCounterDelta = pDpllParam->dpll_state.phaseCounterDelta; 1744 m7DpllParam.m7_dpll_state.PhaseCounterN = pDpllParam->dpll_state.phaseCounterN; 1745 m7DpllParam.m7_dpll_state.PhaseCounterM = pDpllParam->dpll_state.phaseCounterM; 1746 m7DpllParam.m7_dpll_state.PhaseCounterFrac = pDpllParam->dpll_state.phaseCounterFrac; 1747 m7DpllParam.m7_dpll_state.IdumpCounter = pDpllParam->dpll_state.idumpCounter; 1748 m7DpllParam.m7_dpll_state.AccumPhaseError = pDpllParam->dpll_state.accumPhaseError; 1749 m7DpllParam.m7_dpll_state.LockIndicator = 0; 1750 m7DpllParam.m7_dpll_state.LossOfLockIndicator = 0; 1751 m7DpllParam.m7_dpll_state.LargeErrorIndicator = 0; 1752 1753 /* Exclude the debugMode location as it will be programmed in debugMode API */ 1754 pData = (uint32 *)&m7DpllParam; pData++; 1755 dpllAddr += sizeof(uint32); 1756 1757 for (count = 0; count < sizeof(m7DpllParam)-4;) { 1758 soc_iproc_m7_write(unit, dpllAddr, *pData); 1759 pData++; 1760 count += sizeof(uint32); 1761 dpllAddr += sizeof(uint32); 1762 } 1763 1764 #elif defined(DPLL_VERSION_01) 1765 1766 /* Info - Copy to ITCM location for the given channel here 1767 * Verify that M7 also reads with proper offsets 1768 * Every field can also be accessed using 1769 * SAL_OFFSETOF(mos_msg_area_t, data[0].words[0]) 1770 */ 1771 /* Program the number of states */ 1772 serialzedData[DPLL_CONFIG_BASE_DPLLNUMSTATE] = pDpllParam->dpll_config.dpll_num_states; 1773 1774 /* Configure all states for the number of states passed */ 1775 for(stateNum=0; stateNum < pDpllParam->dpll_config.dpll_num_states; stateNum++) { 1776 1777 serialzedData[DPLL_CONFIG_BASE_K1 + SIZEOF_K1*stateNum] = pDpllParam->dpll_config.k1[stateNum]; 1778 serialzedData[DPLL_CONFIG_BASE_K1 + SIZEOF_K1*stateNum + 1] = pDpllParam->dpll_config.k1[stateNum] >> 8; 1779 if (SIZEOF_K1 > 2) { 1780 serialzedData[DPLL_CONFIG_BASE_K1 + SIZEOF_K1*stateNum + 2] = pDpllParam->dpll_config.k1[stateNum] >> 16; 1781 serialzedData[DPLL_CONFIG_BASE_K1 + SIZEOF_K1*stateNum + 3] = pDpllParam->dpll_config.k1[stateNum] >> 24; 1782 } 1783 serialzedData[DPLL_CONFIG_BASE_K1SHIFT + SIZEOF_K1SHIFT*stateNum] = pDpllParam->dpll_config.k1Shift[stateNum]; 1784 1785 serialzedData[DPLL_CONFIG_BASE_K1K2 + SIZEOF_K1K2*stateNum] = pDpllParam->dpll_config.k1k2[stateNum]; 1786 serialzedData[DPLL_CONFIG_BASE_K1K2 + SIZEOF_K1K2*stateNum+1] = pDpllParam->dpll_config.k1k2[stateNum] >>8; 1787 if (SIZEOF_K1K2 > 2) { 1788 serialzedData[DPLL_CONFIG_BASE_K1K2 + SIZEOF_K1K2*stateNum+2] = pDpllParam->dpll_config.k1k2[stateNum] >> 16; 1789 serialzedData[DPLL_CONFIG_BASE_K1K2 + SIZEOF_K1K2*stateNum+3] = pDpllParam->dpll_config.k1k2[stateNum] >> 24; 1790 } 1791 serialzedData[DPLL_CONFIG_BASE_K1K2SHIFT + SIZEOF_K1K2SHIFT*stateNum] = pDpllParam->dpll_config.k1k2Shift[stateNum]; 1792 1793 serialzedData[DPLL_CONFIG_BASE_K1K3 + SIZEOF_K1K3*stateNum] = pDpllParam->dpll_config.k1k3[stateNum]; 1794 serialzedData[DPLL_CONFIG_BASE_K1K3 + SIZEOF_K1K3*stateNum+1] = pDpllParam->dpll_config.k1k3[stateNum] >>8; 1795 if (SIZEOF_K1K3 > 2) { 1796 serialzedData[DPLL_CONFIG_BASE_K1K3 + SIZEOF_K1K3*stateNum+2] = pDpllParam->dpll_config.k1k3[stateNum] >> 16; 1797 serialzedData[DPLL_CONFIG_BASE_K1K3 + SIZEOF_K1K3*stateNum+3] = pDpllParam->dpll_config.k1k3[stateNum] >> 24; 1798 } 1799 serialzedData[DPLL_CONFIG_BASE_K1K3SHIFT + SIZEOF_K1K3SHIFT*stateNum] = pDpllParam->dpll_config.k1k3Shift[stateNum]; 1800 1801 serialzedData[DPLL_CONFIG_BASE_LOCKTHETHRE + SIZEOF_LOCKTHETHRE*stateNum] = pDpllParam->dpll_config.lockDetThres[stateNum]; 1802 serialzedData[DPLL_CONFIG_BASE_LOCKTHETHRE + SIZEOF_LOCKTHETHRE*stateNum+1] = pDpllParam->dpll_config.lockDetThres[stateNum]>>8; 1803 serialzedData[DPLL_CONFIG_BASE_LOCKTHETHRE + SIZEOF_LOCKTHETHRE*stateNum+2] = pDpllParam->dpll_config.lockDetThres[stateNum]>>16; 1804 serialzedData[DPLL_CONFIG_BASE_LOCKTHETHRE + SIZEOF_LOCKTHETHRE*stateNum+3] = pDpllParam->dpll_config.lockDetThres[stateNum]>>24; 1805 1806 serialzedData[DPLL_CONFIG_BASE_DWELLCNT + SIZEOF_DWELLCNT*stateNum] = pDpllParam->dpll_config.dwell_count[stateNum]; 1807 1808 serialzedData[DPLL_CONFIG_BASE_PELTHR_LOW + SIZEOF_PELTHR*stateNum] = 1809 u64_L(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum]); 1810 serialzedData[DPLL_CONFIG_BASE_PELTHR_LOW + SIZEOF_PELTHR*stateNum+1] = 1811 u64_L(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum])>>8; 1812 serialzedData[DPLL_CONFIG_BASE_PELTHR_LOW + SIZEOF_PELTHR*stateNum+2] = 1813 u64_L(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum])>>16; 1814 serialzedData[DPLL_CONFIG_BASE_PELTHR_LOW + SIZEOF_PELTHR*stateNum+3] = 1815 u64_L(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum])>>24; 1816 1817 serialzedData[DPLL_CONFIG_BASE_PELTHR_HIGH + SIZEOF_PELTHR*stateNum] = 1818 u64_H(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum]); 1819 serialzedData[DPLL_CONFIG_BASE_PELTHR_HIGH + SIZEOF_PELTHR*stateNum+1] = 1820 u64_H(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum])>>8; 1821 serialzedData[DPLL_CONFIG_BASE_PELTHR_HIGH + SIZEOF_PELTHR*stateNum+2] = 1822 u64_H(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum])>>16; 1823 serialzedData[DPLL_CONFIG_BASE_PELTHR_HIGH + SIZEOF_PELTHR*stateNum+3] = 1824 u64_H(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum])>>24; 1825 } 1826 1827 /* Read the maximum state value to set the remaining offsets */ 1828 stateNum = pDpllParam->dpll_config.dpll_num_states; 1829 1830 serialzedData[DPLL_CONFIG_BASE_FLLDEC] = pDpllParam->dpll_config.fll_decim_factor; 1831 serialzedData[DPLL_CONFIG_BASE_NCOBITS] = pDpllParam->dpll_config.nco_bits; 1832 serialzedData[DPLL_CONFIG_BASE_PHASECNTREF] = pDpllParam->dpll_config.phase_counter_ref; 1833 serialzedData[DPLL_CONFIG_BASE_DUALLOOPFLAG] = pDpllParam->dpll_config.dual_loop_flag; 1834 1835 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_LOW] = u64_L(pDpllParam->dpll_config.phase_counter_delta); 1836 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_LOW+1] = u64_L(pDpllParam->dpll_config.phase_counter_delta)>>8; 1837 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_LOW+2] = u64_L(pDpllParam->dpll_config.phase_counter_delta)>>16; 1838 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_LOW+3] = u64_L(pDpllParam->dpll_config.phase_counter_delta)>>24; 1839 1840 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_HIGH] = u64_H(pDpllParam->dpll_config.phase_counter_delta); 1841 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_HIGH+1] = u64_H(pDpllParam->dpll_config.phase_counter_delta)>>8; 1842 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_HIGH+2] = u64_H(pDpllParam->dpll_config.phase_counter_delta)>>16; 1843 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_HIGH+3] = u64_H(pDpllParam->dpll_config.phase_counter_delta)>>24; 1844 1845 serialzedData[DPLL_STATE_BASE_STATE] = pDpllParam->dpll_state.dpll_state; 1846 1847 serialzedData[DPLL_STATE_BASE_LOOPF_LOW] = u64_L(pDpllParam->dpll_state.loop_filter); 1848 serialzedData[DPLL_STATE_BASE_LOOPF_LOW+1] = u64_L(pDpllParam->dpll_state.loop_filter)>>8; 1849 serialzedData[DPLL_STATE_BASE_LOOPF_LOW+2] = u64_L(pDpllParam->dpll_state.loop_filter)>>16; 1850 serialzedData[DPLL_STATE_BASE_LOOPF_LOW+3] = u64_L(pDpllParam->dpll_state.loop_filter)>>24; 1851 1852 serialzedData[DPLL_STATE_BASE_LOOPF_HIGH] = u64_H(pDpllParam->dpll_state.loop_filter); 1853 serialzedData[DPLL_STATE_BASE_LOOPF_HIGH+1] = u64_H(pDpllParam->dpll_state.loop_filter)>>8; 1854 serialzedData[DPLL_STATE_BASE_LOOPF_HIGH+2] = u64_H(pDpllParam->dpll_state.loop_filter)>>16; 1855 serialzedData[DPLL_STATE_BASE_LOOPF_HIGH+3] = u64_H(pDpllParam->dpll_state.loop_filter)>>24; 1856 1857 serialzedData[DPLL_STATE_BASE_DWELLCNT] = pDpllParam->dpll_state.dwell_counter; 1858 serialzedData[DPLL_STATE_BASE_DWELLCNT+1] = pDpllParam->dpll_state.dwell_counter >>8; 1859 serialzedData[DPLL_STATE_BASE_DWELLCNT+2] = pDpllParam->dpll_state.dwell_counter >>16; 1860 serialzedData[DPLL_STATE_BASE_DWELLCNT+3] = pDpllParam->dpll_state.dwell_counter >>24; 1861 1862 serialzedData[DPLL_STATE_BASE_LOCKDETF] = pDpllParam->dpll_state.lockDetFilter; 1863 serialzedData[DPLL_STATE_BASE_LOCKDETF+1] = pDpllParam->dpll_state.lockDetFilter >>8; 1864 serialzedData[DPLL_STATE_BASE_LOCKDETF+2] = pDpllParam->dpll_state.lockDetFilter >>16; 1865 serialzedData[DPLL_STATE_BASE_LOCKDETF+3] = pDpllParam->dpll_state.lockDetFilter >>24; 1866 1867 serialzedData[DPLL_STATE_BASE_PERROR_LOW] = u64_L(pDpllParam->dpll_state.prev_perror); 1868 serialzedData[DPLL_STATE_BASE_PERROR_LOW+1] = u64_L(pDpllParam->dpll_state.prev_perror)>>8; 1869 serialzedData[DPLL_STATE_BASE_PERROR_LOW+2] = u64_L(pDpllParam->dpll_state.prev_perror)>>16; 1870 serialzedData[DPLL_STATE_BASE_PERROR_LOW+3] = u64_L(pDpllParam->dpll_state.prev_perror)>>24; 1871 1872 serialzedData[DPLL_STATE_BASE_PERROR_HIGH] = u64_H(pDpllParam->dpll_state.prev_perror); 1873 serialzedData[DPLL_STATE_BASE_PERROR_HIGH+1] = u64_H(pDpllParam->dpll_state.prev_perror)>>8; 1874 serialzedData[DPLL_STATE_BASE_PERROR_HIGH+2] = u64_H(pDpllParam->dpll_state.prev_perror)>>16; 1875 serialzedData[DPLL_STATE_BASE_PERROR_HIGH+3] = u64_H(pDpllParam->dpll_state.prev_perror)>>24; 1876 1877 serialzedData[DPLL_STATE_BASE_FERROR_LOW] = u64_L(pDpllParam->dpll_state.ferror); 1878 serialzedData[DPLL_STATE_BASE_FERROR_LOW+1] = u64_L(pDpllParam->dpll_state.ferror)>>8; 1879 serialzedData[DPLL_STATE_BASE_FERROR_LOW+2] = u64_L(pDpllParam->dpll_state.ferror)>>16; 1880 serialzedData[DPLL_STATE_BASE_FERROR_LOW+3] = u64_L(pDpllParam->dpll_state.ferror)>>24; 1881 1882 serialzedData[DPLL_STATE_BASE_FERROR_HIGH] = u64_H(pDpllParam->dpll_state.ferror); 1883 serialzedData[DPLL_STATE_BASE_FERROR_HIGH+1] = u64_H(pDpllParam->dpll_state.ferror)>>8; 1884 serialzedData[DPLL_STATE_BASE_FERROR_HIGH+2] = u64_H(pDpllParam->dpll_state.ferror)>>16; 1885 serialzedData[DPLL_STATE_BASE_FERROR_HIGH+3] = u64_H(pDpllParam->dpll_state.ferror)>>24; 1886 1887 serialzedData[DPLL_STATE_BASE_FLLCNT] = pDpllParam->dpll_state.fll_decim_counter; 1888 serialzedData[DPLL_STATE_BASE_1STLOOP] = pDpllParam->dpll_state.first_order_loop_transition; 1889 serialzedData[DPLL_STATE_BASE_INITFLAG] = pDpllParam->dpll_state.init_flag; 1890 1891 serialzedData[DPLL_STATE_BASE_PHASECNT_LOW] = u64_L(pDpllParam->dpll_state.phase_counter); 1892 serialzedData[DPLL_STATE_BASE_PHASECNT_LOW+1] = u64_L(pDpllParam->dpll_state.phase_counter)>>8; 1893 serialzedData[DPLL_STATE_BASE_PHASECNT_LOW+2] = u64_L(pDpllParam->dpll_state.phase_counter)>>16; 1894 serialzedData[DPLL_STATE_BASE_PHASECNT_LOW+3] = u64_L(pDpllParam->dpll_state.phase_counter)>>24; 1895 1896 serialzedData[DPLL_STATE_BASE_PHASECNT_HIGH] = u64_H(pDpllParam->dpll_state.phase_counter); 1897 serialzedData[DPLL_STATE_BASE_PHASECNT_HIGH+1] = u64_H(pDpllParam->dpll_state.phase_counter)>>8; 1898 serialzedData[DPLL_STATE_BASE_PHASECNT_HIGH+2] = u64_H(pDpllParam->dpll_state.phase_counter)>>16; 1899 serialzedData[DPLL_STATE_BASE_PHASECNT_HIGH+3] = u64_H(pDpllParam->dpll_state.phase_counter)>>24; 1900 1901 /*Exclude the debugMode location */ 1902 pData = (uint32 *)(serialzedData+4); 1903 dpllAddr += sizeof(uint32); 1904 1905 for (count = 0; count < DPLL_PARAM_SIZE-8;) { 1906 soc_iproc_m7_write(unit, dpllAddr, *pData); 1907 pData++; 1908 count += sizeof(uint32); 1909 dpllAddr += sizeof(uint32); 1910 } 1911 #endif 1912 1913 /* Update the channel for phase counter reference */ 1914 bsl_printf("GDPLL: Set the phase counter ref\n"); 1915 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, ®Val); 1916 soc_reg_field_set(unit, NS_GDPLL_IA_UPDATE_CONFIGr, ®Val, PHASECOUNTERREFf, 1917 pDpllParam->dpll_config.phase_counter_ref ? 1:0); 1918 WRITE_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, regVal); 1919 1920 exit: 1921 return (rv); 1922 } 1923 1924 /*STATIC int*/ 1925 int 1926 _bcm_esw_gdpll_chan_config_dpll_get(int unit, int chan, 1927 dpll_param_t *pDpllParam) 1928 { 1929 int rv = BCM_E_NONE; 1930 #if defined(DPLL_VERSION_01) 1931 uint32 stateNum; 1932 uint8 serialzedData[DPLL_PARAM_SIZE] = {0}; 1933 #endif 1934 uint32 count; 1935 uint32 dpllAddr = DPLL_CHAN_PARAM_ADDR(BCM_M7_DTCM_BASE, chan); 1936 uint32 *pData; 1937 uint32 stateNum; 1938 1939 #if defined(DPLL_VERSION_01) 1940 pData = (uint32 *)serialzedData; 1941 #endif 1942 #if defined(DPLL_VERSION_02) 1943 pData = (uint32 *)&m7DpllParam; 1944 #endif 1945 1946 if ((chan >= BCM_GDPLL_NUM_CHANNELS) || 1947 (pDpllParam == NULL)) { 1948 LOG_ERROR(BSL_LS_SOC_COMMON, 1949 (BSL_META_U(unit, 1950 "chan_config_dpll_get: Error !! invalid param\n"))); 1951 rv = BCM_E_PARAM; 1952 goto exit; 1953 } 1954 1955 /* Read the DTCM locations for DPLL config */ 1956 for (count = 0; count < sizeof(m7_dpll_param_t);) { 1957 *pData = soc_iproc_m7_read(unit, dpllAddr); 1958 pData++; 1959 count += sizeof(uint32); 1960 dpllAddr += sizeof(uint32); 1961 } 1962 1963 #if defined (DPLL_VERSION_02) 1964 pDpllParam->debugMode = m7DpllParam.debugMode; 1965 pDpllParam->dpll_config.dpll_num_states = m7DpllParam.m7_dpll_config.DPLLNumOfStates; 1966 1967 for (stateNum = 0; stateNum < m7DpllParam.m7_dpll_config.DPLLNumOfStates; stateNum++) { 1968 pDpllParam->dpll_config.k1[stateNum] = m7DpllParam.m7_dpll_config.K1[stateNum]; 1969 pDpllParam->dpll_config.k1Shift[stateNum] = m7DpllParam.m7_dpll_config.K1Shift[stateNum]; 1970 pDpllParam->dpll_config.k1k2[stateNum] = m7DpllParam.m7_dpll_config.K1K2[stateNum]; 1971 pDpllParam->dpll_config.k1k2Shift[stateNum] = m7DpllParam.m7_dpll_config.K1K2Shift[stateNum]; 1972 pDpllParam->dpll_config.lockDetThres[stateNum] = m7DpllParam.m7_dpll_config.LockDetThres[stateNum]; 1973 pDpllParam->dpll_config.dwell_count[stateNum] = m7DpllParam.m7_dpll_config.DwellCount[stateNum]; 1974 pDpllParam->dpll_config.phase_error_limiter_thres[stateNum] = 1975 m7DpllParam.m7_dpll_config.PhaseErrorLimiterThres[stateNum]; 1976 pDpllParam->dpll_config.idump_mod[stateNum] = m7DpllParam.m7_dpll_config.IdumpMod[stateNum]; 1977 } 1978 1979 pDpllParam->dpll_config.lockIndicatorThresholdLo = m7DpllParam.m7_dpll_config.LockIndicatorThresholdLo; 1980 pDpllParam->dpll_config.lockIndicatorThresholdLHi = m7DpllParam.m7_dpll_config.LockIndicatorThresholdHi; 1981 1982 pDpllParam->dpll_config.nco_bits = m7DpllParam.m7_dpll_config.NCObits; 1983 pDpllParam->dpll_config.phase_counter_ref = m7DpllParam.m7_dpll_config.PhaseCounterRef; 1984 pDpllParam->dpll_config.phase_error_shift = m7DpllParam.m7_dpll_config.PhaseErrorShift; 1985 pDpllParam->dpll_config.nominal_loop_filter = m7DpllParam.m7_dpll_config.NominalLoopFilter; 1986 pDpllParam->dpll_config.invert_phase_error = m7DpllParam.m7_dpll_config.InvertPhaseError; 1987 1988 pDpllParam->dpll_config.norm_phase_error = m7DpllParam.m7_dpll_config.NormalizePhaseError; 1989 pDpllParam->dpll_config.norm_phase_error_thres0 = m7DpllParam.m7_dpll_config.NormPhaseErrorThres0; 1990 pDpllParam->dpll_config.norm_phase_error_thres1 = m7DpllParam.m7_dpll_config.NormPhaseErrorThres1; 1991 1992 pDpllParam->dpll_state.dpll_state = m7DpllParam.m7_dpll_state.DPLLState; 1993 pDpllParam->dpll_state.loop_filter = m7DpllParam.m7_dpll_state.LoopFilter; 1994 pDpllParam->dpll_state.dwell_counter = m7DpllParam.m7_dpll_state.DwellCounter; 1995 pDpllParam->dpll_state.lockDetFilter = m7DpllParam.m7_dpll_state.LockDetFilter; 1996 pDpllParam->dpll_state.offset = m7DpllParam.m7_dpll_state.Offset; 1997 pDpllParam->dpll_state.init_flag = m7DpllParam.m7_dpll_state.InitPhaseCounterFlag; 1998 pDpllParam->dpll_state.init_offset_flag = m7DpllParam.m7_dpll_state.InitOffsetFlag; 1999 pDpllParam->dpll_state.phase_counter = m7DpllParam.m7_dpll_state.PhaseCounter; 2000 pDpllParam->dpll_state.phaseCounterDelta = m7DpllParam.m7_dpll_state.PhaseCounterDelta; 2001 pDpllParam->dpll_state.phaseCounterN = m7DpllParam.m7_dpll_state.PhaseCounterN; 2002 pDpllParam->dpll_state.phaseCounterM = m7DpllParam.m7_dpll_state.PhaseCounterM; 2003 pDpllParam->dpll_state.phaseCounterFrac = m7DpllParam.m7_dpll_state.PhaseCounterFrac; 2004 pDpllParam->dpll_state.idumpCounter = m7DpllParam.m7_dpll_state.IdumpCounter; 2005 pDpllParam->dpll_state.accumPhaseError = m7DpllParam.m7_dpll_state.AccumPhaseError; 2006 pDpllParam->dpll_state.lockIndicator = m7DpllParam.m7_dpll_state.LockIndicator; 2007 pDpllParam->dpll_state.lossOfLockIndicator = m7DpllParam.m7_dpll_state.LossOfLockIndicator; 2008 2009 #elif defined(DPLL_VERSION_01) 2010 /* Get the debug mode */ 2011 pDpllParam->debugMode = serialzedData[DPLL_DEBUG_MODE]; 2012 2013 /* Get number of states */ 2014 pDpllParam->dpll_config.dpll_num_states = serialzedData[DPLL_CONFIG_BASE_DPLLNUMSTATE]; 2015 2016 /* Configure all states for the number of states passed */ 2017 for(stateNum=0; stateNum < pDpllParam->dpll_config.dpll_num_states; stateNum++) { 2018 pDpllParam->dpll_config.k1[stateNum] = serialzedData[DPLL_CONFIG_BASE_K1 + 2*stateNum] | 2019 serialzedData[DPLL_CONFIG_BASE_K1 + 2*stateNum +1] << 8; 2020 if (SIZEOF_K1 > 2) { 2021 pDpllParam->dpll_config.k1[stateNum] |= serialzedData[DPLL_CONFIG_BASE_K1 + 2*stateNum +2] << 16 | 2022 serialzedData[DPLL_CONFIG_BASE_K1 + 2*stateNum +3] << 24; 2023 } 2024 2025 pDpllParam->dpll_config.k1Shift[stateNum] = serialzedData[DPLL_CONFIG_BASE_K1SHIFT + 1*stateNum]; 2026 2027 pDpllParam->dpll_config.k1k2[stateNum] = serialzedData[DPLL_CONFIG_BASE_K1K2 + 2*stateNum] | 2028 serialzedData[DPLL_CONFIG_BASE_K1K2 + 2*stateNum+1] <<8; 2029 if (SIZEOF_K1K2 > 2) { 2030 pDpllParam->dpll_config.k1k2[stateNum] |= serialzedData[DPLL_CONFIG_BASE_K1K2 + 2*stateNum +2] << 16 | 2031 serialzedData[DPLL_CONFIG_BASE_K1K2 + 2*stateNum+3] <<24; 2032 } 2033 2034 pDpllParam->dpll_config.k1k2Shift[stateNum] = serialzedData[DPLL_CONFIG_BASE_K1K2SHIFT + 1*stateNum]; 2035 2036 pDpllParam->dpll_config.k1k3[stateNum] = serialzedData[DPLL_CONFIG_BASE_K1K3 + 2*stateNum] | 2037 serialzedData[DPLL_CONFIG_BASE_K1K3 + 2*stateNum+1]<<8; 2038 if (SIZEOF_K1K3 > 2) { 2039 pDpllParam->dpll_config.k1k3[stateNum] |= serialzedData[DPLL_CONFIG_BASE_K1K3 + 2*stateNum +2] << 16 | 2040 serialzedData[DPLL_CONFIG_BASE_K1K3 + 2*stateNum+3]<<24; 2041 } 2042 2043 pDpllParam->dpll_config.k1k3Shift[stateNum] = serialzedData[DPLL_CONFIG_BASE_K1K3SHIFT + 1*stateNum]; 2044 2045 pDpllParam->dpll_config.lockDetThres[stateNum] = serialzedData[DPLL_CONFIG_BASE_LOCKTHETHRE + 4*stateNum] | 2046 serialzedData[DPLL_CONFIG_BASE_LOCKTHETHRE + 4*stateNum+1] <<8 | 2047 serialzedData[DPLL_CONFIG_BASE_LOCKTHETHRE + 4*stateNum+2] <<16 | 2048 serialzedData[DPLL_CONFIG_BASE_LOCKTHETHRE + 4*stateNum+3] <<24; 2049 2050 pDpllParam->dpll_config.dwell_count[stateNum] = serialzedData[DPLL_CONFIG_BASE_DWELLCNT + 1*stateNum]; 2051 2052 u64_L(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum]) = 2053 serialzedData[DPLL_CONFIG_BASE_PELTHR_LOW + 8*stateNum] | 2054 serialzedData[DPLL_CONFIG_BASE_PELTHR_LOW + 8*stateNum+1] <<8 | 2055 serialzedData[DPLL_CONFIG_BASE_PELTHR_LOW + 8*stateNum+2] <<16 | 2056 serialzedData[DPLL_CONFIG_BASE_PELTHR_LOW + 8*stateNum+3] << 24; 2057 2058 u64_H(pDpllParam->dpll_config.phase_error_limiter_thres[stateNum]) = 2059 serialzedData[DPLL_CONFIG_BASE_PELTHR_HIGH + 8*stateNum] | 2060 serialzedData[DPLL_CONFIG_BASE_PELTHR_HIGH + 8*stateNum+1] << 8 | 2061 serialzedData[DPLL_CONFIG_BASE_PELTHR_HIGH + 8*stateNum+2] << 16 | 2062 serialzedData[DPLL_CONFIG_BASE_PELTHR_HIGH + 8*stateNum+3] <<24; 2063 } 2064 2065 pDpllParam->dpll_config.fll_decim_factor = serialzedData[DPLL_CONFIG_BASE_FLLDEC]; 2066 pDpllParam->dpll_config.nco_bits = serialzedData[DPLL_CONFIG_BASE_NCOBITS]; 2067 pDpllParam->dpll_config.phase_counter_ref = serialzedData[DPLL_CONFIG_BASE_PHASECNTREF]; 2068 pDpllParam->dpll_config.dual_loop_flag = serialzedData[DPLL_CONFIG_BASE_DUALLOOPFLAG]; 2069 2070 u64_L(pDpllParam->dpll_config.phase_counter_delta)= serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_LOW] | 2071 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_LOW+1]<<8 | 2072 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_LOW+2]<<16 | 2073 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_LOW+3]<<24; 2074 2075 u64_H(pDpllParam->dpll_config.phase_counter_delta) = serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_HIGH] | 2076 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_HIGH+1]<<8 | 2077 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_HIGH+2]<<16 | 2078 serialzedData[DPLL_CONFIG_BASE_PHASECNTDELTA_HIGH+3]<<24; 2079 2080 pDpllParam->dpll_state.dpll_state = serialzedData[DPLL_STATE_BASE_STATE]; 2081 2082 u64_L(pDpllParam->dpll_state.loop_filter) = serialzedData[DPLL_STATE_BASE_LOOPF_LOW] | 2083 serialzedData[DPLL_STATE_BASE_LOOPF_LOW+1]<<8 | 2084 serialzedData[DPLL_STATE_BASE_LOOPF_LOW+2]<<16 | 2085 serialzedData[DPLL_STATE_BASE_LOOPF_LOW+3]<<24; 2086 2087 u64_H(pDpllParam->dpll_state.loop_filter) = serialzedData[DPLL_STATE_BASE_LOOPF_HIGH] | 2088 serialzedData[DPLL_STATE_BASE_LOOPF_HIGH+1]<<8 | 2089 serialzedData[DPLL_STATE_BASE_LOOPF_HIGH+2]<<16 | 2090 serialzedData[DPLL_STATE_BASE_LOOPF_HIGH+3]<<24; 2091 2092 pDpllParam->dpll_state.dwell_counter = serialzedData[DPLL_STATE_BASE_DWELLCNT] | 2093 serialzedData[DPLL_STATE_BASE_DWELLCNT+1]<<8 | 2094 serialzedData[DPLL_STATE_BASE_DWELLCNT+2]<<16 | 2095 serialzedData[DPLL_STATE_BASE_DWELLCNT+3]<<24; 2096 2097 pDpllParam->dpll_state.lockDetFilter = serialzedData[DPLL_STATE_BASE_LOCKDETF] | 2098 serialzedData[DPLL_STATE_BASE_LOCKDETF+1]<<8 | 2099 serialzedData[DPLL_STATE_BASE_LOCKDETF+2]<<16 | 2100 serialzedData[DPLL_STATE_BASE_LOCKDETF+3]<<24; 2101 2102 u64_L(pDpllParam->dpll_state.prev_perror) = serialzedData[DPLL_STATE_BASE_PERROR_LOW] | 2103 serialzedData[DPLL_STATE_BASE_PERROR_LOW+1]<<8 | 2104 serialzedData[DPLL_STATE_BASE_PERROR_LOW+2]<<16 | 2105 serialzedData[DPLL_STATE_BASE_PERROR_LOW+3]<<24; 2106 2107 u64_H(pDpllParam->dpll_state.prev_perror) = serialzedData[DPLL_STATE_BASE_PERROR_HIGH] | 2108 serialzedData[DPLL_STATE_BASE_PERROR_HIGH+1]<<8 | 2109 serialzedData[DPLL_STATE_BASE_PERROR_HIGH+2]<<16 | 2110 serialzedData[DPLL_STATE_BASE_PERROR_HIGH+3]<<24; 2111 2112 u64_L(pDpllParam->dpll_state.ferror) = serialzedData[DPLL_STATE_BASE_FERROR_LOW] | 2113 serialzedData[DPLL_STATE_BASE_FERROR_LOW+1]<<8 | 2114 serialzedData[DPLL_STATE_BASE_FERROR_LOW+2]<<16 | 2115 serialzedData[DPLL_STATE_BASE_FERROR_LOW+3]<<24; 2116 2117 u64_H(pDpllParam->dpll_state.ferror) = serialzedData[DPLL_STATE_BASE_FERROR_HIGH] | 2118 serialzedData[DPLL_STATE_BASE_FERROR_HIGH+1]<<8 | 2119 serialzedData[DPLL_STATE_BASE_FERROR_HIGH+2]<<16 | 2120 serialzedData[DPLL_STATE_BASE_FERROR_HIGH+3]<<24; 2121 2122 pDpllParam->dpll_state.fll_decim_counter = serialzedData[DPLL_STATE_BASE_FLLCNT]; 2123 pDpllParam->dpll_state.first_order_loop_transition = serialzedData[DPLL_STATE_BASE_1STLOOP]; 2124 pDpllParam->dpll_state.init_flag = serialzedData[DPLL_STATE_BASE_INITFLAG]; 2125 2126 u64_L(pDpllParam->dpll_state.phase_counter) = serialzedData[DPLL_STATE_BASE_PHASECNT_LOW] | 2127 serialzedData[DPLL_STATE_BASE_PHASECNT_LOW+1]<<8 | 2128 serialzedData[DPLL_STATE_BASE_PHASECNT_LOW+2]<<16 | 2129 serialzedData[DPLL_STATE_BASE_PHASECNT_LOW+3]<<24; 2130 2131 u64_H(pDpllParam->dpll_state.phase_counter) = serialzedData[DPLL_STATE_BASE_PHASECNT_HIGH] | 2132 serialzedData[DPLL_STATE_BASE_PHASECNT_HIGH+1]<<8 | 2133 serialzedData[DPLL_STATE_BASE_PHASECNT_HIGH+2]<<16 | 2134 serialzedData[DPLL_STATE_BASE_PHASECNT_HIGH+3]<<24; 2135 #endif 2136 exit: 2137 return (rv); 2138 } 2139 2140 STATIC int 2141 _bcm_esw_gdpll_debug_enable_set(int unit, int enable) 2142 { 2143 /* This API may not be required as the debugging is 2144 * always enabled during the init API 2145 */ 2146 int rv = BCM_E_NONE; 2147 2148 return (rv); 2149 } 2150 2151 STATIC int 2152 _bcm_esw_gdpll_chan_debug_mode_set(int unit, int chan, 2153 bcm_gdpll_debug_mode_t debugMode) 2154 { 2155 int rv = BCM_E_NONE; 2156 uint32 dpll_debugMode; 2157 uint32 dpllAddr = DPLL_CHAN_PARAM_ADDR(BCM_M7_DTCM_BASE, chan); 2158 2159 /* Info - debugEnable debugMode addresses visible by M7 */ 2160 dpll_debugMode = dpllAddr + 0/*DPLL_DEBUG_MODE*/; 2161 2162 /* M7 ITCM configuration, for the desired debug mode */ 2163 soc_iproc_m7_write(unit, dpll_debugMode, debugMode); 2164 2165 return (rv); 2166 } 2167 2168 int 2169 _bcm_esw_gdpll_holdover_set(int unit, int chan, uint64 NominalLoopFilter, 2170 uint8 enable) 2171 { 2172 int rv = BCM_E_NONE; 2173 uint32 dpllAddr = DPLL_CHAN_PARAM_ADDR(BCM_M7_DTCM_BASE, chan); 2174 uint32 addrOff_holdover, addrOff_loopFilter; 2175 uint32 regVal; 2176 2177 addrOff_holdover = SAL_OFFSETOF(m7_dpll_param_t, m7_dpll_state.HoldoverFlag); 2178 addrOff_loopFilter = SAL_OFFSETOF(m7_dpll_param_t, m7_dpll_config.NominalLoopFilter); 2179 2180 if (enable) { 2181 /* If holdover set, then update the NominalLoopFilter */ 2182 soc_iproc_m7_write(unit, dpllAddr+addrOff_loopFilter, u64_L(NominalLoopFilter)); 2183 soc_iproc_m7_write(unit, dpllAddr+addrOff_loopFilter+4, u64_H(NominalLoopFilter)); 2184 } 2185 2186 /* Set the holdover flag */ 2187 regVal = soc_iproc_m7_read(unit, dpllAddr+addrOff_holdover); 2188 regVal = enable ? regVal | 0x1 : regVal & (~0x1); 2189 soc_iproc_m7_write(unit, dpllAddr+addrOff_holdover, regVal); 2190 2191 /* Set the phasecounter flag to enable the HW to trigger M7 on 2192 * feedback OR the fb/ref pair 2193 */ 2194 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, ®Val); 2195 soc_reg_field_set(unit, NS_GDPLL_IA_UPDATE_CONFIGr, ®Val, PHASECOUNTERREFf, 2196 enable ? 1:0); 2197 WRITE_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, regVal); 2198 2199 return rv; 2200 } 2201 2202 int 2203 _bcm_esw_gdpll_offset_set(int unit, int chan, 2204 uint64 Offset) 2205 { 2206 int rv = BCM_E_NONE; 2207 uint32 dpllAddr = DPLL_CHAN_PARAM_ADDR(BCM_M7_DTCM_BASE, chan); 2208 uint32 addrOffset; 2209 dpll_param_t dpllParam; 2210 2211 /* Check if the InitOffsetFlag is set */ 2212 if(_bcm_esw_gdpll_chan_config_dpll_get(unit, chan, 2213 &dpllParam) != BCM_E_NONE) { 2214 rv = BCM_E_INTERNAL; 2215 goto exit; 2216 } 2217 2218 if (dpllParam.dpll_state.init_offset_flag) { 2219 bsl_printf("GDPLL: offset_set: Error !! InitOffsetFlag is set\n"); 2220 rv = BCM_E_INTERNAL; 2221 goto exit; 2222 } 2223 2224 addrOffset = SAL_OFFSETOF(m7_dpll_param_t, m7_dpll_state.Offset); 2225 2226 /* Check if the address is non-word aligned */ 2227 if ((dpllAddr+addrOffset)%4) { 2228 bsl_printf("GDPLL: offset_set: Error !! Offset field at offset:%d\n", addrOffset); 2229 rv = BCM_E_INTERNAL; 2230 goto exit; 2231 } 2232 2233 /* M7 DTCM configuration, for the Offset update */ 2234 soc_iproc_m7_write(unit, dpllAddr+addrOffset, u64_L(Offset)); 2235 soc_iproc_m7_write(unit, dpllAddr+addrOffset+4, u64_H(Offset)); 2236 2237 exit: 2238 return (rv); 2239 } 2240 2241 int 2242 _bcm_esw_gdpll_offset_get(int unit, int chan, 2243 uint64 *pOffset) 2244 { 2245 int rv = BCM_E_NONE; 2246 uint32 dpllAddr = DPLL_CHAN_PARAM_ADDR(BCM_M7_DTCM_BASE, chan); 2247 uint32 addrOffset; 2248 2249 addrOffset = SAL_OFFSETOF(m7_dpll_param_t, m7_dpll_state.Offset); 2250 2251 /* Check if the address is non-word aligned */ 2252 if ((dpllAddr+addrOffset)%4) { 2253 bsl_printf("GDPLL: offset_get: Error !! Offset field at offset:%d\n", addrOffset); 2254 rv = BCM_E_INTERNAL; 2255 goto exit; 2256 } 2257 2258 /* M7 DTCM configuration, for the Offset update */ 2259 u64_L(*pOffset) = soc_iproc_m7_read(unit, dpllAddr+addrOffset); 2260 u64_H(*pOffset) = soc_iproc_m7_read(unit, dpllAddr+addrOffset+4); 2261 2262 exit: 2263 return (rv); 2264 } 2265 2266 STATIC int 2267 _bcm_esw_gdpll_chan_debug_mode_get(int unit, int chan, 2268 bcm_gdpll_debug_mode_t *pDebugMode) 2269 { 2270 int rv = BCM_E_NONE; 2271 2272 return (rv); 2273 } 2274 2275 STATIC int 2276 _bcm_esw_gdpll_deinit(int unit) 2277 { 2278 int rv = BCM_E_NONE; 2279 gdpll_context_t *pGdpllContext = pGdpllCtx; 2280 2281 /* Destroy protection mutex. */ 2282 if (NULL != pGdpllContext->mutex) { 2283 sal_mutex_destroy(pGdpllContext->mutex); 2284 pGdpllContext->mutex = NULL; 2285 } 2286 2287 return (rv); 2288 } 2289 2290 void 2291 gdpll_debug_buffer_send_thread(void *unit_vp) 2292 { 2293 int unit = PTR_TO_INT(unit_vp); 2294 gdpll_context_t *pGdpllContext = pGdpllCtx; 2295 uint32 regVal; 2296 uint32 dpllDebugFlag = BCM_M7_DTCM_BASE + DPLL_DEBUG_ENABLE_OFFSET; 2297 2298 if (pGdpllContext == NULL) { 2299 LOG_ERROR(BSL_LS_SOC_COMMON, 2300 (BSL_META_U(unit, 2301 "gdpll_debug_buffer_send_thread: Error !! context not setup\n"))); 2302 return; 2303 2304 } 2305 2306 while(1) { 2307 /* Wait on the signal from the ISR */ 2308 (void)sal_sem_take(pGdpllContext->debug_sem, sal_sem_FOREVER); 2309 if (pGdpllContext->debug_cb && soc_iproc_m7_read (unit, dpllDebugFlag)) { 2310 /* Return of this cb confirms the buffer consumption */ 2311 pGdpllContext->debug_cb(unit, pGdpllContext->pUserData, 2312 (BCM_GDPLL_DEBUG_BUFFER_START + (pGdpllContext->debugRdIdx * 4)), 2313 BCM_GDPLL_DEBUG_THRESHOLD); 2314 } 2315 2316 READ_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_RSTATEr, 0, ®Val); 2317 pGdpllContext->debugRdIdx = regVal; 2318 2319 } 2320 } 2321 2322 STATIC int 2323 _bcm_update_tod_ptpntp(int unit, int chan_num, bcm_gdpll_output_event_t event) 2324 { 2325 uint32 nco_hi, nco_lo; 2326 2327 2328 if (chan_num == 0) { 2329 READ_NS_REGr(unit, NS_GDPLL_OUTPUT_ARRAY_000_MSBr, 0, &nco_hi); 2330 READ_NS_REGr(unit, NS_GDPLL_OUTPUT_ARRAY_000_LSBr, 0, &nco_lo); 2331 } else if (chan_num == 1) { 2332 READ_NS_REGr(unit, NS_GDPLL_OUTPUT_ARRAY_001_MSBr, 0, &nco_hi); 2333 READ_NS_REGr(unit, NS_GDPLL_OUTPUT_ARRAY_001_LSBr, 0, &nco_lo); 2334 } else if (chan_num == 2) { 2335 READ_NS_REGr(unit, NS_GDPLL_OUTPUT_ARRAY_002_MSBr, 0, &nco_hi); 2336 READ_NS_REGr(unit, NS_GDPLL_OUTPUT_ARRAY_002_LSBr, 0, &nco_lo); 2337 } else { 2338 bsl_printf("GDPLL: WARN !! Implement the NCO read from chan:%d\n", chan_num); 2339 return BCM_E_NONE; 2340 } 2341 2342 if (event == 10/*bcmGdpllOutputEventNTPTOD*/) { 2343 WRITE_NTP_TIME_FREQ_CONTROLr(unit, nco_lo); 2344 } else if (event == 11/*bcmGdpllOutputEventPTPTOD*/) { 2345 WRITE_IEEE1588_TIME_FREQ_CONTROLr(unit, nco_lo); 2346 } 2347 2348 return BCM_E_NONE; 2349 } 2350 2351 /* Nanosync generic interrupt */ 2352 void 2353 gdpll_intr(int unit, uint32 int_status, uint32 int_enable) 2354 { 2355 uint32 int_status_clear = 0; /* Interrupt status clear */ 2356 uint32 stat0, stat1, stat2, stat3; /* Interrupt enable */ 2357 uint32 cbData[3]; 2358 gdpll_context_t *pGdpllContext = pGdpllCtx; 2359 int chan_num, chan_idx; 2360 uint32 regVal = 0; 2361 2362 #if 0 /* This is handled in time.c */ 2363 /* Read the GDPLL interrupt */ 2364 READ_NS_REGr(unit, NS_TS_INT_STATUSr, 0, &int_status); 2365 READ_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, &int_enable); 2366 2367 /* Process only enabled interrupts */ 2368 int_status &= int_enable; 2369 2370 /* TS_FIFO_NOT_EMPTY interrupt */ 2371 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_FIFO_NOT_EMPTYf)) { 2372 LOG_ERROR(BSL_LS_SOC_COMMON, 2373 (BSL_META_U(unit, 2374 "soc_nanosync_intr: TS_FIFO_NOT_EMPTYf \n"))); 2375 /* Set W1TC to clear the flag */ 2376 soc_reg_field_set(unit, NS_TS_INT_STATUSr, &int_status_clear, TS_FIFO_NOT_EMPTYf, 1); 2377 } 2378 2379 /* TS_FIFO_OVERFLOW interrupt */ 2380 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_FIFO_OVERFLOWf)) { 2381 LOG_ERROR(BSL_LS_SOC_COMMON, 2382 (BSL_META_U(unit, 2383 "soc_nanosync_intr: TS_FIFO_OVERFLOWf \n"))); 2384 /* Set W1TC to clear the flag */ 2385 soc_reg_field_set(unit, NS_TS_INT_STATUSr, &int_status_clear, TS_FIFO_OVERFLOWf, 1); 2386 } 2387 #endif 2388 2389 /* TS0_CNT_OFFSET_UPDATED interrupt */ 2390 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS0_CNT_OFFSET_UPDATEDf)) { 2391 LOG_ERROR(BSL_LS_SOC_COMMON, 2392 (BSL_META_U(unit, 2393 "soc_nanosync_intr: TS0_CNT_OFFSET_UPDATEDf \n"))); 2394 /* Set W1TC to clear the flag */ 2395 soc_reg_field_set(unit, NS_TS_INT_STATUSr, &int_status_clear, TS0_CNT_OFFSET_UPDATEDf, 1); 2396 } 2397 2398 /* TS1_CNT_OFFSET_UPDATED interrupt */ 2399 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS1_CNT_OFFSET_UPDATEDf)) { 2400 LOG_ERROR(BSL_LS_SOC_COMMON, 2401 (BSL_META_U(unit, 2402 "soc_nanosync_intr: TS1_CNT_OFFSET_UPDATEDf \n"))); 2403 /* Set W1TC to clear the flag */ 2404 soc_reg_field_set(unit, NS_TS_INT_STATUSr, &int_status_clear, TS1_CNT_OFFSET_UPDATEDf, 1); 2405 } 2406 2407 /* Write W1TC to clear the flags in NS_TS_INT_STATUS */ 2408 WRITE_NS_REGr(unit, NS_TS_INT_STATUSr, 0, int_status_clear); 2409 2410 /* RoE_TS_ERR interrupt */ 2411 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, ROE_TS_ERRf)) { 2412 LOG_ERROR(BSL_LS_SOC_COMMON, 2413 (BSL_META_U(unit, 2414 " Error: RoE_TS_ERRf \n"))); 2415 } 2416 2417 /* GDPLL_IA_x_STATUS interrupt */ 2418 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_IA_0_STATUSf) || 2419 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_IA_1_STATUSf) || 2420 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_IA_2_STATUSf) || 2421 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_IA_3_STATUSf)) { 2422 2423 READ_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS0r, 0, &stat0); 2424 READ_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS1r, 0, &stat1); 2425 READ_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS2r, 0, &stat2); 2426 READ_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS3r, 0, &stat3); 2427 2428 chan_num = 0; chan_idx = 0; 2429 while (chan_idx<32) { 2430 if ((stat0>>chan_idx) & 0x1) { 2431 READ_NS_REGr(unit, NS_GDPLL_IA_ERROR_CODEr, chan_num+chan_idx, ®Val); 2432 /* LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2433 " Error: chan-%d error_code-0x%x\n"), chan_num+chan_idx, regVal));*/ 2434 } 2435 chan_idx++; 2436 } 2437 2438 chan_num = 32; chan_idx = 0; 2439 while (chan_idx<32) { 2440 if ((stat1>>chan_idx) & 0x1) { 2441 READ_NS_REGr(unit, NS_GDPLL_IA_ERROR_CODEr, chan_num+chan_idx, ®Val); 2442 /* LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2443 " Error: chan-%d error_code-0x%x\n"), chan_num+chan_idx, regVal));*/ 2444 } 2445 chan_idx++; 2446 } 2447 2448 chan_num = 64; chan_idx = 0; 2449 while (chan_idx<32) { 2450 if ((stat2>>chan_idx) & 0x1) { 2451 READ_NS_REGr(unit, NS_GDPLL_IA_ERROR_CODEr, chan_num+chan_idx, ®Val); 2452 /* LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2453 " Error: chan-%d error_code-0x%x\n"), chan_num+chan_idx, regVal));*/ 2454 } 2455 chan_idx++; 2456 } 2457 2458 chan_num = 96; chan_idx = 0; 2459 while (chan_idx<32) { 2460 if ((stat3>>chan_idx) & 0x1) { 2461 READ_NS_REGr(unit, NS_GDPLL_IA_ERROR_CODEr, chan_num+chan_idx, ®Val); 2462 /* LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2463 " Error: chan-%d error_code-0x%x\n"), chan_num+chan_idx, regVal));*/ 2464 } 2465 chan_idx++; 2466 } 2467 2468 /* Clear the status flag */ 2469 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS0r, 0, stat0); 2470 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS1r, 0, stat1); 2471 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS2r, 0, stat2); 2472 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS3r, 0, stat3); 2473 } 2474 2475 /* GDPLL_OA_x_STATUS interrupt */ 2476 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_OA_0_STATUSf) || 2477 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_OA_1_STATUSf) || 2478 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_OA_2_STATUSf) || 2479 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_OA_3_STATUSf)) { 2480 2481 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS0r, 0, &stat0); 2482 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS1r, 0, &stat1); 2483 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS2r, 0, &stat2); 2484 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS3r, 0, &stat3); 2485 2486 if (1 == soc_property_get(unit,"tod_ptpntp_host_update", -1)) { 2487 2488 /* Check if this NCO update is for NTPTOD */ 2489 chan_num = soc_iproc_m7_read(unit, BCM_M7_DTCM_BASE + DPLL_NTPTOD_UPDATE_LOC); 2490 if (chan_num < 32 && (stat0 & (1<<chan_num))) { 2491 _bcm_update_tod_ptpntp(unit, chan_num, 10/*bcmGdpllOutputEventNTPTOD*/); 2492 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS0r, 0, (1<<chan_num)); 2493 } else if (chan_num < 64 && (stat1 & (1<<(chan_num-32)))) { 2494 _bcm_update_tod_ptpntp(unit, chan_num, 10/*bcmGdpllOutputEventNTPTOD*/); 2495 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS1r, 0, (1<<(chan_num-32))); 2496 } else if (chan_num < 96 && (stat2 & (1<<(chan_num-64)))) { 2497 _bcm_update_tod_ptpntp(unit, chan_num, 10/*bcmGdpllOutputEventNTPTOD*/); 2498 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS2r, 0, (1<<(chan_num-64))); 2499 } else if (chan_num < 128 && (stat3 & (1<<(chan_num-96)))) { 2500 _bcm_update_tod_ptpntp(unit, chan_num, 10/*bcmGdpllOutputEventNTPTOD*/); 2501 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS3r, 0, (1<<(chan_num-96))); 2502 } 2503 } 2504 2505 if (1 == soc_property_get(unit,"tod_ptpntp_host_update", -1)) { 2506 2507 /* Check if this NCO update is for PTPTOD */ 2508 chan_num = soc_iproc_m7_read(unit, BCM_M7_DTCM_BASE + DPLL_PTPTOD_UPDATE_LOC); 2509 if (chan_num < 32 && (stat0 & (1<<chan_num))) { 2510 _bcm_update_tod_ptpntp(unit, chan_num, 11/*bcmGdpllOutputEventPTPTOD*/); 2511 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS0r, 0, (1<<chan_num)); 2512 } else if (chan_num < 64 && (stat1 & (1<<(chan_num-32)))) { 2513 _bcm_update_tod_ptpntp(unit, chan_num, 11/*bcmGdpllOutputEventPTPTOD*/); 2514 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS1r, 0, (1<<(chan_num-32))); 2515 } else if (chan_num < 96 && (stat2 & (1<<(chan_num-64)))) { 2516 _bcm_update_tod_ptpntp(unit, chan_num, 11/*bcmGdpllOutputEventPTPTOD*/); 2517 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS2r, 0, (1<<(chan_num-64))); 2518 } else if (chan_num < 128 && (stat3 & (1<<(chan_num-96)))) { 2519 _bcm_update_tod_ptpntp(unit, chan_num, 11/*bcmGdpllOutputEventPTPTOD*/); 2520 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS3r, 0, (1<<(chan_num-96))); 2521 } 2522 } 2523 } 2524 2525 /* GDPLL_NCO_OVERLOAD_x_STATUS interrupt */ 2526 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_NCO_OVERLOAD_0_STATUSf) || 2527 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_NCO_OVERLOAD_1_STATUSf) || 2528 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_NCO_OVERLOAD_2_STATUSf) || 2529 soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_NCO_OVERLOAD_3_STATUSf)) { 2530 2531 READ_NS_REGr(unit, NS_GDPLL_NCO_OVERLOAD_STATUS0r, 0, &stat0); 2532 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OVERLOAD_STATUS0r, 0, stat0); 2533 2534 READ_NS_REGr(unit, NS_GDPLL_NCO_OVERLOAD_STATUS1r, 0, &stat1); 2535 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OVERLOAD_STATUS1r, 0, stat1); 2536 2537 READ_NS_REGr(unit, NS_GDPLL_NCO_OVERLOAD_STATUS2r, 0, &stat2); 2538 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OVERLOAD_STATUS2r, 0, stat2); 2539 2540 READ_NS_REGr(unit, NS_GDPLL_NCO_OVERLOAD_STATUS3r, 0, &stat3); 2541 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OVERLOAD_STATUS3r, 0, stat3); 2542 2543 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2544 "soc_nanosync_intr: NCO_OVERLOAD(0:31): 0x%x\n"), stat0)); 2545 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2546 "soc_nanosync_intr: NCO_OVERLOAD(32:63): 0x%x\n"), stat1)); 2547 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2548 "soc_nanosync_intr: NCO_OVERLOAD(64:95): 0x%x\n"), stat2)); 2549 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2550 "soc_nanosync_intr: NCO_OVERLOAD(96:127): 0x%x\n"), stat3)); 2551 } 2552 2553 /* GDPLL_COMMON_STATUS interrupt */ 2554 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_COMMON_STATUSf)) { 2555 READ_NS_REGr(unit, NS_GDPLL_GDPLL_COMMON_INT_STATUSr, 0, &stat0); 2556 WRITE_NS_REGr(unit, NS_GDPLL_GDPLL_COMMON_INT_STATUSr, 0, stat0); 2557 2558 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2559 "soc_nanosync_intr: COMMON_INT_STATUS(0:3): 0x%x\n"), stat0)); 2560 } 2561 2562 /* M7_CORE_INT_STATUS interrupt */ 2563 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, M7_CORE_INT_STATUSf)) { 2564 2565 /* M7 can communicate the error code as part of NS_GDPLL_M7_ERROR_INFO 2566 * by setting NS_GDPLL_M7_ERROR_INFO_INT register 2567 */ 2568 WRITE_NS_REGr(unit, NS_GDPLL_M7_ERROR_INFO_INTr, 0, 0); 2569 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2570 "soc_nanosync_intr: M7_CORE_INT_STATUS\n"))); 2571 } 2572 2573 /* TS_CPU_FIFO_ECC_ERR_STATUS interrupt */ 2574 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_CPU_FIFO_ECC_ERR_STATUSf)) { 2575 2576 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2577 "soc_nanosync_intr: TS_CPU_FIFO_ECC_ERR_STATUSf\n"))); 2578 } 2579 2580 /* GDPLL_MEM_ECC_ERR_STATUS interrupt */ 2581 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, GDPLL_MEM_ECC_ERR_STATUSf)) { 2582 READ_NS_REGr(unit, NS_GDPLL_NCO_MEM_ECC_STATUSr, 0, &stat0); 2583 READ_NS_REGr(unit, NS_GDPLL_WTCHDG_MEM_ECC_STATUSr, 0, &stat1); 2584 READ_NS_REGr(unit, NS_GDPLL_IA_MEM_ECC_STATUSr, 0, &stat2); 2585 2586 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2587 "soc_nanosync_intr: NCO_MEM_ECC_STATUS: 0x%x\n"), stat0)); 2588 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2589 "soc_nanosync_intr: NS_GDPLL_WTCHDG_MEM_ECC_STATUS: 0x%x\n"), stat1)); 2590 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2591 "soc_nanosync_intr: NS_GDPLL_IA_MEM_ECC_STATUS: 0x%x\n"), stat2)); 2592 } 2593 2594 /* M7_TCM_ECC_ERR_STATUS interrupt */ 2595 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, M7_TCM_ECC_ERR_STATUSf)) { 2596 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2597 "soc_nanosync_intr: M7_TCM_ECC_ERR_STATUS\n"))); 2598 } 2599 2600 /* RSVD1_MESSAGE_RX_STATUS interrupt */ 2601 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, BRCM_RESERVED_IPROC_3_1f/*RSVD1_MESSAGE_RX_STATUSf*/)) { 2602 if (pGdpllContext && pGdpllContext->gdpll_cb) { 2603 if (pGdpllContext->gdpll_cb_type & BCM_GDPLL_CB_RSVD1) { 2604 /* Read the RSVD1 status registers 2605 * MESSAGE_CAPTURE_0_STATUS - BRCM_RESERVED_IPROC_6 2606 * MESSAGE_CAPTURE_1_STATUS - BRCM_RESERVED_IPROC_7 2607 * MESSAGE_CAPTURE_2_STATUS - BRCM_RESERVED_IPROC_8 2608 */ 2609 READ_NS_REGr(unit, BRCM_RESERVED_IPROC_6r, 0, &cbData[0]); 2610 READ_NS_REGr(unit, BRCM_RESERVED_IPROC_7r, 0, &cbData[1]); 2611 READ_NS_REGr(unit, BRCM_RESERVED_IPROC_8r, 0, &cbData[2]); 2612 2613 /* Return of this cb confirms the data consumption */ 2614 pGdpllContext->gdpll_cb(unit, pGdpllContext->pGdpll_cb_data, 2615 cbData, BCM_GDPLL_CB_RSVD1); 2616 } 2617 } 2618 2619 /* Clear the leaf level status at BRCM_RESERVED_IPROC_9 */ 2620 WRITE_NS_REGr(unit, BRCM_RESERVED_IPROC_9r, 0, 0x3); 2621 } 2622 2623 /* TS_CAPTURE_OVRD interrupt */ 2624 if (soc_reg_field_get(unit, NS_TS_INT_STATUSr, int_status, TS_CAPTURE_OVRDf)) { 2625 READ_NS_REGr(unit, NS_RX_CDR_EVENT_OVRD_STATUS0r, 0, &stat0); 2626 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2627 "soc_nanosync_intr: NS_RX_CDR_EVENT_OVRD_STATUS0:0x%x\n"), stat0)); 2628 2629 READ_NS_REGr(unit, NS_RX_CDR_EVENT_OVRD_STATUS1r, 0, &stat0); 2630 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2631 "soc_nanosync_intr: NS_RX_CDR_EVENT_OVRD_STATUS10:0x%x\n"), stat0)); 2632 2633 READ_NS_REGr(unit, NS_TX_PI_EVENT_OVRD_STATUS0r, 0, &stat0); 2634 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2635 "soc_nanosync_intr: NS_TX_PI_EVENT_OVRD_STATUS0:0x%x\n"), stat0)); 2636 2637 READ_NS_REGr(unit, NS_TX_PI_EVENT_OVRD_STATUS1r, 0, &stat0); 2638 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2639 "soc_nanosync_intr: NS_TX_PI_EVENT_OVRD_STATUS1:0x%x\n"), stat0)); 2640 2641 READ_NS_REGr(unit, NS_MISC_EVENT_OVRD_STATUSr, 0, &stat0); 2642 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2643 "soc_nanosync_intr: NS_MISC_EVENT_OVRD_STATUS:0x%x\n"), stat0)); 2644 2645 READ_NS_REGr(unit, NS_TIMESYNC_MAPPER_RX_TYPE0_OVRD_STATUSr, 0, &stat0); 2646 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2647 "soc_nanosync_intr: NS_TIMESYNC_MAPPER_RX_TYPE0_OVRD_STATUS:0x%x\n"), stat0)); 2648 2649 READ_NS_REGr(unit, NS_TIMESYNC_MAPPER_RX_TYPE1_OVRD_STATUSr, 0, &stat0); 2650 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2651 "soc_nanosync_intr: NS_TIMESYNC_MAPPER_RX_TYPE1_OVRD_STATUS:0x%x\n"), stat0)); 2652 2653 READ_NS_REGr(unit, NS_TIMESYNC_MAPPER_RX_TYPE2_OVRD_STATUSr, 0, &stat0); 2654 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2655 "soc_nanosync_intr: NS_TIMESYNC_MAPPER_RX_TYPE2_OVRD_STATUS:0x%x\n"), stat0)); 2656 } 2657 2658 #if 0 /* Interrupt is re-enabled in time.c */ 2659 /* Re-enable GDPLL NS IRQ */ 2660 soc_cmicm_intr2_enable(unit, SOC_GDPLL_NS_INTR_POS); 2661 #endif 2662 } 2663 /* Manual, CPU copy */ 2664 uint32 gdpll_cpucopy (int unit, uint32 *pDstBuff, uint32 gdpllDebugArea, uint32 count) 2665 { 2666 int rv = BCM_E_NONE; 2667 uint32 i; 2668 2669 for (i = 0; i < count; ) { 2670 *pDstBuff = soc_iproc_m7_read(unit, gdpllDebugArea + i); 2671 pDstBuff++; 2672 i = i + 4; 2673 } 2674 2675 return rv; 2676 } 2677 2678 /* Nanosync debug buffer interrupt */ 2679 void 2680 soc_nanosync_debug_intr(void *unit_vp, void *d1, void *d2, 2681 void *d3, void *d4) 2682 { 2683 int unit = PTR_TO_INT(unit_vp); 2684 uint32 regVal = 0; 2685 uint32 int_status = 0; /* Interrupt status */ 2686 uint32 int_enable = 0; /* Interrupt enable */ 2687 gdpll_context_t *pGdpllContext = pGdpllCtx; 2688 2689 /* Read the GDPLL interrupt status */ 2690 READ_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_INT_STATUSr, 0, &int_status); 2691 2692 /* Process threshold interrupt */ 2693 if (soc_reg_field_get(unit, NS_GDPLL_DEBUG_M7DG_INT_STATUSr, int_status, THRESHOLD_REACHEDf)) { 2694 READ_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_RSTATEr, 0, ®Val); 2695 regVal = (pGdpllContext->debugRdIdx + BCM_GDPLL_DEBUG_THRESHOLD) % BCM_GDPLL_DEBUG_BUFFER_SIZE; 2696 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_RSTATEr, 0, regVal); 2697 2698 int_enable |= INTR_GDPLL_DEBUG_THR; 2699 /* Signal the thread for buffer read */ 2700 if (pGdpllContext->debug_sem) { 2701 sal_sem_give(pGdpllContext->debug_sem); 2702 } else { 2703 uint32 dpllDebugFlag = BCM_M7_DTCM_BASE + DPLL_DEBUG_ENABLE_OFFSET; 2704 2705 if (pGdpllContext->debug_cb && soc_iproc_m7_read (unit, dpllDebugFlag)) { 2706 /* Return of this cb confirms the buffer consumption */ 2707 pGdpllContext->debug_cb(unit, pGdpllContext->pUserData, 2708 (BCM_GDPLL_DEBUG_BUFFER_START + (pGdpllContext->debugRdIdx * 4)), 2709 BCM_GDPLL_DEBUG_THRESHOLD); 2710 } 2711 2712 READ_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_RSTATEr, 0, ®Val); 2713 pGdpllContext->debugRdIdx = regVal; 2714 } 2715 } 2716 2717 if (soc_reg_field_get(unit, NS_GDPLL_DEBUG_M7DG_INT_STATUSr, int_status, OVERFLOWf)) { 2718 int_enable |= INTR_GDPLL_DEBUG_OF; 2719 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "OVERFLOW !!\n"))); 2720 soc_iproc_m7_write(unit, (BCM_M7_DTCM_BASE + DPLL_DEBUG_ENABLE_OFFSET), 0); 2721 } 2722 2723 if (soc_reg_field_get(unit, NS_GDPLL_DEBUG_M7DG_INT_STATUSr, int_status, ECC_ERR_MEM0f)) { 2724 int_enable |= INTR_GDPLL_DEBUG_ECC0; 2725 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "ECC_ERR_MEM0 !!\n"))); 2726 } 2727 2728 if (soc_reg_field_get(unit, NS_GDPLL_DEBUG_M7DG_INT_STATUSr, int_status, ECC_ERR_MEM1f)) { 2729 int_enable |= INTR_GDPLL_DEBUG_ECC1; 2730 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "ECC_ERR_MEM1 !!\n"))); 2731 } 2732 2733 /* Clear the interrupt status, which is W1TC */ 2734 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_INT_STATUSr, 0, int_status); 2735 2736 /* Re-enable the interrupts */ 2737 READ_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_INT_ENABLEr, 0, ®Val); 2738 int_enable |= soc_reg_field_get(unit, NS_GDPLL_DEBUG_M7DG_INT_ENABLEr, regVal, INTENf); 2739 soc_reg_field_set(unit, NS_GDPLL_DEBUG_M7DG_INT_ENABLEr, ®Val, INTENf, int_enable); 2740 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_INT_ENABLEr, 0, int_enable); 2741 2742 /* Re-enable GDPLL debug buffer interrupt */ 2743 soc_cmicm_intr2_enable(unit, SOC_GDPLL_NS_INTR_POS | SOC_GDPLL_NS_INTR_DEBUG_POS); 2744 } 2745 2746 void clear_m7_memory(int unit) 2747 { 2748 uint32 m7_itcmaddr = BCM_M7_ITCM_BASE; 2749 uint32 m7_dtcmaddr = BCM_M7_DTCM_BASE; 2750 uint32 i; 2751 uint32 itcm_size = 1024*8; 2752 uint32 dtcm_size = 1024*32; 2753 2754 /* Clear ITCM */ 2755 for (i=0; i<itcm_size;) { 2756 soc_uc_mem_write(unit, m7_itcmaddr, 0); 2757 i = i+4; 2758 m7_itcmaddr = m7_itcmaddr+4; 2759 } 2760 2761 /* Clear DTCM */ 2762 for (i=0; i<dtcm_size;) { 2763 soc_uc_mem_write(unit, m7_dtcmaddr, 0); 2764 i = i+4; 2765 m7_dtcmaddr = m7_dtcmaddr+4; 2766 } 2767 } 2768 2769 2770 int 2771 _bcm_esw_gdpll_init(int unit) 2772 { 2773 int rv = BCM_E_NONE; 2774 uint32 regVal = 0; 2775 uint32 alloc_sz = 0; 2776 uint32 count = 0; 2777 gdpll_context_t *pGdpllContext = NULL; 2778 sal_thread_t thread_id_debug; 2779 uint32 reg; 2780 uint32 regCount; 2781 int debug_thread_pri = 0; 2782 2783 /* Clear the tdpll state structure */ 2784 for (count = 0; count < NUM_TDPLL_INSTANCE; count++) { 2785 gdpll_tdpll_state.tdpll_instace[count] = BCM_GDPLL_NUM_IA_ENTRIES; 2786 } 2787 2788 /* Allocate time config structure. */ 2789 alloc_sz = sizeof(gdpll_context_t); 2790 pGdpllContext = sal_alloc(alloc_sz, "GDPLL module"); 2791 if (NULL == pGdpllContext) { 2792 rv = BCM_E_MEMORY; 2793 goto exit; 2794 } 2795 sal_memset(pGdpllContext, 0, alloc_sz); 2796 2797 /* Set all events available */ 2798 for (count = 0; count < BCM_GDPLL_NUM_INPUT_EVENTS; count++) { 2799 pGdpllContext->eventId[count] = BCM_GDPLL_NUM_IA_ENTRIES; 2800 } 2801 2802 /* Create protection mutex. */ 2803 pGdpllContext->mutex = NULL; 2804 pGdpllContext->mutex = sal_mutex_create("GDPLL mutex"); 2805 if (NULL == pGdpllContext->mutex) { 2806 _bcm_esw_gdpll_deinit(unit); 2807 return (BCM_E_MEMORY); 2808 } 2809 2810 pGdpllContext->debug_cb = NULL; 2811 clear_m7_memory(unit); 2812 2813 2814 2815 /* Configure debug threshold level */ 2816 READ_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_THRESHOLDr, 0, ®Val); 2817 soc_reg_field_set(unit, NS_GDPLL_DEBUG_M7DG_THRESHOLDr, ®Val, THRESHOLDf, BCM_GDPLL_DEBUG_THRESHOLD); 2818 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_THRESHOLDr, 0, regVal); 2819 2820 /* Enable the GDPLL debug feature */ 2821 /* 1->0 transition to clear the buffer pointers */ 2822 READ_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, 0, ®Val); 2823 soc_reg_field_set(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, ®Val, ENABLEf, 1); 2824 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, 0, regVal); 2825 soc_reg_field_set(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, ®Val, ENABLEf, 0); 2826 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, 0, regVal); 2827 soc_reg_field_set(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, ®Val, ENABLEf, 1); 2828 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, 0, regVal); 2829 2830 pGdpllCtx = pGdpllContext; 2831 2832 pGdpllContext->debugRdIdx = 0; 2833 2834 debug_thread_pri = soc_property_get(unit,"gdpll_debug_thread_pri", -1); 2835 pGdpllContext->debug_sem = NULL; 2836 if ((debug_thread_pri >= 0) && (debug_thread_pri < 255)) { 2837 /* Create the debug buffer semaphore */ 2838 pGdpllContext->debug_sem = sal_sem_create("gdpll_debug_buff", sal_sem_COUNTING, 0); 2839 if (pGdpllContext->debug_sem == NULL) { 2840 LOG_ERROR(BSL_LS_SOC_COMMON, 2841 (BSL_META_U(unit, 2842 "_bcm_esw_gdpll_init: Error !! failed to create the sem\n"))); 2843 return (BCM_E_MEMORY); 2844 } 2845 2846 /* Create the debug thread */ 2847 thread_id_debug = sal_thread_create("GDPLL Debug thread", SAL_THREAD_STKSZ, debug_thread_pri, 2848 gdpll_debug_buffer_send_thread, INT_TO_PTR(unit)); 2849 if (thread_id_debug == SAL_THREAD_ERROR) { 2850 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "GDPLL Error !! debug thread create failed\n"))); 2851 return BCM_E_INTERNAL; 2852 } 2853 } 2854 2855 /* Disable the ECC protection before Input-Array clearing */ 2856 READ_NS_REGr(unit, NS_GDPLL_IA_MEM_ECC_CONTROLr, 0, ®Val); 2857 soc_reg_field_set(unit, NS_GDPLL_IA_MEM_ECC_CONTROLr, ®Val, 2858 DISABLE_ECCf, 1); 2859 WRITE_NS_REGr(unit, NS_GDPLL_IA_MEM_ECC_CONTROLr, 0, regVal); 2860 2861 /* Clear the Input Array */ 2862 reg = 0x03271000; 2863 for (regCount = 0; regCount < 256*2; regCount++) { 2864 soc_iproc_setreg(unit, reg+regCount*4, 0); 2865 } 2866 2867 /* Clear the Output Array */ 2868 reg = 0x03272000; 2869 for (regCount = 0; regCount < 128*2; regCount++) { 2870 soc_iproc_setreg(unit, reg+regCount*4, 0); 2871 } 2872 2873 /* Enable the ECC protection on Input-Array */ 2874 READ_NS_REGr(unit, NS_GDPLL_IA_MEM_ECC_CONTROLr, 0, ®Val); 2875 soc_reg_field_set(unit, NS_GDPLL_IA_MEM_ECC_CONTROLr, ®Val, 2876 DISABLE_ECCf, 0); 2877 WRITE_NS_REGr(unit, NS_GDPLL_IA_MEM_ECC_CONTROLr, 0, regVal); 2878 2879 /* Clear the out status flags */ 2880 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS0r, 0, 0xFFFFFFFF); /* 0:31 */ 2881 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS1r, 0, 0xFFFFFFFF); /* 0:31 */ 2882 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS2r, 0, 0xFFFFFFFF); /* 0:31 */ 2883 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_STATUS3r, 0, 0xFFFFFFFF); /* 0:31 */ 2884 2885 /* Enable the required leaf level interrupts that reflects 2886 * in TS generic interrupts 2887 */ 2888 /* Enable the channel update status reporting */ 2889 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_ENABLE0r, 0, 0xFFFFFFFF); /* 0:31 */ 2890 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_ENABLE1r, 0, 0xFFFFFFFF); /* 32:63 */ 2891 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_ENABLE2r, 0, 0xFFFFFFFF); 2892 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_ENABLE3r, 0, 0xFFFFFFFF); 2893 2894 #if 0 2895 /* Enable the Channel Output array status reporting */ 2896 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE0r, 0, 0xFFFFFFFF); /* 0:31 */ 2897 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE1r, 0, 0xFFFFFFFF); /* 32:63 */ 2898 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE2r, 0, 0xFFFFFFFF); 2899 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE3r, 0, 0xFFFFFFFF); 2900 #endif 2901 2902 /* Enable NCO overload detection is global to all the channeld ?? */ 2903 READ_NS_REGr(unit, NS_GDPLL_NCO_UPDATE_COMMON_CONTROLr, 0, ®Val); 2904 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_COMMON_CONTROLr, ®Val, NCO_WERROR_DISABLEf, 1); 2905 WRITE_NS_REGr(unit, NS_GDPLL_NCO_UPDATE_COMMON_CONTROLr, 0, regVal); 2906 2907 /* ECC error detection is set by default, ECC_CONTROL register */ 2908 2909 /* Enable GDPLL common interrupt status reporting */ 2910 WRITE_NS_REGr(unit, NS_GDPLL_GDPLL_COMMON_INT_ENABLEr, 0, 0xF); 2911 2912 /* Enable the M7 core interrupts status reporting */ 2913 WRITE_NS_REGr(unit, NS_GDPLL_M7_CORE_INT_ENABLEr, 0, 0xF); 2914 2915 /* There are no enabling control for TS_CAPTURE_OVRD */ 2916 2917 2918 for (count = 0; count < BCM_GDPLL_NUM_CHANNELS; count++) { 2919 /* Set enable and Interval field NS_GDPLL_IA_WDOG_CONFIG */ 2920 READ_NS_REGr(unit, NS_GDPLL_IA_WDOG_CONFIGr, count, ®Val); 2921 soc_reg_field_set(unit, NS_GDPLL_IA_WDOG_CONFIGr, ®Val, 2922 INTERVALf, 0xFFFFF); 2923 soc_reg_field_set(unit, NS_GDPLL_IA_WDOG_CONFIGr, ®Val, 2924 ENABLEf, 1); 2925 WRITE_NS_REGr(unit, NS_GDPLL_IA_WDOG_CONFIGr, count, regVal); 2926 } 2927 2928 if (soc_feature(unit, soc_feature_rsvd1_intf)) { 2929 /* Pull RSVD1 PLL out of reset */ 2930 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, ®Val)); 2931 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, ®Val, BRCM_RESERVED_TOP_1_1f, 1); 2932 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, ®Val, BRCM_RESERVED_TOP_1_2f, 1); 2933 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, regVal)); 2934 2935 /* Init the BCN counter */ 2936 READ_NS_REGr(unit, BRCM_RESERVED_IPROC_12r, 0, ®Val); 2937 soc_reg_field_set(unit, BRCM_RESERVED_IPROC_12r, ®Val, BRCM_RESERVED_IPROC_12_1f, 0x400); 2938 WRITE_NS_REGr(unit, BRCM_RESERVED_IPROC_12r, 0, regVal); 2939 2940 READ_NS_REGr(unit, BRCM_RESERVED_IPROC_13r, 0, ®Val); 2941 soc_reg_field_set(unit, BRCM_RESERVED_IPROC_13r, ®Val, BRCM_RESERVED_IPROC_13_1f, 0); 2942 WRITE_NS_REGr(unit, BRCM_RESERVED_IPROC_13r, 0, regVal); 2943 2944 READ_NS_REGr(unit, BRCM_RESERVED_IPROC_11r, 0, ®Val); 2945 soc_reg_field_set(unit, BRCM_RESERVED_IPROC_11r, ®Val, BRCM_RESERVED_IPROC_11_1f, 0x1); 2946 WRITE_NS_REGr(unit, BRCM_RESERVED_IPROC_11r, 0, regVal); 2947 } 2948 2949 /* Set capture_enable for all the TS GPIO's */ 2950 for (count = 0; count < TS_GPIO_COUNT; count++) { 2951 READ_NS_REGr(unit, gpio_regs[count], 0, ®Val); 2952 soc_reg_field_set(unit, gpio_regs[count], ®Val, 2953 CAPTURE_ENABLEf, 1); 2954 WRITE_NS_REGr(unit, gpio_regs[count], 0, regVal); 2955 } 2956 2957 if (!SOC_WARM_BOOT(unit)) { 2958 /* Set broadsync setting to reset state */ 2959 SOC_IF_ERROR_RETURN(WRITE_NS_BS0_BS_TC_CTRLr(unit, 0)); 2960 SOC_IF_ERROR_RETURN(WRITE_NS_BS1_BS_TC_CTRLr(unit, 0)); 2961 } 2962 2963 /* Check if the Offset is non-word aligned */ 2964 reg = SAL_OFFSETOF(m7_dpll_param_t, m7_dpll_state.Offset); 2965 if (reg%4) { 2966 bsl_printf("GDPLL: WARN !! Offset field at offset:%d\n", reg); 2967 } 2968 2969 /* Check if HoldoverFlag and NominalLoopFiletr are non-word aligned */ 2970 reg = SAL_OFFSETOF(m7_dpll_param_t, m7_dpll_state.HoldoverFlag); 2971 if (reg%4) { 2972 bsl_printf("GDPLL: WARN !! HoldoverFlag field at offset:%d\n", reg); 2973 } 2974 2975 reg = SAL_OFFSETOF(m7_dpll_param_t, m7_dpll_config.NominalLoopFilter); 2976 if (reg%4) { 2977 bsl_printf("GDPLL: WARN !! NominalLoopFilter field at offset:%d\n", reg); 2978 } 2979 2980 /* Check the size of DPLL param */ 2981 count = sizeof(m7DpllParam); 2982 if (count > DPLL_PARAM_SIZE) { 2983 bsl_printf("GDPLL: ERROR !! DPLL param size:%d is more than allocated:%d\n", 2984 count, DPLL_PARAM_SIZE); 2985 return BCM_E_NONE; 2986 } 2987 2988 /* Invalidate the NCO out configuration registers */ 2989 if (SOC_IS_MONTEREY(unit)) { 2990 /* Monterey uArch spec defines hw_type:0 and hw_id:70 as invalid */ 2991 for (count = 0; count < BCM_GDPLL_NUM_CHANNELS; count++) { 2992 READ_NS_REGr(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, count, ®Val); 2993 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_HW_IDf, 70); 2994 soc_reg_field_set(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, ®Val, DEST_HW_TYPEf, 0); 2995 WRITE_NS_REGr(unit, NS_GDPLL_NCO_UPDATE_CONTROLr, count, regVal); 2996 } 2997 } 2998 2999 /* Mask the GDPLL Debug IRQ interrupts and NS_TS IRQ interrupts */ 3000 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_INT_ENABLEr, 0, INTR_NS_DEBUG); 3001 3002 /* Enable interrupts on Nanosync intr line */ 3003 #if 0 3004 READ_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, ®Val); 3005 regVal |= INTR_ROE_TS_ERR | INTR_GDPLL_IA_0_STATUS | 3006 INTR_GDPLL_IA_1_STATUS | INTR_GDPLL_IA_2_STATUS | INTR_GDPLL_IA_3_STATUS; 3007 WRITE_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, regVal); 3008 #endif 3009 3010 #ifdef BCN_WAR 3011 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_BCN_UPDATE_LOC, 0xFF); 3012 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_NTPTOD_UPDATE_LOC, 0xFF); 3013 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_PTPTOD_UPDATE_LOC, 0xFF); 3014 #endif 3015 3016 /* Enable both(GDPLL debug buffer and Error) interrupts */ 3017 soc_cmicm_intr2_enable(unit, SOC_GDPLL_NS_INTR_POS | SOC_GDPLL_NS_INTR_DEBUG_POS); 3018 3019 exit: 3020 return (rv); 3021 } 3022 3023 STATIC int 3024 _bcm_esw_gdpll_chan_alloc(int unit, int *pChan) 3025 { 3026 int rv = BCM_E_NONE; 3027 uint32 idx = 0; 3028 gdpll_context_t *pGdpllContext = pGdpllCtx; 3029 3030 if (pGdpllContext == NULL) { 3031 LOG_ERROR(BSL_LS_SOC_COMMON, 3032 (BSL_META_U(unit, 3033 "_bcm_esw_gdpll_chan_alloc: Error !! No context\n"))); 3034 rv = BCM_E_PARAM; 3035 goto exit; 3036 } 3037 3038 for (idx = 0; idx < BCM_GDPLL_NUM_CHANNELS; idx++) { 3039 if (!(pGdpllContext->dpll_chan[idx].flag & BCM_GDPLL_CHAN_ALLOC)) { 3040 *pChan = idx; 3041 goto exit; 3042 } 3043 } 3044 3045 rv = BCM_E_FULL; 3046 3047 exit: 3048 return (rv); 3049 } 3050 3051 STATIC int 3052 _bcm_esw_gdpll_chan_free(int unit, int chan) 3053 { 3054 int rv = BCM_E_NONE; 3055 gdpll_context_t *pGdpllContext = pGdpllCtx; 3056 3057 if ((pGdpllContext == NULL) || 3058 (chan >= BCM_GDPLL_NUM_CHANNELS)){ 3059 rv = BCM_E_PARAM; 3060 goto exit; 3061 } 3062 3063 pGdpllContext->dpll_chan[chan].flag &= ~BCM_GDPLL_CHAN_ALLOC; 3064 3065 exit: 3066 return (rv); 3067 } 3068 3069 STATIC int 3070 _bcm_esw_gdpll_event_config_set(int unit, bcm_gdpll_chan_input_t *pChanInput, uint32 eventId, uint32 *pIaAddr) 3071 { 3072 int rv = BCM_E_NONE; 3073 gdpll_event_dest_cfg_t eventDest; 3074 3075 /* Configure the event */ 3076 eventDest.event_dest = pChanInput->event_dest; 3077 eventDest.ts_counter = pChanInput->ts_counter; 3078 eventDest.ppm_check_enable = pChanInput->ppm_check_enable; 3079 3080 if ((pChanInput->input_event >= bcmGdpllInputEventCpu) && 3081 (pChanInput->input_event <= bcmGdpllInputEventLCPLL3)) { 3082 BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_event_divisor_misc_set(unit, 3083 pChanInput->input_event, 3084 pChanInput->event_divisor)); 3085 BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_event_dest_misc_set(unit, 3086 pChanInput->input_event, 3087 &eventDest, eventId, pIaAddr)); 3088 3089 } else if(pChanInput->input_event == bcmGdpllInputEventPORT) { 3090 if ((pChanInput->port_event_type == bcmGdpllPortEventRXCDR) || 3091 (pChanInput->port_event_type == bcmGdpllPortEventTXPI)) { 3092 BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_event_divisor_port_set(unit, 3093 pChanInput->port, pChanInput->port_event_type, 3094 pChanInput->event_divisor)); 3095 } 3096 BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_event_dest_port_set(unit, pChanInput->port, 3097 pChanInput->port_event_type, 3098 &eventDest, eventId, pIaAddr)); 3099 3100 /* ROE event, disable the 52b conversion SWIPROC-591 */ 3101 if (pChanInput->port_event_type == bcmGdpllPortEventROE) 3102 BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_event_roe_52b_set(unit, 3103 pChanInput->port, 0)); 3104 3105 } else if(pChanInput->input_event == bcmGdpllInputEventR5) { 3106 3107 *pIaAddr = 214; 3108 3109 /* Get the free Input array address */ 3110 /*BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_input_array_alloc(unit, 3111 eventId, pIaAddr));*/ 3112 } else { 3113 LOG_ERROR(BSL_LS_SOC_COMMON, 3114 (BSL_META_U(unit, 3115 "event_config_set: Error !! invalid input event\n"))); 3116 rv = BCM_E_PARAM; 3117 } 3118 3119 return (rv); 3120 } 3121 3122 STATIC int 3123 _bcm_esw_gdpll_chan_priority_set(int unit, int chan, bcm_gdpll_chan_priority_t chan_prio) 3124 { 3125 /* NS_GDPLL_IA_UPDATE_CONFIG */ 3126 int rv = BCM_E_NONE; 3127 uint32 regVal = 0; 3128 3129 if (chan >= BCM_GDPLL_NUM_CHANNELS) { 3130 LOG_ERROR(BSL_LS_SOC_COMMON, 3131 (BSL_META_U(unit, 3132 "chan_priority_set: Error !! invalid chan\n"))); 3133 rv = BCM_E_PARAM; 3134 goto exit; 3135 } 3136 3137 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, ®Val); 3138 soc_reg_field_set(unit, NS_GDPLL_IA_UPDATE_CONFIGr, ®Val, SPEED_BINf, chan_prio); 3139 WRITE_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, regVal); 3140 3141 exit: 3142 return (rv); 3143 } 3144 3145 /****************************************************************************/ 3146 /* API functions implementation */ 3147 /****************************************************************************/ 3148 3149 /* 3150 * Function: 3151 * bcm_esw_gdpll_chan_enable 3152 * Purpose: 3153 * Channel enable 3154 * Parameters: 3155 * unit - (IN) StrataSwitch Unit #. 3156 * chan - (IN) Channel Number 3157 * enable - (IN) Enable flag 3158 * Returns: 3159 * BCM_E_NONE 3160 * BCM_E_XXX 3161 */ 3162 int 3163 bcm_esw_gdpll_chan_enable(int unit, int chan, int enable) 3164 { 3165 int rv = BCM_E_NONE; 3166 bcm_gdpll_input_event_t event_misc; 3167 bcm_gdpll_port_event_t port_event_type; 3168 bcm_port_t port; 3169 gdpll_context_t *pGdpllContext = pGdpllCtx; 3170 uint8 buffer[DPLL_FW_VERSION_SIZE]; 3171 3172 if((chan >= BCM_GDPLL_NUM_CHANNELS) || 3173 (pGdpllContext == NULL)) { 3174 rv = BCM_E_PARAM; 3175 return rv; 3176 } 3177 3178 /* Channel is not allocated and feedbak is configured */ 3179 if (!(pGdpllContext->dpll_chan[chan].flag & BCM_GDPLL_CHAN_ALLOC) || 3180 !(pGdpllContext->dpll_chan[chan].flag & BCM_GDPLL_EVENT_CONFIG_FB)) { 3181 rv = BCM_E_NOT_FOUND; 3182 return rv; 3183 } 3184 3185 /* Check if the M7 is alive to service the channel events */ 3186 rv = _bcm_esw_gdpll_m7_status(unit, buffer); 3187 if (rv != BCM_E_NONE) { 3188 LOG_ERROR(BSL_LS_SOC_COMMON, 3189 (BSL_META_U(unit, 3190 "gdpll_chan_enable: M7-FW not running\n"))); 3191 return rv; 3192 } 3193 3194 sal_mutex_take(pGdpllContext->mutex, sal_mutex_FOREVER); 3195 3196 /* Check if phaseCounterRef and event-ref is not configured */ 3197 if (!pGdpllContext->dpll_chan[chan].phaseConterRef && 3198 !(pGdpllContext->dpll_chan[chan].flag & BCM_GDPLL_EVENT_CONFIG_REF)) { 3199 LOG_ERROR(BSL_LS_SOC_COMMON, 3200 (BSL_META_U(unit, 3201 "gdpll_chan_enable: Error !! phase ref error\n"))); 3202 rv = BCM_E_PARAM; 3203 goto exit; 3204 } 3205 3206 if (enable == 0) { 3207 /* For disable case, first disable the channel */ 3208 _bcm_esw_gdpll_chan_enable_set(unit, chan, enable); 3209 } 3210 3211 /* enable=1, Enable the events in sequence */ 3212 bsl_printf("GDPLL: Set enable for feedback event\n"); 3213 /* set enable for feedback event */ 3214 _bcm_esw_gdpll_input_event_get(unit, pGdpllContext->dpll_chan[chan].eventId_fb, 3215 &event_misc, &port_event_type, &port); 3216 if (event_misc == bcmGdpllInputEventPORT) { 3217 _bcm_esw_gdpll_event_enable_port_set(unit, port, port_event_type, enable); 3218 } else if (event_misc == bcmGdpllInputEventR5) { 3219 3220 } else { 3221 _bcm_esw_gdpll_event_enable_misc_set(unit, event_misc, enable); 3222 } 3223 3224 /* set enable for reference event */ 3225 if (!pGdpllContext->dpll_chan[chan].phaseConterRef) { 3226 if (!(pGdpllContext->dpll_chan[chan].flag & BCM_GDPLL_EVENT_CONFIG_REF)) { 3227 /* Phase reference is not set, return error */ 3228 LOG_ERROR(BSL_LS_SOC_COMMON, 3229 (BSL_META_U(unit, 3230 "gdpll_chan_enable: Error !! phase ref is not set\n"))); 3231 rv = BCM_E_PARAM; 3232 goto exit; 3233 } 3234 3235 bsl_printf("GDPLL: Set enable for reference event\n"); 3236 _bcm_esw_gdpll_input_event_get(unit, pGdpllContext->dpll_chan[chan].eventId_ref, 3237 &event_misc, &port_event_type, &port); 3238 if (event_misc == bcmGdpllInputEventPORT) { 3239 _bcm_esw_gdpll_event_enable_port_set(unit, port, port_event_type, enable); 3240 } else if (event_misc == bcmGdpllInputEventR5) { 3241 3242 } else { 3243 _bcm_esw_gdpll_event_enable_misc_set(unit, event_misc, enable); 3244 } 3245 } 3246 3247 if (enable) { 3248 /* 3249 * For enable:1, first enable the IA capture and then enable the 3250 * GDPLL channel 3251 */ 3252 /* Enable GDPLL input array capture */ 3253 _bcm_esw_gdpll_capture_enable_m7_set(unit, enable); 3254 3255 /* Enable the GDPLL channel */ 3256 _bcm_esw_gdpll_chan_enable_set(unit, chan, enable); 3257 } 3258 3259 /* For channel disable, clear the PAIR_AVAILABLE flag which is just 3260 * a debug hook 3261 */ 3262 if (enable == 0) { 3263 if (chan < 32) { 3264 WRITE_NS_REGr(unit, NS_GDPLL_IA_TS_PAIR_AVAILABLE0r, 0, 1<<chan); 3265 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS0r, 0, 1<<chan); 3266 } else if (chan < 64) { 3267 WRITE_NS_REGr(unit, NS_GDPLL_IA_TS_PAIR_AVAILABLE1r, 0, 1<<(chan-32)); 3268 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS1r, 0, 1<<(chan-32)); 3269 } else if (chan < 96) { 3270 WRITE_NS_REGr(unit, NS_GDPLL_IA_TS_PAIR_AVAILABLE2r, 0, 1<<(chan-64)); 3271 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS2r, 0, 1<<(chan-64)); 3272 } else if (chan < 128) { 3273 WRITE_NS_REGr(unit, NS_GDPLL_IA_TS_PAIR_AVAILABLE3r, 0, 1<<(chan-96)); 3274 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS3r, 0, 1<<(chan-96)); 3275 } 3276 } 3277 3278 exit: 3279 sal_mutex_give(pGdpllContext->mutex); 3280 return (rv); 3281 } 3282 3283 /* 3284 * Function: 3285 * bcm_esw_gdpll_chan_create 3286 * Purpose: 3287 * Initialize time module 3288 * Parameters: 3289 * unit - (IN) StrataSwitch Unit #. 3290 * flags - (IN) Flags for channel create 3291 * Returns: 3292 * BCM_E_NONE 3293 * BCM_E_XXX 3294 */ 3295 int 3296 bcm_esw_gdpll_chan_create(int unit, uint32 flags, 3297 bcm_gdpll_chan_t *pGdpllChan, int *pChan) 3298 { 3299 int rv = BCM_E_NONE; 3300 uint32 iaAddr_fb = BCM_GDPLL_NUM_IA_ENTRIES; /* Indicating free */ 3301 uint32 iaAddr_ref = BCM_GDPLL_NUM_IA_ENTRIES; /* Indicating free */ 3302 uint32 eventId_fb = BCM_GDPLL_NUM_INPUT_EVENTS; /* Indicating invalid event */ 3303 uint32 eventId_ref = BCM_GDPLL_NUM_INPUT_EVENTS; /* Indicating invalid event */ 3304 int phaseCounterRef = 0; 3305 uint32 regVal = 0; 3306 int gdpll_port; 3307 3308 int chan; 3309 int inUse = 0; 3310 dpll_param_t dpllParam; 3311 gdpll_context_t *pGdpllContext = pGdpllCtx; 3312 3313 if ((pChan == NULL) || (pGdpllChan == NULL) || 3314 (pGdpllContext == NULL)) { 3315 rv = BCM_E_PARAM; 3316 goto exit; 3317 } 3318 3319 /* Lock the channel access */ 3320 sal_mutex_take(pGdpllContext->mutex, sal_mutex_FOREVER); 3321 3322 /* Get the free channel 3323 * If the channel is allocated earlier, then pChan carries the 3324 * allocated channel number, otherwise flag should need to be 3325 * with BCM_GDPLL_CHAN_ALLOC 3326 */ 3327 if(flags & BCM_GDPLL_CHAN_ALLOC) { 3328 /* Alloc new channel */ 3329 if(_bcm_esw_gdpll_chan_alloc(unit, &chan) != BCM_E_NONE) { 3330 rv = BCM_E_INTERNAL; 3331 goto exit; 3332 } 3333 *pChan = chan; 3334 } else if((*pChan < BCM_GDPLL_NUM_CHANNELS) && 3335 (pGdpllContext->dpll_chan[*pChan].flag & BCM_GDPLL_CHAN_ALLOC)){ 3336 /* Channel is already allocated earlier and channel number 3337 * passed by the user 3338 */ 3339 chan = *pChan; 3340 } else { 3341 /* Channel is not allocated earlier either */ 3342 rv = BCM_E_PARAM; 3343 goto exit; 3344 } 3345 3346 /* Feedback event forward configuration */ 3347 if(flags & BCM_GDPLL_EVENT_CONFIG_FB) { 3348 if (pGdpllChan->event_fb.input_event == bcmGdpllInputEventPORT) { 3349 rv = _bcm_esw_gdpll_portmap_get(unit, pGdpllChan->event_fb.port, &gdpll_port); 3350 if (rv != BCM_E_NONE) { 3351 goto exit; 3352 } 3353 pGdpllChan->event_fb.port = gdpll_port; 3354 } 3355 3356 if(_bcm_esw_gdpll_input_eventId_get(unit, 3357 &pGdpllChan->event_fb, 3358 &eventId_fb) != BCM_E_NONE) { 3359 rv = BCM_E_INTERNAL; 3360 goto exit; 3361 } 3362 3363 bsl_printf("GDPLL: Feedback eventId:%d\n", eventId_fb); 3364 /* Check if the event is already under use */ 3365 if(_bcm_esw_gdpll_input_eventId_inUse(unit, 3366 eventId_fb, &inUse) != BCM_E_NONE) { 3367 rv = BCM_E_INTERNAL; 3368 goto exit; 3369 } 3370 if (inUse) { 3371 /* Event is under use by other channel */ 3372 rv = BCM_E_PARAM; 3373 goto exit; 3374 } 3375 3376 /* Configure the input event and get iaAddr_fb */ 3377 if(_bcm_esw_gdpll_event_config_set(unit, &(pGdpllChan->event_fb), 3378 eventId_fb, &iaAddr_fb) != BCM_E_NONE) { 3379 rv = BCM_E_INTERNAL; 3380 goto exit; 3381 } 3382 pGdpllContext->eventId[eventId_fb] = iaAddr_fb; 3383 } 3384 3385 /* Reference event forward configuration */ 3386 if(flags & BCM_GDPLL_EVENT_CONFIG_REF) { 3387 if (pGdpllChan->event_ref.input_event == bcmGdpllInputEventPORT) { 3388 rv = _bcm_esw_gdpll_portmap_get(unit, pGdpllChan->event_ref.port, &gdpll_port); 3389 if (rv != BCM_E_NONE) { 3390 goto exit; 3391 } 3392 pGdpllChan->event_ref.port = gdpll_port; 3393 } 3394 3395 if (_bcm_esw_gdpll_input_eventId_get(unit, 3396 &pGdpllChan->event_ref, 3397 &eventId_ref) != BCM_E_NONE) { 3398 rv = BCM_E_INTERNAL; 3399 goto exit; 3400 } 3401 3402 bsl_printf("GDPLL: Reference eventId:%d\n", eventId_ref); 3403 /* Check if the event is already under use */ 3404 if(_bcm_esw_gdpll_input_eventId_inUse(unit, 3405 eventId_ref, &inUse) != BCM_E_NONE) { 3406 rv = BCM_E_INTERNAL; 3407 goto exit; 3408 } 3409 if (inUse) { 3410 /* Event is under use by other channel */ 3411 rv = BCM_E_PARAM; 3412 goto exit; 3413 } 3414 3415 /* Configure the input event and get iaAddr_ref */ 3416 if(_bcm_esw_gdpll_event_config_set(unit, &(pGdpllChan->event_ref), eventId_ref, &iaAddr_ref) != BCM_E_NONE) { 3417 rv = BCM_E_INTERNAL; 3418 goto exit; 3419 } 3420 pGdpllContext->eventId[eventId_ref] = iaAddr_ref; 3421 } 3422 3423 /* Channel priority set */ 3424 if(flags & BCM_GDPLL_CHAN_SET_PRIORITY) { 3425 if(_bcm_esw_gdpll_chan_priority_set(unit, chan, 3426 pGdpllChan->chan_prio) != BCM_E_NONE) { 3427 rv = BCM_E_INTERNAL; 3428 goto exit; 3429 } 3430 } 3431 3432 /* Channel DPLL configuration */ 3433 if(flags & BCM_GDPLL_CONF_DPLL) { 3434 dpllParam.dpll_config = pGdpllChan->chan_dpll_config; 3435 dpllParam.dpll_state = pGdpllChan->chan_dpll_state; 3436 if(_bcm_esw_gdpll_chan_config_dpll_set(unit, chan, 3437 &dpllParam) != BCM_E_NONE) { 3438 rv = BCM_E_INTERNAL; 3439 goto exit; 3440 } 3441 if (pGdpllChan->chan_dpll_config.phase_counter_ref) { 3442 phaseCounterRef = 1; 3443 } 3444 } 3445 3446 /* Channel output configurations */ 3447 if(flags & BCM_GDPLL_CHAN_OUTPUT_CONF) { 3448 if (pGdpllChan->out_event == bcmGdpllOutputEventTXPI) { 3449 rv = _bcm_esw_gdpll_portmap_get(unit, pGdpllChan->port, &gdpll_port); 3450 if (rv != BCM_E_NONE) { 3451 goto exit; 3452 } 3453 pGdpllChan->port = gdpll_port; 3454 if(_bcm_esw_gdpll_chan_out_txpi_set(unit, chan, pGdpllChan->port) != BCM_E_NONE) { 3455 rv = BCM_E_INTERNAL; 3456 goto exit; 3457 } 3458 } else { 3459 if(_bcm_esw_gdpll_chan_out_misc_set(unit, chan, pGdpllChan->out_event) != BCM_E_NONE) { 3460 rv = BCM_E_INTERNAL; 3461 goto exit; 3462 } 3463 } 3464 } 3465 3466 /* Set the channel soft state data structures */ 3467 if((flags & BCM_GDPLL_EVENT_CONFIG_REF) && 3468 (pGdpllContext->dpll_chan[chan].phaseConterRef == 0)) { 3469 pGdpllContext->dpll_chan[chan].eventId_ref = eventId_ref; 3470 } 3471 3472 if(flags & BCM_GDPLL_EVENT_CONFIG_FB) { 3473 pGdpllContext->dpll_chan[chan].eventId_fb = eventId_fb; 3474 } 3475 3476 /* Set the channel soft state data structures */ 3477 if (phaseCounterRef) { 3478 3479 /* If the ref event is not in use by any channels, then free */ 3480 if (pGdpllContext->dpll_chan[chan].eventId_ref < BCM_GDPLL_NUM_INPUT_EVENTS) { 3481 if(_bcm_esw_gdpll_input_eventId_inUse(unit, 3482 pGdpllContext->dpll_chan[chan].eventId_ref, &inUse) != BCM_E_NONE) { 3483 rv = BCM_E_INTERNAL; 3484 goto exit; 3485 } 3486 if (!inUse) { 3487 pGdpllContext->eventId[pGdpllContext->dpll_chan[chan].eventId_ref] = BCM_GDPLL_NUM_IA_ENTRIES; 3488 } else { 3489 bsl_printf("GDPLL: This channel has phaseCounterRef but the ref settings are used by other channel\n"); 3490 } 3491 } 3492 3493 pGdpllContext->dpll_chan[chan].phaseConterRef = 1; 3494 pGdpllContext->dpll_chan[chan].eventId_ref = BCM_GDPLL_NUM_INPUT_EVENTS; /* Indicating invalid event */; 3495 } 3496 3497 /* Now update the flags for the channel */ 3498 pGdpllContext->dpll_chan[chan].flag |= flags; 3499 3500 /* Upadet the channel with ref and fb event */ 3501 _bcm_esw_gdpll_chan_update_set(unit, chan); 3502 3503 /* Miscellaneous settings */ 3504 if ((pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS0ConvTC) || 3505 (pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS1ConvTC)) { 3506 3507 /* Settings specific to Broadsync refernce(Ex: use-case-2b) 3508 * NS_BSx_BS_TC_CTRL.MODE - 0:TS Init 1:No TS Init 3509 * NS_BSx_BS_TC_CTRL.ENABLE - 0 to 1 transition will cause Mode in affect 3510 * NS_TIMESYNC_TSx_BS_INIT_CTRL.SRC_ID - 0:BS0 1:BS1 3511 * NS_BSx_BS_CONFIG - MODE:0 BS in Input mode 3512 */ 3513 3514 if ((pGdpllChan->out_event == bcmGdpllOutputEventTS0) && (pGdpllChan->event_ref.ts_counter == 0)) { 3515 WRITE_NS_REGr(unit, NS_TIMESYNC_TS0_BS_INIT_CTRLr, 0, 3516 pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS0ConvTC ? 0:1); 3517 } else if ((pGdpllChan->out_event == bcmGdpllOutputEventTS1) && (pGdpllChan->event_ref.ts_counter == 1)) { 3518 WRITE_NS_REGr(unit, NS_TIMESYNC_TS1_BS_INIT_CTRLr, 0, 3519 pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS0ConvTC ? 0:1); 3520 } else { 3521 goto exit; 3522 } 3523 3524 /* Set MODE:0 and ENABLE:0 */ 3525 READ_NS_REGr(unit, pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS0ConvTC ? NS_BS0_BS_TC_CTRLr:NS_BS1_BS_TC_CTRLr, 3526 0, ®Val); 3527 soc_reg_field_set(unit, NS_BS0_BS_TC_CTRLr, ®Val, MODEf, 0); 3528 soc_reg_field_set(unit, NS_BS0_BS_TC_CTRLr, ®Val, ENABLEf, 0); 3529 WRITE_NS_REGr(unit, pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS0ConvTC ? NS_BS0_BS_TC_CTRLr:NS_BS1_BS_TC_CTRLr, 3530 0, regVal); 3531 3532 /* Now set ENABLE:1 that makes the MODE settings get in place */ 3533 soc_reg_field_set(unit, NS_BS0_BS_TC_CTRLr, ®Val, ENABLEf, 1); 3534 WRITE_NS_REGr(unit, pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS0ConvTC ? NS_BS0_BS_TC_CTRLr:NS_BS1_BS_TC_CTRLr, 3535 0, regVal); 3536 3537 /* Set BS in Input mode */ 3538 READ_NS_REGr(unit, pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS0ConvTC ? NS_BS0_BS_CONFIGr:NS_BS1_BS_CONFIGr, 3539 0, ®Val); 3540 soc_reg_field_set(unit, NS_BS0_BS_CONFIGr, ®Val, MODEf, 0); 3541 WRITE_NS_REGr(unit, pGdpllChan->event_ref.input_event == bcmGdpllInputEventBS0ConvTC ? NS_BS0_BS_CONFIGr:NS_BS1_BS_CONFIGr, 3542 0, regVal); 3543 } 3544 3545 exit: 3546 sal_mutex_give(pGdpllContext->mutex); 3547 return (rv); 3548 } 3549 3550 /* 3551 * Function: 3552 * bcm_esw_gdpll_chan_destroy 3553 * Purpose: 3554 * Destroys the GDPLL channel 3555 * Parameters: 3556 * unit - (IN) StrataSwitch Unit #. 3557 * chan - (IN) Channel number 3558 * Returns: 3559 * BCM_E_NONE 3560 * BCM_E_XXX 3561 */ 3562 int 3563 bcm_esw_gdpll_chan_destroy(int unit, int chan) 3564 { 3565 int rv = BCM_E_NONE; 3566 int inUse = 0; 3567 gdpll_context_t *pGdpllContext = pGdpllCtx; 3568 #ifdef BCN_WAR 3569 uint32 enableReg = 0; 3570 uint32 disable_chan_nco = 0; 3571 #endif 3572 3573 if((chan >= BCM_GDPLL_NUM_CHANNELS) || 3574 (pGdpllContext == NULL)) { 3575 rv = BCM_E_PARAM; 3576 goto exit; 3577 } 3578 3579 sal_mutex_take(pGdpllContext->mutex, sal_mutex_FOREVER); 3580 3581 /* If channel is not created, then return BCM_E_NOT_FOUND */ 3582 if (pGdpllContext->dpll_chan[chan].flag == 0) { 3583 return BCM_E_NOT_FOUND; 3584 } 3585 3586 /* Disable the channel */ 3587 bcm_esw_gdpll_chan_enable(unit, chan, 0); 3588 pGdpllContext->dpll_chan[chan].flag = 0; 3589 3590 /* If the ref event is not in use by any channels, then free */ 3591 if (pGdpllContext->dpll_chan[chan].eventId_ref < BCM_GDPLL_NUM_INPUT_EVENTS) { 3592 if(_bcm_esw_gdpll_input_eventId_inUse(unit, 3593 pGdpllContext->dpll_chan[chan].eventId_ref, &inUse) != BCM_E_NONE) { 3594 rv = BCM_E_INTERNAL; 3595 goto exit; 3596 } 3597 if (!inUse) { 3598 pGdpllContext->eventId[pGdpllContext->dpll_chan[chan].eventId_ref] = BCM_GDPLL_NUM_IA_ENTRIES; 3599 } else { 3600 bsl_printf("GDPLL: Error !! Ref event is in use by other channel \n"); 3601 } 3602 } 3603 3604 /* If the fb event is not in use by any channels, then free */ 3605 if (pGdpllContext->dpll_chan[chan].eventId_fb < BCM_GDPLL_NUM_INPUT_EVENTS) { 3606 if(_bcm_esw_gdpll_input_eventId_inUse(unit, 3607 pGdpllContext->dpll_chan[chan].eventId_fb, &inUse) != BCM_E_NONE) { 3608 rv = BCM_E_INTERNAL; 3609 goto exit; 3610 } 3611 if (!inUse) { 3612 pGdpllContext->eventId[pGdpllContext->dpll_chan[chan].eventId_fb] = BCM_GDPLL_NUM_IA_ENTRIES; 3613 } else { 3614 bsl_printf("GDPLL: Error !! FB event is IN use by other channel\n"); 3615 } 3616 } 3617 3618 _bcm_esw_gdpll_input_array_free(unit, 3619 pGdpllContext->dpll_chan[chan].eventId_ref); 3620 pGdpllContext->dpll_chan[chan].eventId_ref = BCM_GDPLL_NUM_INPUT_EVENTS; 3621 3622 _bcm_esw_gdpll_input_array_free(unit, 3623 pGdpllContext->dpll_chan[chan].eventId_fb); 3624 pGdpllContext->dpll_chan[chan].eventId_fb = BCM_GDPLL_NUM_INPUT_EVENTS; 3625 pGdpllContext->dpll_chan[chan].phaseConterRef = 0; /*BCM_GDPLL_NUM_INPUT_EVENTS; */ 3626 3627 #ifdef BCN_WAR 3628 /* 3629 * If the channel is for BCN output, then clear location to indicate R5, 3630 * not to process the NCO and update BCN counter 3631 */ 3632 if(chan == soc_iproc_m7_read(unit, BCM_M7_DTCM_BASE + DPLL_BCN_UPDATE_LOC)) { 3633 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_BCN_UPDATE_LOC, 0xFF); 3634 disable_chan_nco = 1; 3635 } else if (chan == soc_iproc_m7_read(unit, BCM_M7_DTCM_BASE + DPLL_NTPTOD_UPDATE_LOC)) { 3636 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_NTPTOD_UPDATE_LOC, 0xFF); 3637 disable_chan_nco = 1; 3638 } else if (chan == soc_iproc_m7_read(unit, BCM_M7_DTCM_BASE + DPLL_PTPTOD_UPDATE_LOC)) { 3639 soc_iproc_m7_write(unit, BCM_M7_DTCM_BASE + DPLL_PTPTOD_UPDATE_LOC, 0xFF); 3640 disable_chan_nco = 1; 3641 } 3642 3643 if (disable_chan_nco) { 3644 /* Disable the Channel Output array status reporting over interrupt */ 3645 if (chan < 32) { 3646 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE0r, 0, &enableReg); 3647 enableReg &= ~(1<<chan); 3648 soc_reg_field_set(unit, NS_GDPLL_NCO_OUT_ENABLE0r, &enableReg, INTENf, enableReg); 3649 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE0r, 0, enableReg); /* 0:31 */ 3650 } else if (chan < 64) { 3651 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE1r, 0, &enableReg); 3652 enableReg &= ~(1<<(chan-32)); 3653 soc_reg_field_set(unit, NS_GDPLL_NCO_OUT_ENABLE1r, &enableReg, INTENf, enableReg); 3654 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE1r, 0, enableReg); /* 32:63 */ 3655 } else if (chan < 96) { 3656 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE2r, 0, &enableReg); 3657 enableReg &= ~(1<<(chan-64)); 3658 soc_reg_field_set(unit, NS_GDPLL_NCO_OUT_ENABLE2r, &enableReg, INTENf, enableReg); 3659 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE2r, 0, enableReg); /* 64:95 */ 3660 } else if (chan < 128) { 3661 READ_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE3r, 0, &enableReg); 3662 enableReg &= ~(1<<(chan-96)); 3663 soc_reg_field_set(unit, NS_GDPLL_NCO_OUT_ENABLE3r, &enableReg, INTENf, enableReg); 3664 WRITE_NS_REGr(unit, NS_GDPLL_NCO_OUT_ENABLE3r, 0, enableReg); /* 64:95 */ 3665 } 3666 } 3667 #endif 3668 3669 exit: 3670 sal_mutex_give(pGdpllContext->mutex); 3671 return (rv); 3672 } 3673 3674 /* 3675 * Function: 3676 * bcm_esw_gdpll_chan_state_get 3677 * Purpose: 3678 * Get Channel status 3679 * Parameters: 3680 * unit - (IN) StrataSwitch Unit #. 3681 * chan - (IN) Channel Number 3682 * dpllState - (OUT) DPLL State 3683 * Returns: 3684 * BCM_E_NONE 3685 * BCM_E_XXX 3686 */ 3687 int 3688 bcm_esw_gdpll_chan_state_get(int unit, int chan, uint32 *dpllState) 3689 { 3690 int rv = BCM_E_NONE; 3691 dpll_param_t dpllParam; 3692 uint32 regVal = 0; 3693 uint8 chan_enable = 0; 3694 uint8 chan_err = 0; 3695 uint32 dpllAddr = DPLL_CHAN_PARAM_ADDR(BCM_M7_DTCM_BASE, chan); 3696 uint32 addrOffset; 3697 3698 if ((chan >= BCM_GDPLL_NUM_CHANNELS) || (chan < 0) || (dpllState == NULL)) { 3699 rv = BCM_E_PARAM; 3700 goto exit; 3701 } 3702 3703 /* Check the channel enable status */ 3704 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, chan, ®Val); 3705 chan_enable = soc_reg_field_get(unit, NS_GDPLL_IA_UPDATE_CONFIGr, regVal, ENABLEf); 3706 if (!chan_enable) { 3707 /* Channel is not enabled */ 3708 *dpllState = 0; 3709 goto exit; 3710 } 3711 3712 if (chan < 32) { 3713 READ_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS0r, 0, ®Val); 3714 chan_err = (regVal & (1<<chan)) ? 1:0; 3715 } else if (chan < 64) { 3716 READ_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS1r, 0, ®Val); 3717 chan_err = (regVal & (1<<(chan-32))) ? 1:0; 3718 } else if (chan < 96) { 3719 READ_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS2r, 0, ®Val); 3720 chan_err = (regVal & (1<<(chan-64))) ? 1:0; 3721 } else if (chan < 128) { 3722 READ_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS3r, 0, ®Val); 3723 chan_err = (regVal & (1<<(chan-96))) ? 1:0; 3724 } 3725 3726 if(_bcm_esw_gdpll_chan_config_dpll_get(unit, chan, 3727 &dpllParam) != BCM_E_NONE) { 3728 rv = BCM_E_INTERNAL; 3729 goto exit; 3730 } 3731 3732 /* Clear the M7-DPLL indications */ 3733 if (chan_err) { 3734 dpllParam.dpll_state.lockIndicator = 0; 3735 dpllParam.dpll_state.lossOfLockIndicator = 0; 3736 m7DpllParam.m7_dpll_state.LargeErrorIndicator = 0; 3737 3738 addrOffset = SAL_OFFSETOF(m7_dpll_param_t, m7_dpll_state.LockIndicator); 3739 soc_iproc_m7_write(unit, dpllAddr+addrOffset, 0); 3740 3741 /* Clear the channel error */ 3742 if (chan < 32) { 3743 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS0r, 0, 1<<chan); 3744 } else if (chan < 64) { 3745 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS1r, 0, 1<<(chan-32)); 3746 } else if (chan < 96) { 3747 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS2r, 0, 1<<(chan-64)); 3748 } else if (chan < 128) { 3749 WRITE_NS_REGr(unit, NS_GDPLL_IA_IN_STATUS3r, 0, 1<<(chan-96)); 3750 } 3751 } 3752 *dpllState = dpllParam.dpll_state.lockIndicator | 3753 (dpllParam.dpll_state.lossOfLockIndicator & 0x7F) << 1 | 3754 chan_enable << 8 | chan_err << 31 | 3755 (m7DpllParam.m7_dpll_state.LargeErrorIndicator & 0x1) << 30; 3756 exit: 3757 return (rv); 3758 } 3759 3760 /* 3761 * Function: 3762 * bcm_esw_gdpll_chan_debug_enable 3763 * Purpose: 3764 * Enable Channel debugging 3765 * Parameters: 3766 * unit - (IN) StrataSwitch Unit #. 3767 * chan - (IN) Channel Number 3768 * debug_mode - (IN) Debug mode 3769 * enable - (IN) Enable flag 3770 * Returns: 3771 * BCM_E_NONE 3772 * BCM_E_XXX 3773 */ 3774 int 3775 bcm_esw_gdpll_chan_debug_enable(int unit, int chan, 3776 bcm_gdpll_debug_mode_t debug_mode, int enable) 3777 { 3778 int rv = BCM_E_NONE; 3779 3780 if(chan >= BCM_GDPLL_NUM_CHANNELS) { 3781 rv = BCM_E_PARAM; 3782 goto exit; 3783 } 3784 3785 BCM_IF_ERROR_RETURN(_bcm_esw_gdpll_chan_debug_mode_set(unit, chan, 3786 debug_mode)); 3787 exit: 3788 return (rv); 3789 } 3790 3791 /* 3792 * Function: 3793 * bcm_esw_gdpll_debug_cb_register 3794 * Purpose: 3795 * Register Channel debug callback 3796 * Parameters: 3797 * unit - (IN) StrataSwitch Unit #. 3798 * user_data - (IN) Users private data 3799 * cb - (IN) Callback handler 3800 * Returns: 3801 * BCM_E_NONE 3802 * BCM_E_XXX 3803 */ 3804 int 3805 bcm_esw_gdpll_debug_cb_register(int unit, void *user_data, 3806 bcm_gdpll_debug_cb cb) 3807 { 3808 int rv = BCM_E_NONE; 3809 gdpll_context_t *pGdpllContext = pGdpllCtx; 3810 3811 if(pGdpllContext == NULL) { 3812 rv = BCM_E_PARAM; 3813 goto exit; 3814 } 3815 3816 pGdpllContext->debug_cb = cb; 3817 pGdpllContext->pUserData = user_data; 3818 3819 exit: 3820 return (rv); 3821 } 3822 3823 /* 3824 * Function: 3825 * bcm_esw_gdpll_cb_register 3826 * Purpose: 3827 * Register Generic GDPLL callback 3828 * Parameters: 3829 * unit - (IN) StrataSwitch Unit #. 3830 * cb_type - (IN) Callback type 3831 * cb - (IN) Callback handler 3832 * user_data - (IN) Users private data 3833 * Returns: 3834 * BCM_E_NONE 3835 * BCM_E_XXX 3836 */ 3837 int bcm_esw_gdpll_cb_register(int unit, int cb_type, 3838 bcm_gdpll_cb cb, void *user_data) 3839 { 3840 int rv = BCM_E_NONE; 3841 gdpll_context_t *pGdpllContext = pGdpllCtx; 3842 uint32 regVal = 0; 3843 3844 if((pGdpllContext == NULL) || 3845 (cb && (pGdpllContext->gdpll_cb != NULL))) { 3846 rv = BCM_E_PARAM; 3847 goto exit; 3848 } 3849 3850 if(cb) { 3851 pGdpllContext->gdpll_cb = cb; 3852 pGdpllContext->pGdpll_cb_data = user_data; 3853 } 3854 3855 if (cb_type == BCM_GDPLL_CB_RSVD1) { 3856 /* Enable the 3857 * Enable the RSVD1 message arrival status leaf-level interrupt(both RX and ERR interrupts) 3858 * in MESSAGE_INT_ENABLE(BRCM_RESERVED_IPROC_10) 3859 * Enable RSVD1 interrupt on Nanosync interrupt line in NS_TS_INT_ENABLE(bit-22) 3860 */ 3861 if (soc_feature(unit, soc_feature_rsvd1_intf)) { 3862 pGdpllContext->gdpll_cb_type |= cb_type; 3863 3864 /* Enable the RSVD1 leaf-level interupt, both RX and ERR */ 3865 READ_NS_REGr(unit, BRCM_RESERVED_IPROC_10r, 0, ®Val); 3866 regVal |= 0x3; 3867 WRITE_NS_REGr(unit, BRCM_RESERVED_IPROC_10r, 0, regVal); 3868 3869 /* Enable RSVD1 status interrupt on Nanosync intr line */ 3870 READ_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, ®Val); 3871 regVal |= INTR_RSVD1_MESSAGE_RX_STATUS; 3872 WRITE_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, regVal); 3873 } 3874 } 3875 3876 if (pGdpllContext->gdpll_cb_type == 0) { 3877 pGdpllContext->gdpll_cb = NULL; 3878 pGdpllContext->pGdpll_cb_data = NULL; 3879 } 3880 3881 exit: 3882 return (rv); 3883 } 3884 3885 /* 3886 * Function: 3887 * bcm_esw_gdpll_cb_unregister 3888 * Purpose: 3889 * Un-register Generic GDPLL callback 3890 * Parameters: 3891 * unit - (IN) StrataSwitch Unit #. 3892 * cb_type - (IN) Callback type 3893 * Returns: 3894 * BCM_E_NONE 3895 * BCM_E_XXX 3896 */ 3897 int bcm_esw_gdpll_cb_unregister(int unit, int cb_type) 3898 { 3899 int rv = BCM_E_NONE; 3900 uint32 regVal = 0; 3901 gdpll_context_t *pGdpllContext = pGdpllCtx; 3902 3903 if(pGdpllContext == NULL) { 3904 rv = BCM_E_PARAM; 3905 goto exit; 3906 } 3907 3908 if (cb_type == BCM_GDPLL_CB_RSVD1) { 3909 pGdpllContext->gdpll_cb_type &= ~cb_type; 3910 3911 if (soc_feature(unit, soc_feature_rsvd1_intf)) { 3912 /* Disable RSVD1 status interrupt on Nanosync intr line */ 3913 READ_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, ®Val); 3914 regVal &= ~INTR_RSVD1_MESSAGE_RX_STATUS; 3915 WRITE_NS_REGr(unit, NS_TS_INT_ENABLEr, 0, regVal); 3916 3917 /* Disable the RSVD1 leaf-level interupt, both RX and ERR */ 3918 regVal = 0; 3919 WRITE_NS_REGr(unit, BRCM_RESERVED_IPROC_10r, 0, regVal); 3920 } 3921 } 3922 3923 if (pGdpllContext->gdpll_cb_type == 0) { 3924 pGdpllContext->gdpll_cb = NULL; 3925 pGdpllContext->pGdpll_cb_data = NULL; 3926 } 3927 3928 exit: 3929 return (rv); 3930 } 3931 3932 /* 3933 * Function: 3934 * bcm_esw_gdpll_flush 3935 * Purpose: 3936 * Flush the GDPLL pipeline 3937 * Parameters: 3938 * unit - (IN) StrataSwitch Unit #. 3939 * Returns: 3940 * BCM_E_NONE 3941 * BCM_E_XXX 3942 */ 3943 int 3944 bcm_esw_gdpll_flush (int unit) 3945 { 3946 int rv = BCM_E_NONE; 3947 int chan = 0; 3948 gdpll_context_t *pGdpllContext = pGdpllCtx; 3949 3950 if(pGdpllContext == NULL) { 3951 rv = BCM_E_PARAM; 3952 goto exit; 3953 } 3954 3955 for(chan = 0; chan < BCM_GDPLL_NUM_CHANNELS; chan++) { 3956 bcm_esw_gdpll_chan_destroy(unit, chan); 3957 } 3958 3959 /* Disable the GDPLL capture */ 3960 _bcm_esw_gdpll_capture_enable_m7_set(unit, 0); 3961 3962 pGdpllContext->debug_cb = NULL; 3963 pGdpllContext->pUserData = NULL; 3964 3965 _bcm_esw_gdpll_flush(unit); 3966 3967 exit: 3968 return (rv); 3969 } 3970 3971 /* 3972 * Function: 3973 * bcm_esw_gdpll_debug 3974 * Purpose: 3975 * Enable the GDPLL global debug feature 3976 * This will set the flag for M7 to start pushing the debug 3977 * content to debug buffers 3978 * Parameters: 3979 * unit - (IN) StrataSwitch Unit #. 3980 * Returns: 3981 * BCM_E_NONE 3982 * BCM_E_XXX 3983 */ 3984 int 3985 bcm_esw_gdpll_debug (int unit, int enable) 3986 { 3987 int rv = BCM_E_NONE; 3988 uint32 regVal = 0; 3989 uint32 dpllDebugFlag = BCM_M7_DTCM_BASE + DPLL_DEBUG_ENABLE_OFFSET; 3990 3991 if (enable) { 3992 /* Check if its already enabled */ 3993 if(soc_iproc_m7_read (unit, dpllDebugFlag)) { 3994 /* Already enabled. Return error */ 3995 rv = BCM_E_PARAM; 3996 goto exit; 3997 } 3998 3999 /* Reset the debug pointers and re-enable */ 4000 READ_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, 0, ®Val); 4001 soc_reg_field_set(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, ®Val, ENABLEf, 0); 4002 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, 0, regVal); 4003 4004 soc_reg_field_set(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, ®Val, ENABLEf, 1); 4005 WRITE_NS_REGr(unit, NS_GDPLL_DEBUG_M7DG_ENABLEr, 0, regVal); 4006 } 4007 4008 soc_iproc_m7_write(unit, dpllDebugFlag, enable); 4009 4010 exit: 4011 return (rv); 4012 } 4013 4014 int 4015 _bcm_esw_gdpll_tdpllinstance_bind(int unit, int gdpllChan, uint32 tdpll_instance_num) 4016 { 4017 int rv = BCM_E_NONE; 4018 uint32 regVal = 0; 4019 uint32 eventId_ref; 4020 bcm_gdpll_chan_input_t inputEvent; 4021 uint32 iaAddr; 4022 4023 if ((tdpll_instance_num < 0 || tdpll_instance_num >= NUM_TDPLL_INSTANCE) || 4024 (gdpllChan < 0 || gdpllChan >= BCM_GDPLL_NUM_CHANNELS)) { 4025 bsl_printf("_bcm_esw_gdpll_tdpllinstance_bind: Error!! parameters\n"); 4026 rv = BCM_E_PARAM; 4027 goto exit; 4028 } 4029 4030 if (BCM_GDPLL_NUM_IA_ENTRIES == gdpll_tdpll_state.tdpll_instace[tdpll_instance_num]) { 4031 /* Alloc the IA entry */ 4032 inputEvent.input_event = bcmGdpllInputEventR5; 4033 if(_bcm_esw_gdpll_input_eventId_get(unit, 4034 &inputEvent, 4035 &eventId_ref) != BCM_E_NONE) { 4036 bsl_printf("_bcm_esw_gdpll_tdpllinstance_bind: Error!! in input_eventId_get \n"); 4037 rv = BCM_E_INTERNAL; 4038 goto exit; 4039 } 4040 4041 rv = _bcm_esw_gdpll_input_array_alloc(unit, eventId_ref, &iaAddr); 4042 if (rv != BCM_E_NONE) { 4043 bsl_printf("_bcm_esw_gdpll_tdpllinstance_bind: Error!! input_array_alloc failed. %s\n", bcm_errmsg(rv)); 4044 goto exit; 4045 } 4046 4047 gdpll_tdpll_state.tdpll_instace[tdpll_instance_num] = iaAddr; 4048 } 4049 4050 bsl_printf("_bcm_esw_gdpll_tdpllinstance_bind Channel: %d ref:%d\n", gdpllChan, gdpll_tdpll_state.tdpll_instace[tdpll_instance_num]); 4051 4052 /* Channel update with reference indix */ 4053 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, gdpllChan, ®Val); 4054 soc_reg_field_set(unit, NS_GDPLL_IA_UPDATE_CONFIGr, ®Val, REFERENCE_IDf, 4055 gdpll_tdpll_state.tdpll_instace[tdpll_instance_num]); 4056 WRITE_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, gdpllChan, regVal); 4057 4058 exit: 4059 return rv; 4060 } 4061 4062 int 4063 _bcm_esw_tdpll_chan_create(int unit, uint32 flags, 4064 bcm_gdpll_chan_t *pGdpllChan, int *pChan, 4065 uint32 tdpll_instance_num) 4066 { 4067 int rv = BCM_E_NONE; 4068 uint32 iaAddr; 4069 uint32 eventId_ref; 4070 uint32 regVal = 0; 4071 4072 /* Checks if reference is set to be from R5 and check instance number */ 4073 if ((bcmGdpllInputEventR5 != pGdpllChan->event_ref.input_event) || 4074 (tdpll_instance_num < 0 || tdpll_instance_num >= NUM_TDPLL_INSTANCE)) { 4075 bsl_printf("_bcm_esw_tdpll_chan_create: Error!! parameters\n"); 4076 rv = BCM_E_PARAM; 4077 goto exit; 4078 } 4079 4080 rv = bcm_esw_gdpll_chan_create (unit, flags, pGdpllChan, pChan); 4081 if (BCM_FAILURE(rv)) { 4082 bsl_printf("_bcm_esw_tdpll_chan_create: Error!! gdpll_chan_create failed. %s\n", bcm_errmsg(rv)); 4083 goto exit; 4084 } 4085 4086 if (BCM_GDPLL_NUM_IA_ENTRIES == gdpll_tdpll_state.tdpll_instace[tdpll_instance_num]) { 4087 /* Alloc the IA entry */ 4088 if(_bcm_esw_gdpll_input_eventId_get(unit, 4089 &pGdpllChan->event_ref, 4090 &eventId_ref) != BCM_E_NONE) { 4091 bsl_printf("_bcm_esw_tdpll_chan_create: Error!! in input_eventId_get \n"); 4092 rv = BCM_E_INTERNAL; 4093 goto deleteChan; 4094 } 4095 4096 rv = _bcm_esw_gdpll_input_array_alloc(unit, eventId_ref, &iaAddr); 4097 if (rv != BCM_E_NONE) { 4098 bsl_printf("_bcm_esw_tdpll_chan_create: Error!! input_array_alloc failed. %s\n", bcm_errmsg(rv)); 4099 goto deleteChan; 4100 } 4101 4102 gdpll_tdpll_state.tdpll_instace[tdpll_instance_num] = iaAddr; 4103 } 4104 4105 bsl_printf("_bcm_esw_tdpll_chan_create Channel: %d ref:%d\n", *pChan, gdpll_tdpll_state.tdpll_instace[tdpll_instance_num]); 4106 4107 /* Channel update with reference indix */ 4108 READ_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, *pChan, ®Val); 4109 soc_reg_field_set(unit, NS_GDPLL_IA_UPDATE_CONFIGr, ®Val, REFERENCE_IDf, 4110 gdpll_tdpll_state.tdpll_instace[tdpll_instance_num]); 4111 WRITE_NS_REGr(unit, NS_GDPLL_IA_UPDATE_CONFIGr, *pChan, regVal); 4112 return rv; 4113 4114 deleteChan: 4115 rv = bcm_esw_gdpll_chan_destroy(unit, *pChan); 4116 if (BCM_FAILURE(rv)) { 4117 bsl_printf("_bcm_esw_tdpll_chan_create: chan destroy failed\n"); 4118 } 4119 exit: 4120 return rv; 4121 } 4122 4123 /* 4124 * Call this API if user want to perform one of the bellow or both 4125 * 1. disassociate instance with all outputs with valid instance number 4126 * 2. Free the channel allocated 4127 */ 4128 int 4129 _bcm_esw_tdpll_gdpll_chan_destroy(int unit, int chan, uint32 tdpll_instance_num) 4130 { 4131 int rv = BCM_E_NONE; 4132 4133 rv = bcm_esw_gdpll_chan_destroy(unit, chan); 4134 if (BCM_FAILURE(rv)) { 4135 bsl_printf("_bcm_esw_tdpll_gdpll_chan_destroy: chan destroy failed\n"); 4136 } 4137 4138 /* Free the instance with associated outputs */ 4139 if ((tdpll_instance_num >= 0) && (tdpll_instance_num < NUM_TDPLL_INSTANCE)) { 4140 gdpll_tdpll_state.tdpll_instace[tdpll_instance_num] = BCM_GDPLL_NUM_IA_ENTRIES; 4141 } 4142 4143 return rv; 4144 } 4145 4146 #endif