fsl_lsch2_serdes.c 11 KB

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