pm12x10_xgs.c (27010B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 10 #include <soc/drv.h> 11 #include <soc/types.h> 12 #include <soc/error.h> 13 #include <soc/portmod/portmod_internal.h> 14 #include <soc/portmod/portmod_common.h> 15 #include <soc/portmod/portmod.h> 16 #include <soc/portmod/portmod_dispatch.h> 17 #include <soc/portmod/pm4x10.h> 18 #include <soc/portmod/pm12x10.h> 19 #include <soc/portmod/portmod_chain.h> 20 #include <soc/portmod/pm4x25_shared.h> 21 #include <soc/portmod/portmod_system.h> 22 23 24 25 #ifdef _ERR_MSG_MODULE_NAME 26 #error "_ERR_MSG_MODULE_NAME redefined" 27 #endif 28 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT 29 30 #ifdef PORTMOD_PM12X10_XGS_SUPPORT 31 32 static int pm12x10_xgs_core_seq[] = {0,1,2}; 33 34 #define PM_12x10_INFO(pm_info) ((pm_info)->pm_data.pm12x10_db) 35 #define PM_4X25_INFO(pm_info) (PM_12x10_INFO(pm_info)->pm4x25_info) 36 #define PM_4x25_DB(pm_info) (PM_4X25_INFO(pm_info)->pm_data.pm4x25_db) 37 38 39 #define PM_4X10_INFO(pm_info, i) (PM_12x10_INFO(pm_info)->pm4x10_info[pm12x10_xgs_core_seq[i]]) 40 #define PM_4X25_DRIVER(pm_info) PM_DRIVER(PM_4X25_INFO(pm_info)) 41 #define PM_4X10_DRIVER(pm_info, i) PM_DRIVER(PM_4X10_INFO(pm_info, pm12x10_xgs_core_seq[i])) 42 43 44 #define TOP_BLK_ID_OFFSET (4) 45 46 #define PM12x10_INTERNAL_4x10_CNT (3) 47 48 struct pm12x10_s{ 49 int blk_id; 50 pm_info_t pm4x25_info; 51 pm_info_t pm4x10_info[PM12x10_INTERNAL_4x10_CNT]; 52 portmod_pbmp_t phys; 53 uint32 external_top_mode; 54 int refclk_source; 55 }; 56 57 58 59 STATIC int 60 pm12x10_xgs_quad0_default_bus_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val) 61 { 62 return portmod_common_phy_sbus_reg_write(CXXPORT_WC_UCMEM_DATA0m, user_acc, core_addr, reg_addr, val); 63 } 64 65 STATIC int 66 pm12x10_xgs_quad0_default_bus_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val) 67 { 68 return portmod_common_phy_sbus_reg_read(CXXPORT_WC_UCMEM_DATA0m, user_acc, core_addr, reg_addr, val); 69 } 70 71 phymod_bus_t pm4x10_xgs_quad0_default_bus = { 72 "PM12x10_xgs Quad0 Bus", 73 pm12x10_xgs_quad0_default_bus_read, 74 pm12x10_xgs_quad0_default_bus_write, 75 NULL, 76 portmod_common_mutex_take, 77 portmod_common_mutex_give, 78 NULL, 79 NULL, 80 PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL 81 }; 82 83 STATIC int 84 pm12x10_xgs_quad1_default_bus_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val) 85 { 86 return portmod_common_phy_sbus_reg_write(CXXPORT_WC_UCMEM_DATA1m, user_acc, core_addr, reg_addr, val); 87 } 88 89 STATIC int 90 pm12x10_xgs_quad1_default_bus_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val) 91 { 92 return portmod_common_phy_sbus_reg_read(CXXPORT_WC_UCMEM_DATA1m, user_acc, core_addr, reg_addr, val); 93 } 94 95 phymod_bus_t pm4x10_xgs_quad1_default_bus = { 96 "PM12x10_xgs Quad1 Bus", 97 pm12x10_xgs_quad1_default_bus_read, 98 pm12x10_xgs_quad1_default_bus_write, 99 NULL, 100 portmod_common_mutex_take, 101 portmod_common_mutex_give, 102 NULL, 103 NULL, 104 PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL 105 }; 106 107 STATIC int 108 pm12x10_xgs_quad2_default_bus_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val) 109 { 110 return portmod_common_phy_sbus_reg_write(CXXPORT_WC_UCMEM_DATA2m, user_acc, core_addr, reg_addr, val); 111 } 112 113 STATIC int 114 pm12x10_xgs_quad2_default_bus_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val) 115 { 116 return portmod_common_phy_sbus_reg_read(CXXPORT_WC_UCMEM_DATA2m, user_acc, core_addr, reg_addr, val); 117 } 118 119 phymod_bus_t pm4x10_xgs_quad2_default_bus = { 120 "PM12x10_xgs Quad2 Bus", 121 pm12x10_xgs_quad2_default_bus_read, 122 pm12x10_xgs_quad2_default_bus_write, 123 NULL, 124 portmod_common_mutex_take, 125 portmod_common_mutex_give, 126 NULL, 127 NULL, 128 PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL 129 }; 130 131 STATIC portmod_ucode_buf_t pm12x10_xgs_ucode_buf[SOC_MAX_NUM_DEVICES] = {{NULL, 0}}; 132 133 STATIC int 134 pm4x10_xgs_quad0_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data) 135 { 136 int rv; 137 portmod_default_user_access_t *user_data; 138 int unit = ((portmod_default_user_access_t*)core->access.user_acc)->unit; 139 SOC_INIT_FUNC_DEFS; 140 141 user_data = (portmod_default_user_access_t*)core->access.user_acc; 142 143 rv = portmod_firmware_set(unit, 144 user_data->blk_id, 145 data, 146 length, 147 portmod_ucode_buf_order_reversed, 148 0, 149 &(pm12x10_xgs_ucode_buf[unit]), 150 NULL, 151 CXXPORT_WC_UCMEM_DATA0m, 152 CXXPORT_WC_UCMEM_CTRL0r); 153 _SOC_IF_ERR_EXIT(rv); 154 155 exit: 156 SOC_FUNC_RETURN; 157 } 158 159 STATIC int 160 pm4x10_xgs_quad1_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data) 161 { 162 int rv; 163 portmod_default_user_access_t *user_data; 164 int unit = ((portmod_default_user_access_t*)core->access.user_acc)->unit; 165 SOC_INIT_FUNC_DEFS; 166 167 user_data = (portmod_default_user_access_t*)core->access.user_acc; 168 169 rv = portmod_firmware_set(unit, 170 user_data->blk_id, 171 data, 172 length, 173 portmod_ucode_buf_order_reversed, 174 0, 175 &(pm12x10_xgs_ucode_buf[unit]), 176 NULL, 177 CXXPORT_WC_UCMEM_DATA1m, 178 CXXPORT_WC_UCMEM_CTRL1r); 179 _SOC_IF_ERR_EXIT(rv); 180 181 exit: 182 SOC_FUNC_RETURN; 183 } 184 185 STATIC int 186 pm4x10_xgs_quad2_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data) 187 { 188 int rv; 189 portmod_default_user_access_t *user_data; 190 int unit = ((portmod_default_user_access_t*)core->access.user_acc)->unit; 191 SOC_INIT_FUNC_DEFS; 192 193 user_data = (portmod_default_user_access_t*)core->access.user_acc; 194 195 rv = portmod_firmware_set(unit, 196 user_data->blk_id, 197 data, 198 length, 199 portmod_ucode_buf_order_reversed, 200 0, 201 &(pm12x10_xgs_ucode_buf[unit]), 202 NULL, 203 CXXPORT_WC_UCMEM_DATA2m, 204 CXXPORT_WC_UCMEM_CTRL2r); 205 _SOC_IF_ERR_EXIT(rv); 206 207 exit: 208 SOC_FUNC_RETURN; 209 } 210 211 int pm12x10_xgs_port_core_num_get(int unit, int port, pm_info_t pm_info, int* core_num) 212 { 213 int rv = 0, i; 214 SOC_INIT_FUNC_DEFS; 215 216 for(i = 0 ; i < 3 ; i++) 217 { 218 rv = PM_4X10_DRIVER(pm_info, i)->f_portmod_port_core_num_get(unit, port, 219 PM_4X10_INFO(pm_info,i), core_num); 220 _SOC_IF_ERR_EXIT(rv); 221 } 222 223 exit: 224 SOC_FUNC_RETURN; 225 } 226 227 int pm12x10_xgs_pm_destroy(int unit, pm_info_t pm_info) 228 { 229 if(pm_info->pm_data.pm12x10_db != NULL){ 230 sal_free(pm_info->pm_data.pm12x10_db); 231 pm_info->pm_data.pm12x10_db = NULL; 232 } 233 234 /* free pm12x10_xgs_ucode_buf */ 235 if(pm12x10_xgs_ucode_buf[unit].ucode_dma_buf != NULL){ 236 portmod_sys_dma_free(unit, pm12x10_xgs_ucode_buf[unit].ucode_dma_buf); 237 pm12x10_xgs_ucode_buf[unit].ucode_dma_buf = NULL; 238 } 239 pm12x10_xgs_ucode_buf[unit].ucode_alloc_size = 0; 240 241 return SOC_E_NONE; 242 } 243 244 245 246 int pm12x10_xgs_pm_init(int unit, const portmod_pm_create_info_internal_t* pm_add_info, 247 int wb_buffer_index, pm_info_t pm_info) 248 { 249 pm12x10_t pm12x10_data = NULL; 250 int nof_phys = 0, core; 251 portmod_bus_update_t bupdate; 252 SOC_INIT_FUNC_DEFS; 253 254 PORTMOD_PBMP_COUNT(pm_add_info->phys, nof_phys); 255 if(nof_phys != 12){ 256 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("number of phys should be 12"))); 257 } 258 pm12x10_data = sal_alloc(sizeof(*(pm_info->pm_data.pm12x10_db)), "specific_db"); 259 SOC_NULL_CHECK(pm12x10_data); 260 261 /*PM12x10 Top*/ 262 pm_info->type = portmodDispatchTypePm12x10_xgs; 263 pm_info->unit = unit; 264 pm_info->wb_buffer_id = wb_buffer_index; 265 266 pm_info->pm_data.pm12x10_db = pm12x10_data; 267 pm_info->pm_data.pm12x10_db->blk_id = pm_add_info->pm_specific_info.pm12x10.blk_id; 268 PORTMOD_PBMP_ASSIGN(pm_info->pm_data.pm12x10_db->phys, pm_add_info->phys); 269 270 for (core = 0; core < PM12x10_INTERNAL_4x10_CNT; core++) { 271 pm_info->pm_data.pm12x10_db->pm4x10_info[core] = 272 pm_add_info->pm_specific_info.pm12x10.pm4x10[core]; 273 } 274 275 pm_info->pm_data.pm12x10_db->pm4x25_info = pm_add_info->pm_specific_info.pm12x10.pm4x25; 276 pm_info->pm_data.pm12x10_db->refclk_source = pm_add_info->pm_specific_info.pm12x10.refclk_source; 277 pm_info->pm_data.pm12x10_db->external_top_mode = PORTMOD_PM12x10_F_EXTERNAL_TOP_MODE_GET(pm_add_info->pm_specific_info.pm12x10.flags); 278 279 if(!pm_info->pm_data.pm12x10_db->external_top_mode) { 280 /* Update Quad 0 */ 281 bupdate.blk_id = pm_info->pm_data.pm12x10_db->blk_id; 282 bupdate.default_bus = &pm4x10_xgs_quad0_default_bus; 283 bupdate.external_fw_loader = pm4x10_xgs_quad0_default_fw_loader; 284 bupdate.user_acc = NULL; /*use default user_acc */ 285 _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_12x10_INFO(pm_info)->pm4x10_info[0], &bupdate)); 286 287 /* Update Quad 1 */ 288 bupdate.default_bus = &pm4x10_xgs_quad1_default_bus; 289 bupdate.external_fw_loader = pm4x10_xgs_quad1_default_fw_loader; 290 _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_12x10_INFO(pm_info)->pm4x10_info[1], &bupdate)); 291 292 /* Update Quad 2 */ 293 bupdate.default_bus = &pm4x10_xgs_quad2_default_bus; 294 bupdate.external_fw_loader = pm4x10_xgs_quad2_default_fw_loader; 295 _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_12x10_INFO(pm_info)->pm4x10_info[2], &bupdate)); 296 297 } 298 299 exit: 300 if(SOC_FUNC_ERROR){ 301 pm12x10_xgs_pm_destroy(unit, pm_info); 302 } 303 SOC_FUNC_RETURN; 304 } 305 306 int pm12x10_xgs_port_attach (int unit, int port, pm_info_t pm_info, 307 const portmod_port_add_info_t* add_info) 308 { 309 portmod_port_add_info_t lcl_add_info = *add_info; 310 uint32 nof_lanes = 0; 311 int i = 0; 312 int rv = 0; 313 SOC_INIT_FUNC_DEFS; 314 315 PORTMOD_PBMP_COUNT(add_info->phys, nof_lanes); 316 317 if (nof_lanes == 10) { 318 319 } else if(nof_lanes != 12){ 320 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("number of lanes should be 10 or 12"))); 321 } 322 323 lcl_add_info.interface_config.flags |= PHYMOD_INTF_F_SET_CORE_MAP_MODE; 324 325 for(i = 0 ; i < 3 ; i++) 326 { 327 /* do it before pm is active only - so skip in the second pass of multi stage init */ 328 if (PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) || (lcl_add_info.flags == 0)) { 329 rv = PM_4X10_DRIVER(pm_info, i)->f_portmod_pm_bypass_set(unit, PM_4X10_INFO(pm_info,i), 1); 330 _SOC_IF_ERR_EXIT(rv); 331 } 332 333 if (i) { 334 lcl_add_info.flags |= PORTMOD_PORT_ADD_F_PORT_ATTACH_EXT_PHY_SKIP; 335 } 336 337 rv = PM_4X10_DRIVER(pm_info, i)->f_portmod_port_attach(unit, port, PM_4X10_INFO(pm_info,i), &lcl_add_info); 338 _SOC_IF_ERR_EXIT(rv); 339 } 340 341 if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info) || (add_info->flags == 0)) { 342 343 for(i = 0 ; i < 3 ; i++) 344 { 345 rv = PM_4X10_DRIVER(pm_info, i)->f_portmod_port_interface_config_set(unit, 346 port, PM_4X10_INFO(pm_info,i), 347 &add_info->interface_config, 348 PORTMOD_INIT_F_ALL_PHYS); 349 _SOC_IF_ERR_EXIT(rv); 350 } 351 352 if(!pm_info->pm_data.pm12x10_db->external_top_mode) { 353 rv = WRITE_CXXPORT_MODE_REGr(unit, port, 1); 354 _SOC_IF_ERR_EXIT(rv); 355 } 356 } 357 358 /* CAUI10 port is not connected to any PHY.., so clear the phy information before adding it */ 359 lcl_add_info = *add_info; 360 SOC_PBMP_CLEAR(lcl_add_info.phys); 361 for(i = 0 ; i < PM4X25_LANES_PER_CORE; i++){ 362 PM_4x25_DB(pm_info)->nof_phys[i] = 0; 363 } 364 365 rv = PM_4X25_DRIVER(pm_info)->f_portmod_port_attach(unit, port, PM_4X25_INFO(pm_info), &lcl_add_info); 366 _SOC_IF_ERR_EXIT(rv); 367 368 exit: 369 SOC_FUNC_RETURN; 370 } 371 372 int pm12x10_xgs_port_detach(int unit, int port, pm_info_t pm_info) 373 { 374 int rv = 0; 375 int i = 0; 376 SOC_INIT_FUNC_DEFS; 377 378 /* Detach MAC first since detaching PHY and resetting the TSC's first 379 * will render CLMAC/CLPORT registers inaccessible 380 */ 381 rv = PM_4X25_DRIVER(pm_info)->f_portmod_port_detach(unit, port, PM_4X25_INFO(pm_info)); 382 _SOC_IF_ERR_EXIT(rv); 383 384 for(i = 0 ; i < 3; i++){ 385 _SOC_IF_ERR_EXIT(PM_4X10_DRIVER(pm_info, i)->f_portmod_port_detach(unit, 386 port, PM_4X10_INFO(pm_info, i))); 387 } 388 389 390 if(!pm_info->pm_data.pm12x10_db->external_top_mode) { 391 rv = WRITE_CXXPORT_MODE_REGr(unit, port, 0); 392 _SOC_IF_ERR_EXIT(rv); 393 } 394 395 for(i = 0 ; i < 3 ; i++) 396 { 397 PM_4X10_DRIVER(pm_info, i)->f_portmod_pm_bypass_set(unit, PM_4X10_INFO(pm_info,i), 0); 398 } 399 400 exit: 401 SOC_FUNC_RETURN; 402 } 403 404 405 int pm12x10_xgs_port_led_chain_config(int unit, int port, pm_info_t pm_info, int value) 406 { 407 SOC_INIT_FUNC_DEFS; 408 409 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_LED_CHAIN_CONFIGr (unit, port, value)); 410 411 exit: 412 SOC_FUNC_RETURN; 413 } 414 415 int pm12x10_xgs_pm4x10_enable(int unit, int port, uint32 phy, uint32 enable) 416 { 417 pm_info_t pm_info; 418 int found = 0, quad, i, phy_i; 419 int core_num; 420 uint32 soft_reset, power_save; 421 soc_port_if_t if_type; 422 SOC_INIT_FUNC_DEFS; 423 424 /* get PM info */ 425 _SOC_IF_ERR_EXIT(portmod_pm_info_type_get(unit, port, portmodDispatchTypePm12x10_xgs, &pm_info)); 426 427 if(!pm_info->pm_data.pm12x10_db->external_top_mode) { 428 /* get inteface type */ 429 _SOC_IF_ERR_EXIT(portmod_port_interface_type_get(unit, port, &if_type)); 430 431 /* Find quad */ 432 i=0; 433 quad=-1; 434 PORTMOD_PBMP_ITER(PM_12x10_INFO(pm_info)->phys, phy_i) { 435 if(i%4 == 0) { 436 quad++; 437 } 438 if(phy_i == phy) { 439 found = 1; 440 break; 441 } 442 i++; 443 } 444 445 if(!found) { 446 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("Phy invalid for current PM"))); 447 } 448 449 _SOC_IF_ERR_EXIT(pm12x10_xgs_port_core_num_get(unit, port, pm_info, &core_num)); 450 451 if (!((((core_num >= 4) && (core_num <= 6))) || ((core_num >= 13) && (core_num <= 15)))) { 452 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("invalid core for current PM"))); 453 } 454 455 /* Enable block */ 456 _SOC_IF_ERR_EXIT(READ_CXXPORT_SOFT_RESETr(unit, port, &soft_reset)); 457 _SOC_IF_ERR_EXIT(READ_CXXPORT_POWER_SAVEr(unit, port, &power_save)); 458 459 switch(quad) { 460 case 0: 461 soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE0_RSTf, enable ? 0 : 1); 462 soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE0_PWRDWNf, enable ? 0 : 1); 463 break; 464 case 1: 465 soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE1_RSTf, enable ? 0 : 1); 466 soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE1_PWRDWNf, enable ? 0 : 1); 467 break; 468 case 2: 469 soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE2_RSTf, enable ? 0 : 1); 470 soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE2_PWRDWNf, enable ? 0 : 1); 471 break; 472 default: 473 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("Invalid quad"))); 474 } 475 476 /* PM4x25 reset */ 477 if(if_type != SOC_PORT_IF_CAUI) { 478 soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE3_RSTf, 1); /* always in reset */ 479 soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE3_PWRDWNf, 1); /* always power down */ 480 } else { 481 soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE3_RSTf, enable ? 0 : 1); 482 soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE3_PWRDWNf, enable ? 0 : 1); 483 } 484 485 if(enable) { 486 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_POWER_SAVEr(unit, port, power_save)); 487 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_SOFT_RESETr(unit, port, soft_reset)); 488 } else { 489 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_SOFT_RESETr(unit, port, soft_reset)); 490 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_POWER_SAVEr(unit, port, power_save)); 491 } 492 } 493 494 exit: 495 SOC_FUNC_RETURN; 496 } 497 498 499 int pm12x10_xgs_pm4x10_tsc_reset(int unit, int port, uint32 phy, uint32 in_reset) 500 { 501 pm_info_t pm_info; 502 int found = 0, quad, i, phy_i; 503 int core_num; 504 uint32 reg_val; 505 SOC_INIT_FUNC_DEFS; 506 507 /* get PM info */ 508 _SOC_IF_ERR_EXIT(portmod_pm_info_type_get(unit, port, portmodDispatchTypePm12x10_xgs, &pm_info)); 509 510 if(!pm_info->pm_data.pm12x10_db->external_top_mode) { 511 /* Find quad */ 512 i=0; 513 quad=-1; 514 PORTMOD_PBMP_ITER(PM_12x10_INFO(pm_info)->phys, phy_i) { 515 if(i%4 == 0) { 516 quad++; 517 } 518 if(phy_i == phy) { 519 found = 1; 520 break; 521 } 522 i++; 523 } 524 525 if(!found) { 526 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("Phy invalid for current PM"))); 527 } 528 529 530 _SOC_IF_ERR_EXIT(pm12x10_xgs_port_core_num_get(unit, port, pm_info, &core_num)); 531 532 if (!((((core_num >= 4) && (core_num <= 6))) || ((core_num >= 13) && (core_num <= 15)))) { 533 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("invalid core for current PM"))); 534 } 535 536 /* Enable block */ 537 switch(quad) { 538 case 0: 539 _SOC_IF_ERR_EXIT(READ_CXXPORT_XGXS0_CTRL0_REGr(unit, port, ®_val)); 540 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, ®_val, RSTB_HWf, in_reset ? 0 : 1); 541 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, ®_val, PWRDWNf, in_reset ? 1 : 0); 542 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, ®_val, IDDQf, in_reset ? 1 : 0); 543 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, ®_val, REFOUT_ENf, 0); 544 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, ®_val, REFIN_ENf, 1); 545 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_XGXS0_CTRL0_REGr(unit, port, reg_val)); 546 break; 547 case 1: 548 _SOC_IF_ERR_EXIT(READ_CXXPORT_XGXS0_CTRL1_REGr(unit, port, ®_val)); 549 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, ®_val, RSTB_HWf, in_reset ? 0 : 1); 550 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, ®_val, PWRDWNf, in_reset ? 1 : 0); 551 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, ®_val, IDDQf, in_reset ? 1 : 0); 552 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, ®_val, REFOUT_ENf, 0); 553 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, ®_val, REFIN_ENf, 1); 554 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_XGXS0_CTRL1_REGr(unit, port, reg_val)); 555 break; 556 case 2: 557 _SOC_IF_ERR_EXIT(READ_CXXPORT_XGXS0_CTRL2_REGr(unit, port, ®_val)); 558 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, ®_val, RSTB_HWf, in_reset ? 0 : 1); 559 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, ®_val, PWRDWNf, in_reset ? 1 : 0); 560 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, ®_val, IDDQf, in_reset ? 1 : 0); 561 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, ®_val, REFOUT_ENf, 0); 562 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, ®_val, REFIN_ENf, 1); 563 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_XGXS0_CTRL2_REGr(unit, port, reg_val)); 564 break; 565 default: 566 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("Invalid quad"))); 567 } 568 } 569 570 exit: 571 SOC_FUNC_RETURN; 572 } 573 574 575 /* set interrupt value. */ 576 int pm12x10_xgs_port_interrupt_enable_get (int unit, int port, pm_info_t pm_info, 577 int intr_type, uint32 *val) 578 { 579 uint32 reg_val; 580 SOC_INIT_FUNC_DEFS; 581 582 _SOC_IF_ERR_EXIT(READ_CXXPORT_INTR_ENABLEr(unit, port, ®_val)); 583 584 switch(intr_type) { 585 case portmodIntrTypeCore0Intr: 586 *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, CORE0_INTf); 587 break; 588 case portmodIntrTypeCore1Intr: 589 *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, CORE1_INTf); 590 break; 591 case portmodIntrTypeCore2Intr: 592 *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, CORE2_INTf); 593 break; 594 case portmodIntrTypeCore3Intr: 595 *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, CORE3_INTf); 596 break; 597 case portmodIntrTypeTsc0Intr: 598 *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, TSC_0_INTf); 599 break; 600 case portmodIntrTypeTsc1Intr: 601 *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, TSC_0_INTf); 602 break; 603 case portmodIntrTypeTsc2Intr: 604 *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, TSC_0_INTf); 605 break; 606 607 default: 608 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type"))); 609 break; 610 } 611 exit: 612 SOC_FUNC_RETURN; 613 } 614 615 /* set interrupt value. */ 616 int pm12x10_xgs_port_interrupt_enable_set (int unit, int port, pm_info_t pm_info, 617 int intr_type, uint32 val) 618 { 619 uint32 reg_val; 620 SOC_INIT_FUNC_DEFS; 621 622 _SOC_IF_ERR_EXIT(READ_CXXPORT_INTR_ENABLEr(unit, port, ®_val)); 623 624 switch(intr_type) { 625 case portmodIntrTypeCore0Intr: 626 soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, ®_val, CORE0_INTf, val); 627 break; 628 case portmodIntrTypeCore1Intr: 629 soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, ®_val, CORE1_INTf, val); 630 break; 631 case portmodIntrTypeCore2Intr: 632 soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, ®_val, CORE2_INTf, val); 633 break; 634 case portmodIntrTypeCore3Intr: 635 soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, ®_val, CORE3_INTf, val); 636 break; 637 case portmodIntrTypeTsc0Intr: 638 soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, ®_val, TSC_0_INTf, val); 639 break; 640 case portmodIntrTypeTsc1Intr: 641 soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, ®_val, TSC_0_INTf, val); 642 break; 643 case portmodIntrTypeTsc2Intr: 644 soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, ®_val, TSC_0_INTf, val); 645 break; 646 647 default: 648 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type"))); 649 break; 650 } 651 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_INTR_ENABLEr(unit, port, reg_val)); 652 exit: 653 SOC_FUNC_RETURN; 654 } 655 656 /* get interrupt value. */ 657 int pm12x10_xgs_port_interrupt_get (int unit, int port, pm_info_t pm_info, 658 int intr_type, uint32* val) 659 { 660 uint32 reg_val; 661 SOC_INIT_FUNC_DEFS; 662 663 _SOC_IF_ERR_EXIT(READ_CXXPORT_INTR_STATUSr(unit, port, ®_val)); 664 665 switch(intr_type) { 666 case portmodIntrTypeCore0Intr: 667 *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE0_INTf); 668 break; 669 case portmodIntrTypeCore1Intr: 670 *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE1_INTf); 671 break; 672 case portmodIntrTypeCore2Intr: 673 *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE2_INTf); 674 break; 675 case portmodIntrTypeCore3Intr: 676 *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE3_INTf); 677 break; 678 case portmodIntrTypeTsc0Intr: 679 *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_0_INTf); 680 break; 681 case portmodIntrTypeTsc1Intr: 682 *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_1_INTf); 683 break; 684 case portmodIntrTypeTsc2Intr: 685 *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_2_INTf); 686 break; 687 688 default: 689 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type"))); 690 break; 691 } 692 exit: 693 SOC_FUNC_RETURN; 694 } 695 696 int pm12x10_xgs_port_interrupts_get (int unit, int port, pm_info_t pm_info, 697 int arr_max_size, uint32* intr_arr, uint32* size) 698 { 699 uint32 reg_val, cnt = 0; 700 SOC_INIT_FUNC_DEFS; 701 702 _SOC_IF_ERR_EXIT(READ_CXXPORT_INTR_STATUSr(unit, port, ®_val)); 703 704 if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE0_INTf)) { 705 if (cnt >= arr_max_size) { 706 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 707 } 708 intr_arr[cnt++] = portmodIntrTypeCore0Intr; 709 } 710 711 if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE1_INTf)) { 712 if (cnt >= arr_max_size) { 713 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 714 } 715 intr_arr[cnt++] = portmodIntrTypeCore1Intr; 716 } 717 718 if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE2_INTf)) { 719 if (cnt >= arr_max_size) { 720 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 721 } 722 intr_arr[cnt++] = portmodIntrTypeCore2Intr; 723 } 724 725 if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE3_INTf)) { 726 if (cnt >= arr_max_size) { 727 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 728 } 729 intr_arr[cnt++] = portmodIntrTypeCore3Intr; 730 } 731 732 if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_0_INTf)) { 733 if (cnt >= arr_max_size) { 734 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 735 } 736 intr_arr[cnt++] = portmodIntrTypeTsc0Intr; 737 } 738 739 if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_1_INTf)) { 740 if (cnt >= arr_max_size) { 741 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 742 } 743 intr_arr[cnt++] = portmodIntrTypeTsc1Intr; 744 } 745 746 if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_2_INTf)) { 747 if (cnt >= arr_max_size) { 748 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 749 } 750 intr_arr[cnt++] = portmodIntrTypeTsc2Intr; 751 } 752 753 *size = cnt; 754 755 exit: 756 SOC_FUNC_RETURN; 757 } 758 759 760 761 #endif /* PORTMOD_PM12X10_XGS_SUPPORT */ 762 763 #undef _ERR_MSG_MODULE_NAME