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