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