1 /* 2 * Copyright 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 13 #ifdef CONFIG_SYS_FSL_SRDS_1 14 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT]; 15 #endif 16 #ifdef CONFIG_SYS_FSL_SRDS_2 17 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT]; 18 #endif 19 20 int is_serdes_configured(enum srds_prtcl device) 21 { 22 int ret = 0; 23 24 #ifdef CONFIG_SYS_FSL_SRDS_1 25 if (!serdes1_prtcl_map[NONE]) 26 fsl_serdes_init(); 27 28 ret |= serdes1_prtcl_map[device]; 29 #endif 30 #ifdef CONFIG_SYS_FSL_SRDS_2 31 if (!serdes2_prtcl_map[NONE]) 32 fsl_serdes_init(); 33 34 ret |= serdes2_prtcl_map[device]; 35 #endif 36 37 return !!ret; 38 } 39 40 int serdes_get_first_lane(u32 sd, enum srds_prtcl device) 41 { 42 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 43 u32 cfg = gur_in32(&gur->rcwsr[4]); 44 int i; 45 46 switch (sd) { 47 #ifdef CONFIG_SYS_FSL_SRDS_1 48 case FSL_SRDS_1: 49 cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK; 50 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT; 51 break; 52 #endif 53 #ifdef CONFIG_SYS_FSL_SRDS_2 54 case FSL_SRDS_2: 55 cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK; 56 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT; 57 break; 58 #endif 59 default: 60 printf("invalid SerDes%d\n", sd); 61 break; 62 } 63 64 /* Is serdes enabled at all? */ 65 if (unlikely(cfg == 0)) 66 return -ENODEV; 67 68 for (i = 0; i < SRDS_MAX_LANES; i++) { 69 if (serdes_get_prtcl(sd, cfg, i) == device) 70 return i; 71 } 72 73 return -ENODEV; 74 } 75 76 int get_serdes_protocol(void) 77 { 78 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 79 u32 cfg = gur_in32(&gur->rcwsr[4]) & 80 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK; 81 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT; 82 83 return cfg; 84 } 85 86 const char *serdes_clock_to_string(u32 clock) 87 { 88 switch (clock) { 89 case SRDS_PLLCR0_RFCK_SEL_100: 90 return "100"; 91 case SRDS_PLLCR0_RFCK_SEL_125: 92 return "125"; 93 case SRDS_PLLCR0_RFCK_SEL_156_25: 94 return "156.25"; 95 default: 96 return "100"; 97 } 98 } 99 100 void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, 101 u8 serdes_prtcl_map[SERDES_PRCTL_COUNT]) 102 { 103 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 104 u32 cfg; 105 int lane; 106 107 if (serdes_prtcl_map[NONE]) 108 return; 109 110 memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT); 111 112 cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask; 113 cfg >>= sd_prctl_shift; 114 printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg); 115 116 if (!is_serdes_prtcl_valid(sd, cfg)) 117 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg); 118 119 for (lane = 0; lane < SRDS_MAX_LANES; lane++) { 120 enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane); 121 122 if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT)) 123 debug("Unknown SerDes lane protocol %d\n", lane_prtcl); 124 else 125 serdes_prtcl_map[lane_prtcl] = 1; 126 } 127 128 /* Set the first element to indicate serdes has been initialized */ 129 serdes_prtcl_map[NONE] = 1; 130 } 131 132 __weak int get_serdes_volt(void) 133 { 134 return -1; 135 } 136 137 __weak int set_serdes_volt(int svdd) 138 { 139 return -1; 140 } 141 142 int setup_serdes_volt(u32 svdd) 143 { 144 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 145 struct ccsr_serdes *serdes1_base; 146 #ifdef CONFIG_SYS_FSL_SRDS_2 147 struct ccsr_serdes *serdes2_base; 148 #endif 149 u32 cfg_rcw4 = gur_in32(&gur->rcwsr[4]); 150 u32 cfg_rcw5 = gur_in32(&gur->rcwsr[5]); 151 u32 cfg_tmp, reg = 0; 152 int svdd_cur, svdd_tar; 153 int ret; 154 int i; 155 156 /* Only support switch SVDD to 900mV/1000mV */ 157 if (svdd != 900 && svdd != 1000) 158 return -EINVAL; 159 160 svdd_tar = svdd; 161 svdd_cur = get_serdes_volt(); 162 if (svdd_cur < 0) 163 return -EINVAL; 164 165 debug("%s: current SVDD: %dmV; target SVDD: %dmV\n", 166 __func__, svdd_cur, svdd_tar); 167 if (svdd_cur == svdd_tar) 168 return 0; 169 170 serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR; 171 #ifdef CONFIG_SYS_FSL_SRDS_2 172 serdes2_base = (void *)serdes1_base + 0x10000; 173 #endif 174 175 /* Put the all enabled lanes in reset */ 176 #ifdef CONFIG_SYS_FSL_SRDS_1 177 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK; 178 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT; 179 180 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) { 181 reg = in_be32(&serdes1_base->lane[i].gcr0); 182 reg &= 0xFF9FFFFF; 183 out_be32(&serdes1_base->lane[i].gcr0, reg); 184 } 185 #endif 186 #ifdef CONFIG_SYS_FSL_SRDS_2 187 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK; 188 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT; 189 190 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) { 191 reg = in_be32(&serdes2_base->lane[i].gcr0); 192 reg &= 0xFF9FFFFF; 193 out_be32(&serdes2_base->lane[i].gcr0, reg); 194 } 195 #endif 196 197 /* Put the all enabled PLL in reset */ 198 #ifdef CONFIG_SYS_FSL_SRDS_1 199 cfg_tmp = (cfg_rcw5 >> 22) & 0x3; 200 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) { 201 reg = in_be32(&serdes1_base->bank[i].rstctl); 202 reg &= 0xFFFFFFBF; 203 reg |= 0x10000000; 204 out_be32(&serdes1_base->bank[i].rstctl, reg); 205 udelay(1); 206 207 reg = in_be32(&serdes1_base->bank[i].rstctl); 208 reg &= 0xFFFFFF1F; 209 out_be32(&serdes1_base->bank[i].rstctl, reg); 210 } 211 udelay(1); 212 #endif 213 214 #ifdef CONFIG_SYS_FSL_SRDS_2 215 cfg_tmp = (cfg_rcw5 >> 20) & 0x3; 216 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) { 217 reg = in_be32(&serdes2_base->bank[i].rstctl); 218 reg &= 0xFFFFFFBF; 219 reg |= 0x10000000; 220 out_be32(&serdes2_base->bank[i].rstctl, reg); 221 udelay(1); 222 223 reg = in_be32(&serdes2_base->bank[i].rstctl); 224 reg &= 0xFFFFFF1F; 225 out_be32(&serdes2_base->bank[i].rstctl, reg); 226 } 227 udelay(1); 228 #endif 229 230 /* Put the Rx/Tx calibration into reset */ 231 #ifdef CONFIG_SYS_FSL_SRDS_1 232 reg = in_be32(&serdes1_base->srdstcalcr); 233 reg &= 0xF7FFFFFF; 234 out_be32(&serdes1_base->srdstcalcr, reg); 235 reg = in_be32(&serdes1_base->srdsrcalcr); 236 reg &= 0xF7FFFFFF; 237 out_be32(&serdes1_base->srdsrcalcr, reg); 238 239 #endif 240 #ifdef CONFIG_SYS_FSL_SRDS_2 241 reg = in_be32(&serdes2_base->srdstcalcr); 242 reg &= 0xF7FFFFFF; 243 out_be32(&serdes2_base->srdstcalcr, reg); 244 reg = in_be32(&serdes2_base->srdsrcalcr); 245 reg &= 0xF7FFFFFF; 246 out_be32(&serdes2_base->srdsrcalcr, reg); 247 #endif 248 249 /* 250 * If SVDD set failed, will not return directly, so that the 251 * serdes lanes can complete reseting. 252 */ 253 ret = set_serdes_volt(svdd_tar); 254 if (ret) 255 printf("%s: Failed to set SVDD\n", __func__); 256 257 /* Wait for SVDD to stabilize */ 258 udelay(100); 259 260 /* For each PLL that’s not disabled via RCW */ 261 #ifdef CONFIG_SYS_FSL_SRDS_1 262 cfg_tmp = (cfg_rcw5 >> 22) & 0x3; 263 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) { 264 reg = in_be32(&serdes1_base->bank[i].rstctl); 265 reg |= 0x00000020; 266 out_be32(&serdes1_base->bank[i].rstctl, reg); 267 udelay(1); 268 269 reg = in_be32(&serdes1_base->bank[i].rstctl); 270 reg |= 0x00000080; 271 out_be32(&serdes1_base->bank[i].rstctl, reg); 272 273 /* Take the Rx/Tx calibration out of reset */ 274 if (!(cfg_tmp == 0x3 && i == 1)) { 275 udelay(1); 276 reg = in_be32(&serdes1_base->srdstcalcr); 277 reg |= 0x08000000; 278 out_be32(&serdes1_base->srdstcalcr, reg); 279 reg = in_be32(&serdes1_base->srdsrcalcr); 280 reg |= 0x08000000; 281 out_be32(&serdes1_base->srdsrcalcr, reg); 282 } 283 } 284 udelay(1); 285 #endif 286 287 #ifdef CONFIG_SYS_FSL_SRDS_2 288 cfg_tmp = (cfg_rcw5 >> 20) & 0x3; 289 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) { 290 reg = in_be32(&serdes2_base->bank[i].rstctl); 291 reg |= 0x00000020; 292 out_be32(&serdes2_base->bank[i].rstctl, reg); 293 udelay(1); 294 295 reg = in_be32(&serdes2_base->bank[i].rstctl); 296 reg |= 0x00000080; 297 out_be32(&serdes2_base->bank[i].rstctl, reg); 298 299 /* Take the Rx/Tx calibration out of reset */ 300 if (!(cfg_tmp == 0x3 && i == 1)) { 301 udelay(1); 302 reg = in_be32(&serdes2_base->srdstcalcr); 303 reg |= 0x08000000; 304 out_be32(&serdes2_base->srdstcalcr, reg); 305 reg = in_be32(&serdes2_base->srdsrcalcr); 306 reg |= 0x08000000; 307 out_be32(&serdes2_base->srdsrcalcr, reg); 308 } 309 } 310 udelay(1); 311 312 #endif 313 314 /* Wait for at lesat 625us to ensure the PLLs being reset are locked */ 315 udelay(800); 316 317 #ifdef CONFIG_SYS_FSL_SRDS_1 318 cfg_tmp = (cfg_rcw5 >> 22) & 0x3; 319 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) { 320 /* if the PLL is not locked, set RST_ERR */ 321 reg = in_be32(&serdes1_base->bank[i].pllcr0); 322 if (!((reg >> 23) & 0x1)) { 323 reg = in_be32(&serdes1_base->bank[i].rstctl); 324 reg |= 0x20000000; 325 out_be32(&serdes1_base->bank[i].rstctl, reg); 326 } else { 327 udelay(1); 328 reg = in_be32(&serdes1_base->bank[i].rstctl); 329 reg &= 0xFFFFFFEF; 330 reg |= 0x00000040; 331 out_be32(&serdes1_base->bank[i].rstctl, reg); 332 udelay(1); 333 } 334 } 335 #endif 336 337 #ifdef CONFIG_SYS_FSL_SRDS_2 338 cfg_tmp = (cfg_rcw5 >> 20) & 0x3; 339 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) { 340 reg = in_be32(&serdes2_base->bank[i].pllcr0); 341 if (!((reg >> 23) & 0x1)) { 342 reg = in_be32(&serdes2_base->bank[i].rstctl); 343 reg |= 0x20000000; 344 out_be32(&serdes2_base->bank[i].rstctl, reg); 345 } else { 346 udelay(1); 347 reg = in_be32(&serdes2_base->bank[i].rstctl); 348 reg &= 0xFFFFFFEF; 349 reg |= 0x00000040; 350 out_be32(&serdes2_base->bank[i].rstctl, reg); 351 udelay(1); 352 } 353 } 354 #endif 355 356 /* Take the all enabled lanes out of reset */ 357 #ifdef CONFIG_SYS_FSL_SRDS_1 358 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK; 359 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT; 360 361 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) { 362 reg = in_be32(&serdes1_base->lane[i].gcr0); 363 reg |= 0x00600000; 364 out_be32(&serdes1_base->lane[i].gcr0, reg); 365 } 366 #endif 367 #ifdef CONFIG_SYS_FSL_SRDS_2 368 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK; 369 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT; 370 371 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) { 372 reg = in_be32(&serdes2_base->lane[i].gcr0); 373 reg |= 0x00600000; 374 out_be32(&serdes2_base->lane[i].gcr0, reg); 375 } 376 #endif 377 /* For each PLL being reset, and achieved PLL lock set RST_DONE */ 378 #ifdef CONFIG_SYS_FSL_SRDS_1 379 cfg_tmp = (cfg_rcw5 >> 22) & 0x3; 380 for (i = 0; i < 2; i++) { 381 reg = in_be32(&serdes1_base->bank[i].pllcr0); 382 if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) { 383 reg = in_be32(&serdes1_base->bank[i].rstctl); 384 reg |= 0x40000000; 385 out_be32(&serdes1_base->bank[i].rstctl, reg); 386 } 387 } 388 #endif 389 #ifdef CONFIG_SYS_FSL_SRDS_2 390 cfg_tmp = (cfg_rcw5 >> 20) & 0x3; 391 for (i = 0; i < 2; i++) { 392 reg = in_be32(&serdes2_base->bank[i].pllcr0); 393 if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) { 394 reg = in_be32(&serdes2_base->bank[i].rstctl); 395 reg |= 0x40000000; 396 out_be32(&serdes2_base->bank[i].rstctl, reg); 397 } 398 } 399 #endif 400 401 return ret; 402 } 403 404 void fsl_serdes_init(void) 405 { 406 #ifdef CONFIG_SYS_FSL_SRDS_1 407 serdes_init(FSL_SRDS_1, 408 CONFIG_SYS_FSL_SERDES_ADDR, 409 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK, 410 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT, 411 serdes1_prtcl_map); 412 #endif 413 #ifdef CONFIG_SYS_FSL_SRDS_2 414 serdes_init(FSL_SRDS_2, 415 CONFIG_SYS_FSL_SERDES_ADDR, 416 FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK, 417 FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT, 418 serdes2_prtcl_map); 419 #endif 420 } 421