1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2016-2018 NXP 4 * Copyright 2014-2015 Freescale Semiconductor, Inc. 5 */ 6 7 #include <common.h> 8 #include <asm/io.h> 9 #include <linux/errno.h> 10 #include <asm/arch/fsl_serdes.h> 11 #include <asm/arch/soc.h> 12 #include <fsl-mc/ldpaa_wriop.h> 13 14 #ifdef CONFIG_SYS_FSL_SRDS_1 15 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT]; 16 #endif 17 #ifdef CONFIG_SYS_FSL_SRDS_2 18 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT]; 19 #endif 20 #ifdef CONFIG_SYS_NXP_SRDS_3 21 static u8 serdes3_prtcl_map[SERDES_PRCTL_COUNT]; 22 #endif 23 24 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) 25 #ifdef CONFIG_ARCH_LX2160A 26 int xfi_dpmac[XFI14 + 1]; 27 int sgmii_dpmac[SGMII18 + 1]; 28 int a25gaui_dpmac[_25GE10 + 1]; 29 int xlaui_dpmac[_40GE2 + 1]; 30 int caui2_dpmac[_50GE2 + 1]; 31 int caui4_dpmac[_100GE2 + 1]; 32 #else 33 int xfi_dpmac[XFI8 + 1]; 34 int sgmii_dpmac[SGMII16 + 1]; 35 #endif 36 #endif 37 38 __weak void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl) 39 { 40 return; 41 } 42 43 /* 44 *The return value of this func is the serdes protocol used. 45 *Typically this function is called number of times depending 46 *upon the number of serdes blocks in the Silicon. 47 *Zero is used to denote that no serdes was enabled, 48 *this is the case when golden RCW was used where DPAA2 bring was 49 *intentionally removed to achieve boot to prompt 50 */ 51 52 __weak int serdes_get_number(int serdes, int cfg) 53 { 54 return cfg; 55 } 56 57 int is_serdes_configured(enum srds_prtcl device) 58 { 59 int ret = 0; 60 61 #ifdef CONFIG_SYS_FSL_SRDS_1 62 if (!serdes1_prtcl_map[NONE]) 63 fsl_serdes_init(); 64 65 ret |= serdes1_prtcl_map[device]; 66 #endif 67 #ifdef CONFIG_SYS_FSL_SRDS_2 68 if (!serdes2_prtcl_map[NONE]) 69 fsl_serdes_init(); 70 71 ret |= serdes2_prtcl_map[device]; 72 #endif 73 #ifdef CONFIG_SYS_NXP_SRDS_3 74 if (!serdes3_prtcl_map[NONE]) 75 fsl_serdes_init(); 76 77 ret |= serdes3_prtcl_map[device]; 78 #endif 79 80 return !!ret; 81 } 82 83 int serdes_get_first_lane(u32 sd, enum srds_prtcl device) 84 { 85 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 86 u32 cfg = 0; 87 int i; 88 89 switch (sd) { 90 #ifdef CONFIG_SYS_FSL_SRDS_1 91 case FSL_SRDS_1: 92 cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]); 93 cfg &= FSL_CHASSIS3_SRDS1_PRTCL_MASK; 94 cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT; 95 break; 96 #endif 97 #ifdef CONFIG_SYS_FSL_SRDS_2 98 case FSL_SRDS_2: 99 cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]); 100 cfg &= FSL_CHASSIS3_SRDS2_PRTCL_MASK; 101 cfg >>= FSL_CHASSIS3_SRDS2_PRTCL_SHIFT; 102 break; 103 #endif 104 #ifdef CONFIG_SYS_NXP_SRDS_3 105 case NXP_SRDS_3: 106 cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS3_REGSR - 1]); 107 cfg &= FSL_CHASSIS3_SRDS3_PRTCL_MASK; 108 cfg >>= FSL_CHASSIS3_SRDS3_PRTCL_SHIFT; 109 break; 110 #endif 111 default: 112 printf("invalid SerDes%d\n", sd); 113 break; 114 } 115 116 cfg = serdes_get_number(sd, cfg); 117 118 /* Is serdes enabled at all? */ 119 if (cfg == 0) 120 return -ENODEV; 121 122 for (i = 0; i < SRDS_MAX_LANES; i++) { 123 if (serdes_get_prtcl(sd, cfg, i) == device) 124 return i; 125 } 126 127 return -ENODEV; 128 } 129 130 void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32 sd_prctl_mask, 131 u32 sd_prctl_shift, u8 serdes_prtcl_map[SERDES_PRCTL_COUNT]) 132 { 133 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 134 u32 cfg; 135 int lane; 136 137 if (serdes_prtcl_map[NONE]) 138 return; 139 140 memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT); 141 142 cfg = gur_in32(&gur->rcwsr[rcwsr - 1]) & sd_prctl_mask; 143 cfg >>= sd_prctl_shift; 144 145 cfg = serdes_get_number(sd, cfg); 146 printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg); 147 148 if (!is_serdes_prtcl_valid(sd, cfg)) 149 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg); 150 151 for (lane = 0; lane < SRDS_MAX_LANES; lane++) { 152 enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane); 153 if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT)) 154 debug("Unknown SerDes lane protocol %d\n", lane_prtcl); 155 else { 156 serdes_prtcl_map[lane_prtcl] = 1; 157 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) 158 #ifdef CONFIG_ARCH_LX2160A 159 if (lane_prtcl >= XFI1 && lane_prtcl <= XFI14) 160 wriop_init_dpmac(sd, xfi_dpmac[lane_prtcl], 161 (int)lane_prtcl); 162 163 if (lane_prtcl >= SGMII1 && lane_prtcl <= SGMII18) 164 wriop_init_dpmac(sd, sgmii_dpmac[lane_prtcl], 165 (int)lane_prtcl); 166 167 if (lane_prtcl >= _25GE1 && lane_prtcl <= _25GE10) 168 wriop_init_dpmac(sd, a25gaui_dpmac[lane_prtcl], 169 (int)lane_prtcl); 170 171 if (lane_prtcl >= _40GE1 && lane_prtcl <= _40GE2) 172 wriop_init_dpmac(sd, xlaui_dpmac[lane_prtcl], 173 (int)lane_prtcl); 174 175 if (lane_prtcl >= _50GE1 && lane_prtcl <= _50GE2) 176 wriop_init_dpmac(sd, caui2_dpmac[lane_prtcl], 177 (int)lane_prtcl); 178 179 if (lane_prtcl >= _100GE1 && lane_prtcl <= _100GE2) 180 wriop_init_dpmac(sd, caui4_dpmac[lane_prtcl], 181 (int)lane_prtcl); 182 183 #else 184 switch (lane_prtcl) { 185 case QSGMII_A: 186 case QSGMII_B: 187 case QSGMII_C: 188 case QSGMII_D: 189 wriop_init_dpmac_qsgmii(sd, (int)lane_prtcl); 190 break; 191 default: 192 if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8) 193 wriop_init_dpmac(sd, 194 xfi_dpmac[lane_prtcl], 195 (int)lane_prtcl); 196 197 if (lane_prtcl >= SGMII1 && 198 lane_prtcl <= SGMII16) 199 wriop_init_dpmac(sd, sgmii_dpmac[ 200 lane_prtcl], 201 (int)lane_prtcl); 202 break; 203 } 204 #endif 205 #endif 206 } 207 } 208 209 /* Set the first element to indicate serdes has been initialized */ 210 serdes_prtcl_map[NONE] = 1; 211 } 212 213 __weak int get_serdes_volt(void) 214 { 215 return -1; 216 } 217 218 __weak int set_serdes_volt(int svdd) 219 { 220 return -1; 221 } 222 223 #define LNAGCR0_RT_RSTB 0x00600000 224 225 #define RSTCTL_RESET_MASK 0x000000E0 226 227 #define RSTCTL_RSTREQ 0x80000000 228 #define RSTCTL_RST_DONE 0x40000000 229 #define RSTCTL_RSTERR 0x20000000 230 231 #define RSTCTL_SDEN 0x00000020 232 #define RSTCTL_SDRST_B 0x00000040 233 #define RSTCTL_PLLRST_B 0x00000080 234 235 #define TCALCR_CALRST_B 0x08000000 236 237 struct serdes_prctl_info { 238 u32 id; 239 u32 mask; 240 u32 shift; 241 }; 242 243 struct serdes_prctl_info srds_prctl_info[] = { 244 #ifdef CONFIG_SYS_FSL_SRDS_1 245 {.id = 1, 246 .mask = FSL_CHASSIS3_SRDS1_PRTCL_MASK, 247 .shift = FSL_CHASSIS3_SRDS1_PRTCL_SHIFT 248 }, 249 250 #endif 251 #ifdef CONFIG_SYS_FSL_SRDS_2 252 {.id = 2, 253 .mask = FSL_CHASSIS3_SRDS2_PRTCL_MASK, 254 .shift = FSL_CHASSIS3_SRDS2_PRTCL_SHIFT 255 }, 256 #endif 257 #ifdef CONFIG_SYS_NXP_SRDS_3 258 {.id = 3, 259 .mask = FSL_CHASSIS3_SRDS3_PRTCL_MASK, 260 .shift = FSL_CHASSIS3_SRDS3_PRTCL_SHIFT 261 }, 262 #endif 263 {} /* NULL ENTRY */ 264 }; 265 266 static int get_serdes_prctl_info_idx(u32 serdes_id) 267 { 268 int pos = 0; 269 struct serdes_prctl_info *srds_info; 270 271 /* loop until NULL ENTRY defined by .id=0 */ 272 for (srds_info = srds_prctl_info; srds_info->id != 0; 273 srds_info++, pos++) { 274 if (srds_info->id == serdes_id) 275 return pos; 276 } 277 278 return -1; 279 } 280 281 static void do_enabled_lanes_reset(u32 serdes_id, u32 cfg, 282 struct ccsr_serdes __iomem *serdes_base, 283 bool cmplt) 284 { 285 int i, pos; 286 u32 cfg_tmp; 287 288 pos = get_serdes_prctl_info_idx(serdes_id); 289 if (pos == -1) { 290 printf("invalid serdes_id %d\n", serdes_id); 291 return; 292 } 293 294 cfg_tmp = cfg & srds_prctl_info[pos].mask; 295 cfg_tmp >>= srds_prctl_info[pos].shift; 296 297 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) { 298 if (cmplt) 299 setbits_le32(&serdes_base->lane[i].gcr0, 300 LNAGCR0_RT_RSTB); 301 else 302 clrbits_le32(&serdes_base->lane[i].gcr0, 303 LNAGCR0_RT_RSTB); 304 } 305 } 306 307 static void do_pll_reset(u32 cfg, 308 struct ccsr_serdes __iomem *serdes_base) 309 { 310 int i; 311 312 for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) { 313 clrbits_le32(&serdes_base->bank[i].rstctl, 314 RSTCTL_RESET_MASK); 315 udelay(1); 316 317 setbits_le32(&serdes_base->bank[i].rstctl, 318 RSTCTL_RSTREQ); 319 } 320 udelay(1); 321 } 322 323 static void do_rx_tx_cal_reset(struct ccsr_serdes __iomem *serdes_base) 324 { 325 clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B); 326 clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B); 327 } 328 329 static void do_rx_tx_cal_reset_comp(u32 cfg, int i, 330 struct ccsr_serdes __iomem *serdes_base) 331 { 332 if (!(cfg == 0x3 && i == 1)) { 333 udelay(1); 334 setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B); 335 setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B); 336 } 337 udelay(1); 338 } 339 340 static void do_pll_reset_done(u32 cfg, 341 struct ccsr_serdes __iomem *serdes_base) 342 { 343 int i; 344 u32 reg = 0; 345 346 for (i = 0; i < 2; i++) { 347 reg = in_le32(&serdes_base->bank[i].pllcr0); 348 if (!(cfg & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) { 349 setbits_le32(&serdes_base->bank[i].rstctl, 350 RSTCTL_RST_DONE); 351 } 352 } 353 } 354 355 static void do_serdes_enable(u32 cfg, 356 struct ccsr_serdes __iomem *serdes_base) 357 { 358 int i; 359 360 for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) { 361 setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_SDEN); 362 udelay(1); 363 364 setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_PLLRST_B); 365 udelay(1); 366 /* Take the Rx/Tx calibration out of reset */ 367 do_rx_tx_cal_reset_comp(cfg, i, serdes_base); 368 } 369 } 370 371 static void do_pll_lock(u32 cfg, 372 struct ccsr_serdes __iomem *serdes_base) 373 { 374 int i; 375 u32 reg = 0; 376 377 for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) { 378 /* if the PLL is not locked, set RST_ERR */ 379 reg = in_le32(&serdes_base->bank[i].pllcr0); 380 if (!((reg >> 23) & 0x1)) { 381 setbits_le32(&serdes_base->bank[i].rstctl, 382 RSTCTL_RSTERR); 383 } else { 384 udelay(1); 385 setbits_le32(&serdes_base->bank[i].rstctl, 386 RSTCTL_SDRST_B); 387 udelay(1); 388 } 389 } 390 } 391 392 int setup_serdes_volt(u32 svdd) 393 { 394 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 395 struct ccsr_serdes __iomem *serdes1_base = 396 (void *)CONFIG_SYS_FSL_LSCH3_SERDES_ADDR; 397 u32 cfg_rcwsrds1 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]); 398 #ifdef CONFIG_SYS_FSL_SRDS_2 399 struct ccsr_serdes __iomem *serdes2_base = 400 (void *)(CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + 0x10000); 401 u32 cfg_rcwsrds2 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]); 402 #endif 403 #ifdef CONFIG_SYS_NXP_SRDS_3 404 struct ccsr_serdes __iomem *serdes3_base = 405 (void *)(CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + 0x20000); 406 u32 cfg_rcwsrds3 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS3_REGSR - 1]); 407 #endif 408 u32 cfg_tmp; 409 int svdd_cur, svdd_tar; 410 int ret = 1; 411 412 /* Only support switch SVDD to 900mV */ 413 if (svdd != 900) 414 return -EINVAL; 415 416 /* Scale up to the LTC resolution is 1/4096V */ 417 svdd = (svdd * 4096) / 1000; 418 419 svdd_tar = svdd; 420 svdd_cur = get_serdes_volt(); 421 if (svdd_cur < 0) 422 return -EINVAL; 423 424 debug("%s: current SVDD: %x; target SVDD: %x\n", 425 __func__, svdd_cur, svdd_tar); 426 if (svdd_cur == svdd_tar) 427 return 0; 428 429 /* Put the all enabled lanes in reset */ 430 #ifdef CONFIG_SYS_FSL_SRDS_1 431 do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, false); 432 #endif 433 434 #ifdef CONFIG_SYS_FSL_SRDS_2 435 do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, false); 436 #endif 437 #ifdef CONFIG_SYS_NXP_SRDS_3 438 do_enabled_lanes_reset(3, cfg_rcwsrds3, serdes3_base, false); 439 #endif 440 441 /* Put the all enabled PLL in reset */ 442 #ifdef CONFIG_SYS_FSL_SRDS_1 443 cfg_tmp = cfg_rcwsrds1 & 0x3; 444 do_pll_reset(cfg_tmp, serdes1_base); 445 #endif 446 447 #ifdef CONFIG_SYS_FSL_SRDS_2 448 cfg_tmp = cfg_rcwsrds1 & 0xC; 449 cfg_tmp >>= 2; 450 do_pll_reset(cfg_tmp, serdes2_base); 451 #endif 452 453 #ifdef CONFIG_SYS_NXP_SRDS_3 454 cfg_tmp = cfg_rcwsrds3 & 0x30; 455 cfg_tmp >>= 4; 456 do_pll_reset(cfg_tmp, serdes3_base); 457 #endif 458 459 /* Put the Rx/Tx calibration into reset */ 460 #ifdef CONFIG_SYS_FSL_SRDS_1 461 do_rx_tx_cal_reset(serdes1_base); 462 #endif 463 464 #ifdef CONFIG_SYS_FSL_SRDS_2 465 do_rx_tx_cal_reset(serdes2_base); 466 #endif 467 468 #ifdef CONFIG_SYS_NXP_SRDS_3 469 do_rx_tx_cal_reset(serdes3_base); 470 #endif 471 472 ret = set_serdes_volt(svdd); 473 if (ret < 0) { 474 printf("could not change SVDD\n"); 475 ret = -1; 476 } 477 478 /* For each PLL that’s not disabled via RCW enable the SERDES */ 479 #ifdef CONFIG_SYS_FSL_SRDS_1 480 cfg_tmp = cfg_rcwsrds1 & 0x3; 481 do_serdes_enable(cfg_tmp, serdes1_base); 482 #endif 483 #ifdef CONFIG_SYS_FSL_SRDS_2 484 cfg_tmp = cfg_rcwsrds1 & 0xC; 485 cfg_tmp >>= 2; 486 do_serdes_enable(cfg_tmp, serdes2_base); 487 #endif 488 #ifdef CONFIG_SYS_NXP_SRDS_3 489 cfg_tmp = cfg_rcwsrds3 & 0x30; 490 cfg_tmp >>= 4; 491 do_serdes_enable(cfg_tmp, serdes3_base); 492 #endif 493 494 /* Wait for at at least 625us, ensure the PLLs being reset are locked */ 495 udelay(800); 496 497 #ifdef CONFIG_SYS_FSL_SRDS_1 498 cfg_tmp = cfg_rcwsrds1 & 0x3; 499 do_pll_lock(cfg_tmp, serdes1_base); 500 #endif 501 502 #ifdef CONFIG_SYS_FSL_SRDS_2 503 cfg_tmp = cfg_rcwsrds1 & 0xC; 504 cfg_tmp >>= 2; 505 do_pll_lock(cfg_tmp, serdes2_base); 506 #endif 507 508 #ifdef CONFIG_SYS_NXP_SRDS_3 509 cfg_tmp = cfg_rcwsrds3 & 0x30; 510 cfg_tmp >>= 4; 511 do_pll_lock(cfg_tmp, serdes3_base); 512 #endif 513 514 /* Take the all enabled lanes out of reset */ 515 #ifdef CONFIG_SYS_FSL_SRDS_1 516 do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, true); 517 #endif 518 #ifdef CONFIG_SYS_FSL_SRDS_2 519 do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, true); 520 #endif 521 522 #ifdef CONFIG_SYS_NXP_SRDS_3 523 do_enabled_lanes_reset(3, cfg_rcwsrds3, serdes3_base, true); 524 #endif 525 526 /* For each PLL being reset, and achieved PLL lock set RST_DONE */ 527 #ifdef CONFIG_SYS_FSL_SRDS_1 528 cfg_tmp = cfg_rcwsrds1 & 0x3; 529 do_pll_reset_done(cfg_tmp, serdes1_base); 530 #endif 531 #ifdef CONFIG_SYS_FSL_SRDS_2 532 cfg_tmp = cfg_rcwsrds1 & 0xC; 533 cfg_tmp >>= 2; 534 do_pll_reset_done(cfg_tmp, serdes2_base); 535 #endif 536 537 #ifdef CONFIG_SYS_NXP_SRDS_3 538 cfg_tmp = cfg_rcwsrds3 & 0x30; 539 cfg_tmp >>= 4; 540 do_pll_reset_done(cfg_tmp, serdes3_base); 541 #endif 542 543 return ret; 544 } 545 546 void fsl_serdes_init(void) 547 { 548 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) 549 int i , j; 550 551 for (i = XFI1, j = 1; i <= XFI8; i++, j++) 552 xfi_dpmac[i] = j; 553 554 for (i = SGMII1, j = 1; i <= SGMII16; i++, j++) 555 sgmii_dpmac[i] = j; 556 #endif 557 558 #ifdef CONFIG_SYS_FSL_SRDS_1 559 serdes_init(FSL_SRDS_1, 560 CONFIG_SYS_FSL_LSCH3_SERDES_ADDR, 561 FSL_CHASSIS3_SRDS1_REGSR, 562 FSL_CHASSIS3_SRDS1_PRTCL_MASK, 563 FSL_CHASSIS3_SRDS1_PRTCL_SHIFT, 564 serdes1_prtcl_map); 565 #endif 566 #ifdef CONFIG_SYS_FSL_SRDS_2 567 serdes_init(FSL_SRDS_2, 568 CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000, 569 FSL_CHASSIS3_SRDS2_REGSR, 570 FSL_CHASSIS3_SRDS2_PRTCL_MASK, 571 FSL_CHASSIS3_SRDS2_PRTCL_SHIFT, 572 serdes2_prtcl_map); 573 #endif 574 #ifdef CONFIG_SYS_NXP_SRDS_3 575 serdes_init(NXP_SRDS_3, 576 CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + NXP_SRDS_3 * 0x10000, 577 FSL_CHASSIS3_SRDS3_REGSR, 578 FSL_CHASSIS3_SRDS3_PRTCL_MASK, 579 FSL_CHASSIS3_SRDS3_PRTCL_SHIFT, 580 serdes3_prtcl_map); 581 #endif 582 } 583